Repository: apache/streampipes
Pull request #2598 (2024-03-20 21:14:37)

fix(#2597): Improve Influx query handling
<!--
  ~ Licensed to the Apache Software Foundation (ASF) under one or more
  ~ contributor license agreements.  See the NOTICE file distributed with
  ~ this work for additional information regarding copyright ownership.
  ~ The ASF licenses this file to You under the Apache License, Version 2.0
  ~ (the "License"); you may not use this file except in compliance with
  ~ the License.  You may obtain a copy of the License at
  ~
  ~    http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  ~
  -->
  
  <!--
Thanks for contributing! Here are some tips you can follow to help us incorporate your contribution quickly and easily:
1. If this is your first time, please read our contributor guidelines:
    - https://streampipes.apache.org/getinvolved.html
    - https://cwiki.apache.org/confluence/display/STREAMPIPES/Getting+Started
2. Make sure the PR title is formatted like: `[#<GitHub issue id>] PR title ...`
3. If the PR is unfinished, add '[WIP]' in your PR title, e.g., `[WIP][#<GitHub issue id>] PR title ...`.
4. Please write your PR title to summarize what this PR proposes/fixes.
5. Link the PR to the corresponding GitHub issue (if present) in the `Development` section in the right menu bar. 
6. Be sure to keep the PR description updated to reflect all changes.
7. If possible, provide a concise example to reproduce the issue for a faster review.
8. Make sure tests pass via `mvn clean install`.
9. (Optional) If the contribution is large, please file an Apache ICLA
    - http://apache.org/licenses/icla.pdf
-->

### Purpose
<!--
Please clarify what changes you are proposing and describe how those changes will address the issue.
Furthermore, describe potential consequences the changes might have.
-->

Add some minor improvements to the query handling of Influx data explorer queries:
* Return timestamp instead of time string from Influx queries, since timestamps are properly interpreted by data explorer charts
* This also improves performance of data download queries since the timestamp doesn't need to be parsed from the time string

### Remarks
<!--
Is there anything left we need to pay attention on?
Are there some references that might be important? E.g. links to Confluence, or discussions
on the mailing list or GitHub.
-->
PR introduces (a) breaking change(s): no

PR introduces (a) deprecation(s): no



Patch:
diff --git a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/influx/DataExplorerInfluxQueryExecutor.java b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/influx/DataExplorerInfluxQueryExecutor.java
index 01194fc259..dbb8a9a0b2 100644
--- a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/influx/DataExplorerInfluxQueryExecutor.java
+++ b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/influx/DataExplorerInfluxQueryExecutor.java
@@ -33,6 +33,8 @@ import org.influxdb.dto.QueryResult;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
 
 public class DataExplorerInfluxQueryExecutor extends DataExplorerQueryExecutor<Query, QueryResult> {
 
@@ -72,14 +74,19 @@ public class DataExplorerInfluxQueryExecutor extends DataExplorerQueryExecutor<Q
   protected SpQueryResult postQuery(QueryResult queryResult,
                                     boolean ignoreMissingValues) throws RuntimeException {
     SpQueryResult result = new SpQueryResult();
+    AtomicLong lastTimestamp = new AtomicLong();
 
     if (hasResult(queryResult)) {
-      result.setTotal(queryResult.getResults().get(0).getSeries().size());
       queryResult.getResults().get(0).getSeries().forEach(rs -> {
         DataSeries series = convertResult(rs, ignoreMissingValues);
         result.setHeaders(series.getHeaders());
         result.addDataResult(series);
+        List<Object> lastValue = rs.getValues().get(rs.getValues().size() - 1);
+        lastTimestamp.set(Math.max(lastTimestamp.get(), ((Double) lastValue.get(0)).longValue()));
       });
+
+      result.setTotal(result.getAllDataSeries().stream().mapToInt(DataSeries::getTotal).sum());
+      result.setLastTimestamp(lastTimestamp.get());
     }
 
     if (this.appendId) {
@@ -96,7 +103,7 @@ public class DataExplorerInfluxQueryExecutor extends DataExplorerQueryExecutor<Q
   @Override
   protected QueryResult executeQuery(Query query) {
     try (final InfluxDB influxDB = InfluxClientProvider.getInfluxDBClient()) {
-      return influxDB.query(query);
+      return influxDB.query(query, TimeUnit.MILLISECONDS);
     }
   }
 
diff --git a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/param/ProvidedRestQueryParams.java b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/param/ProvidedRestQueryParams.java
index 308bfba3c4..d703eb934b 100644
--- a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/param/ProvidedRestQueryParams.java
+++ b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/param/ProvidedRestQueryParams.java
@@ -65,6 +65,10 @@ public class ProvidedRestQueryParams {
     this.providedParams.put(key, value);
   }
 
+  public void update(String key, long value) {
+    update(key, String.valueOf(value));
+  }
+
   public void update(String key, Integer value) {
     update(key, String.valueOf(value));
   }
diff --git a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/query/StreamedQueryResultProvider.java b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/query/StreamedQueryResultProvider.java
index ee356e9368..e1a8f756e6 100644
--- a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/query/StreamedQueryResultProvider.java
+++ b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/query/StreamedQueryResultProvider.java
@@ -32,11 +32,10 @@ import java.util.List;
 import java.util.Optional;
 
 import static org.apache.streampipes.dataexplorer.param.SupportedRestQueryParams.QP_LIMIT;
-import static org.apache.streampipes.dataexplorer.param.SupportedRestQueryParams.QP_PAGE;
 
 public class StreamedQueryResultProvider extends QueryResultProvider {
 
-  private static final int MAX_RESULTS_PER_QUERY = 500000;
+  private static final int MAX_RESULTS_PER_QUERY = 200000;
   private static final String TIME_FIELD = "time";
 
   private final OutputFormat format;
@@ -61,36 +60,34 @@ public class StreamedQueryResultProvider extends QueryResultProvider {
     var measurement = findByMeasurementName(queryParams.getMeasurementId()).get();
 
     SpQueryResult dataResult;
-    int page = 0;
-    if (queryParams.has(QP_PAGE)) {
-      page = queryParams.getAsInt(QP_PAGE);
-    }
 
     boolean isFirstDataItem = true;
+    var resultsCount = 0;
     configuredWriter.beforeFirstItem(outputStream);
     do {
-      queryParams.update(SupportedRestQueryParams.QP_PAGE, String.valueOf(page));
       dataResult = getData();
+      long lastTimestamp = 0;
+      resultsCount = dataResult.getTotal() > 0 ? dataResult.getAllDataSeries().get(0).getTotal() : 0;
+      if (resultsCount > 0) {
 
-      if (dataResult.getTotal() > 0) {
         changeTimestampHeader(measurement, dataResult);
         var columns = dataResult.getHeaders();
         for (List<Object> row : dataResult.getAllDataSeries().get(0).getRows()) {
           configuredWriter.writeItem(outputStream, row, columns, isFirstDataItem);
           isFirstDataItem = false;
+          lastTimestamp = dataResult.getLastTimestamp();
         }
       }
-      page++;
-    } while (queryNextPage(dataResult.getTotal(), usesLimit, limit, page));
+      queryParams.update(SupportedRestQueryParams.QP_START_DATE, lastTimestamp + 1);
+    } while (queryNextPage(resultsCount, usesLimit, limit));
     configuredWriter.afterLastItem(outputStream);
   }
 
   private boolean queryNextPage(int lastResultsCount,
                                 boolean usesLimit,
-                                int limit,
-                                int lastPage) {
+                                int limit) {
     if (usesLimit) {
-      return !(limit <= (lastPage) * MAX_RESULTS_PER_QUERY);
+      return lastResultsCount >= limit;
     } else {
       return lastResultsCount > 0;
     }
diff --git a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/query/writer/item/ItemGenerator.java b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/query/writer/item/ItemGenerator.java
index 7b3aa447fe..31e9eb61d5 100644
--- a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/query/writer/item/ItemGenerator.java
+++ b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/query/writer/item/ItemGenerator.java
@@ -19,8 +19,6 @@
 
 package org.apache.streampipes.dataexplorer.query.writer.item;
 
-import org.apache.streampipes.dataexplorer.utils.TimeParser;
-
 import java.util.List;
 import java.util.StringJoiner;
 
@@ -39,9 +37,9 @@ public abstract class ItemGenerator {
     StringJoiner joiner = new StringJoiner(separator);
 
     for (int i = 0; i < row.size(); i++) {
-      var value = row.get(i);
+      Object value = row.get(i);
       if (i == 0) {
-        value = TimeParser.parseTime(value.toString());
+        value = getTimestampValue((Double) row.get(i));
       }
       joiner.add(makeItemString(columns.get(i), value));
     }
@@ -54,4 +52,8 @@ public abstract class ItemGenerator {
 
   protected abstract String finalizeItem(String item);
 
+  private long getTimestampValue(Double value) {
+    return value.longValue();
+  }
+
 }
diff --git a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/utils/TimeParser.java b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/utils/TimeParser.java
deleted file mode 100644
index 135a5d89df..0000000000
--- a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/utils/TimeParser.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.streampipes.dataexplorer.utils;
-
-import java.time.Instant;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.ZonedDateTime;
-import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeFormatterBuilder;
-import java.time.temporal.ChronoField;
-import java.time.temporal.ChronoUnit;
-import java.time.temporal.TemporalAccessor;
-
-public class TimeParser {
-
-  private static final DateTimeFormatter formatter = new DateTimeFormatterBuilder()
-      .appendPattern(
-          "uuuu[-MM[-dd]]['T'HH[:mm[:ss[.SSSSSSSSS][.SSSSSSSS][.SSSSSSS]"
-              + "[.SSSSSS][.SSSSS][.SSSS][.SSS][.SS][.S]]]][XXX]")
-      .parseDefaulting(ChronoField.NANO_OF_SECOND, 0)
-      .parseDefaulting(ChronoField.OFFSET_SECONDS, 0)
-      .toFormatter();
-
-  public static Long parseTime(String v) {
-    TemporalAccessor temporalAccessor = formatter.parseBest(v,
-        ZonedDateTime::from,
-        LocalDateTime::from,
-        LocalDate::from);
-
-    Instant instant = Instant.from(temporalAccessor);
-    return Instant.EPOCH.until(instant, ChronoUnit.MILLIS);
-  }
-}
diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/datalake/SpQueryResult.java b/streampipes-model/src/main/java/org/apache/streampipes/model/datalake/SpQueryResult.java
index d65142d33a..6b9ee352d7 100644
--- a/streampipes-model/src/main/java/org/apache/streampipes/model/datalake/SpQueryResult.java
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/datalake/SpQueryResult.java
@@ -33,6 +33,8 @@ public class SpQueryResult {
   private SpQueryStatus spQueryStatus;
   private String forId;
 
+  private long lastTimestamp;
+
   public SpQueryResult() {
     this.total = 0;
     this.allDataSeries = new ArrayList<>();
@@ -101,4 +103,12 @@ public class SpQueryResult {
   public void setForId(String forId) {
     this.forId = forId;
   }
+
+  public long getLastTimestamp() {
+    return lastTimestamp;
+  }
+
+  public void setLastTimestamp(long lastTimestamp) {
+    this.lastTimestamp = lastTimestamp;
+  }
 }
diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/util/ElementIdGenerator.java b/streampipes-model/src/main/java/org/apache/streampipes/model/util/ElementIdGenerator.java
index 18d29f1e85..1652fe90e2 100644
--- a/streampipes-model/src/main/java/org/apache/streampipes/model/util/ElementIdGenerator.java
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/util/ElementIdGenerator.java
@@ -41,8 +41,4 @@ public class ElementIdGenerator {
   public static String makeElementIdFromAppId(String appId) {
     return prefix + appId;
   }
-
-  public static String makeRecoveryToken() {
-    return RandomStringUtils.randomAlphanumeric(40);
-  }
 }
diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/endpoint/EndpointFetcher.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/endpoint/EndpointFetcher.java
index 1896f33194..abe3ff2b75 100644
--- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/endpoint/EndpointFetcher.java
+++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/endpoint/EndpointFetcher.java
@@ -18,14 +18,10 @@
 package org.apache.streampipes.manager.endpoint;
 
 import org.apache.streampipes.model.client.endpoint.ExtensionsServiceEndpoint;
-import org.apache.streampipes.storage.management.StorageDispatcher;
 import org.apache.streampipes.svcdiscovery.SpServiceDiscovery;
 
-import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
 
 public class EndpointFetcher {
 
@@ -38,15 +34,7 @@ public class EndpointFetcher {
               new ExtensionsServiceEndpoint(endpoint);
       serviceExtensionsServiceEndpoints.add(extensionsServiceEndpoint);
     }
-    List<ExtensionsServiceEndpoint> databasedExtensionsServiceEndpoints = StorageDispatcher.INSTANCE.getNoSqlStore()
-            .getRdfEndpointStorage()
-            .getExtensionsServiceEndpoints();
 
-    List<ExtensionsServiceEndpoint> concatList =
-            Stream.of(databasedExtensionsServiceEndpoints, serviceExtensionsServiceEndpoints)
-                    .flatMap(Collection::stream)
-                    .collect(Collectors.toList());
-
-    return concatList;
+    return serviceExtensionsServiceEndpoints;
   }
 }
diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java
index ae8852a330..e980d9f900 100644
--- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java
+++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/CouchDbInstallationStep.java
@@ -21,28 +21,22 @@ package org.apache.streampipes.manager.setup;
 import org.apache.streampipes.manager.setup.design.UserDesignDocument;
 import org.apache.streampipes.manager.setup.tasks.CreateAssetLinkTypeTask;
 import org.apache.streampipes.manager.setup.tasks.CreateDefaultAssetTask;
-import org.apache.streampipes.model.client.endpoint.ExtensionsServiceEndpoint;
-import org.apache.streampipes.storage.couchdb.impl.ExtensionsServiceEndpointStorageImpl;
 import org.apache.streampipes.storage.couchdb.utils.Utils;
 
 import org.lightcouch.DesignDocument;
 import org.lightcouch.DesignDocument.MapReduce;
 import org.lightcouch.Response;
 
-import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 
 import static org.apache.streampipes.manager.setup.design.DesignDocumentUtils.prepareDocument;
 
 public class CouchDbInstallationStep extends InstallationStep {
 
-  private static final String initRdfEndpointHost = "http://localhost:";
   private static final String PREPARING_NOTIFICATIONS_TEXT = "Preparing database "
       + "'notifications'...";
   private static final String PREPARING_USERS_TEXT = "Preparing database 'users'...";
-  private static List<String> initRdfEndpointPorts = new ArrayList<>();
 
   public CouchDbInstallationStep() {
 
@@ -52,7 +46,6 @@ public class CouchDbInstallationStep extends InstallationStep {
   public void install() {
     createDatabases();
     createViews();
-    addRdfEndpoints();
     new CreateAssetLinkTypeTask().execute();
     new CreateDefaultAssetTask().execute();
   }
@@ -77,7 +70,6 @@ public class CouchDbInstallationStep extends InstallationStep {
       Utils.getCouchDbNotificationClient();
       Utils.getCouchDbPipelineCategoriesClient();
       Utils.getCouchDbVisualizationClient();
-      Utils.getCouchDbRdfEndpointClient();
       Utils.getCouchDbDashboardClient();
       Utils.getCouchDbDashboardWidgetClient();
       Utils.getCouchDbLabelClient();
@@ -97,15 +89,6 @@ public class CouchDbInstallationStep extends InstallationStep {
     addPipelineView();
   }
 
-  private void addRdfEndpoints() {
-    ExtensionsServiceEndpointStorageImpl rdfEndpointStorage = new ExtensionsServiceEndpointStorageImpl();
-    initRdfEndpointPorts
-        .forEach(p -> rdfEndpointStorage
-            .addExtensionsServiceEndpoint(new ExtensionsServiceEndpoint(initRdfEndpointHost + p)));
-
-    logSuccess("Discovering pipeline element endpoints...");
-  }
-
   private void addNotificationView() {
     try {
       DesignDocument userDocument = prepareDocument("_design/notificationtypes");
diff --git a/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/UserResourceManager.java b/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/UserResourceManager.java
index 719ea614c2..a2d3327932 100644
--- a/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/UserResourceManager.java
+++ b/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/UserResourceManager.java
@@ -29,23 +29,24 @@ import org.apache.streampipes.model.client.user.RegistrationData;
 import org.apache.streampipes.model.client.user.Role;
 import org.apache.streampipes.model.client.user.UserAccount;
 import org.apache.streampipes.model.client.user.UserActivationToken;
-import org.apache.streampipes.model.util.ElementIdGenerator;
 import org.apache.streampipes.storage.api.IPasswordRecoveryTokenStorage;
 import org.apache.streampipes.storage.api.IUserActivationTokenStorage;
 import org.apache.streampipes.storage.api.IUserStorage;
 import org.apache.streampipes.storage.couchdb.CouchDbStorageManager;
 import org.apache.streampipes.storage.management.StorageDispatcher;
 import org.apache.streampipes.user.management.util.PasswordUtil;
+import org.apache.streampipes.user.management.util.TokenUtil;
 
 import java.io.IOException;
 import java.security.NoSuchAlgorithmException;
 import java.security.spec.InvalidKeySpecException;
 import java.util.HashSet;
 import java.util.List;
-import java.util.stream.Collectors;
 
 public class UserResourceManager extends AbstractResourceManager<IUserStorage> {
 
+  private static final int RECOVERY_TOKEN_LENGTH = 40;
+
   public UserResourceManager() {
     super(StorageDispatcher.INSTANCE.getNoSqlStore().getUserStorageAPI());
   }
@@ -89,7 +90,7 @@ public class UserResourceManager extends AbstractResourceManager<IUserStorage> {
         throw new UsernameAlreadyTakenException("Username already taken");
       }
       String encryptedPassword = PasswordUtil.encryptPassword(data.getPassword());
-      List<Role> roles = data.getRoles().stream().map(Role::valueOf).collect(Collectors.toList());
+      List<Role> roles = data.getRoles().stream().map(Role::valueOf).toList();
       UserAccount user = UserAccount.from(data.getUsername(), encryptedPassword, new HashSet<>(roles));
       user.setUsername(data.getUsername());
       user.setPassword(encryptedPassword);
@@ -118,7 +119,7 @@ public class UserResourceManager extends AbstractResourceManager<IUserStorage> {
   }
 
   private void createTokenAndSendActivationMail(String username) throws IOException {
-    String activationCode = ElementIdGenerator.makeRecoveryToken();
+    String activationCode =  TokenUtil.generateToken(RECOVERY_TOKEN_LENGTH);
     storeActivationCode(username, activationCode);
   }
 
@@ -132,7 +133,7 @@ public class UserResourceManager extends AbstractResourceManager<IUserStorage> {
   public void sendPasswordRecoveryLink(String username) throws UserNotFoundException, IOException {
     // send a password recovery link to the user
     if (db.checkUser(username)) {
-      String recoveryCode = ElementIdGenerator.makeRecoveryToken();
+      String recoveryCode = TokenUtil.generateToken(RECOVERY_TOKEN_LENGTH);
       storeRecoveryCode(username, recoveryCode);
       new MailSender().sendPasswordRecoveryMail(username, recoveryCode);
     }
diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/admin/ExtensionsServiceEndpointResource.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/admin/ExtensionsServiceEndpointResource.java
index a2d83a014f..d1f3c6941f 100644
--- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/admin/ExtensionsServiceEndpointResource.java
+++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/admin/ExtensionsServiceEndpointResource.java
@@ -31,16 +31,13 @@ import org.apache.streampipes.rest.core.base.impl.AbstractAuthGuardedRestResourc
 import org.apache.streampipes.rest.security.AuthConstants;
 import org.apache.streampipes.rest.shared.exception.SpMessageException;
 import org.apache.streampipes.sdk.utils.Assets;
-import org.apache.streampipes.storage.api.IExtensionsServiceEndpointStorage;
 
 import org.apache.http.client.fluent.Request;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.DeleteMapping;
 import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -55,32 +52,6 @@ import java.util.List;
 @PreAuthorize(AuthConstants.IS_ADMIN_ROLE)
 public class ExtensionsServiceEndpointResource extends AbstractAuthGuardedRestResource {
 
-  @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
-  public ResponseEntity<List<ExtensionsServiceEndpoint>> getAllEndpoints() {
-    //TODO: return the endpoint of passing services
-    return ok(getEndpoints());
-  }
-
-  @PostMapping(produces = MediaType.APPLICATION_JSON_VALUE)
-  public ResponseEntity<Void> addRdfEndpoint(@RequestBody ExtensionsServiceEndpoint extensionsServiceEndpoint) {
-    getRdfEndpointStorage()
-        .addExtensionsServiceEndpoint(extensionsServiceEndpoint);
-
-    return ok();
-  }
-
-
-  @DeleteMapping(
-      path = "/{rdfEndpointId}",
-      produces = MediaType.APPLICATION_JSON_VALUE,
-      consumes = MediaType.APPLICATION_JSON_VALUE)
-  public ResponseEntity<Void> removeRdfEndpoint(@PathVariable("rdfEndpointId") String rdfEndpointId) {
-    getRdfEndpointStorage()
-        .removeExtensionsServiceEndpoint(rdfEndpointId);
-
-    return ok();
-  }
-
   @GetMapping(path = "/items", produces = MediaType.APPLICATION_JSON_VALUE)
   public ResponseEntity<List<ExtensionsServiceEndpointItem>> getEndpointContents() {
     List<ExtensionsServiceEndpoint> endpoints = getEndpoints();
@@ -213,8 +184,4 @@ public class ExtensionsServiceEndpointResource extends AbstractAuthGuardedRestRe
   private List<DataSinkDescription> getAllDataSinks() {
     return getNoSqlStorage().getDataSinkStorage().getAll();
   }
-
-  private IExtensionsServiceEndpointStorage getRdfEndpointStorage() {
-    return getNoSqlStorage().getRdfEndpointStorage();
-  }
 }
diff --git a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/INoSqlStorage.java b/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/INoSqlStorage.java
index a87b0fabff..98a1ec78c5 100644
--- a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/INoSqlStorage.java
+++ b/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/INoSqlStorage.java
@@ -44,8 +44,6 @@ public interface INoSqlStorage {
 
   IVisualizationStorage getVisualizationStorageApi();
 
-  IExtensionsServiceEndpointStorage getRdfEndpointStorage();
-
   IAssetDashboardStorage getAssetDashboardStorage();
 
   IDataLakeStorage getDataLakeStorage();
diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/CouchDbStorageManager.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/CouchDbStorageManager.java
index 87886fc7c9..3b9533ee26 100644
--- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/CouchDbStorageManager.java
+++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/CouchDbStorageManager.java
@@ -29,7 +29,6 @@ import org.apache.streampipes.storage.api.IDataLakeStorage;
 import org.apache.streampipes.storage.api.IDataProcessorStorage;
 import org.apache.streampipes.storage.api.IDataSinkStorage;
 import org.apache.streampipes.storage.api.IDataStreamStorage;
-import org.apache.streampipes.storage.api.IExtensionsServiceEndpointStorage;
 import org.apache.streampipes.storage.api.IFileMetadataStorage;
 import org.apache.streampipes.storage.api.IGenericStorage;
 import org.apache.streampipes.storage.api.IImageStorage;
@@ -62,7 +61,6 @@ import org.apache.streampipes.storage.couchdb.impl.DataProcessorStorageImpl;
 import org.apache.streampipes.storage.couchdb.impl.DataSinkStorageImpl;
 import org.apache.streampipes.storage.couchdb.impl.DataStreamStorageImpl;
 import org.apache.streampipes.storage.couchdb.impl.ExtensionsServiceConfigStorageImpl;
-import org.apache.streampipes.storage.couchdb.impl.ExtensionsServiceEndpointStorageImpl;
 import org.apache.streampipes.storage.couchdb.impl.ExtensionsServiceStorageImpl;
 import org.apache.streampipes.storage.couchdb.impl.FileMetadataStorageImpl;
 import org.apache.streampipes.storage.couchdb.impl.GenericStorageImpl;
@@ -139,11 +137,6 @@ public enum CouchDbStorageManager implements INoSqlStorage {
     return new VisualizationStorageImpl();
   }
 
-  @Override
-  public IExtensionsServiceEndpointStorage getRdfEndpointStorage() {
-    return new ExtensionsServiceEndpointStorageImpl();
-  }
-
   @Override
   public IAssetDashboardStorage getAssetDashboardStorage() {
     return new AssetDashboardStorageImpl();
diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/ExtensionsServiceEndpointStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/ExtensionsServiceEndpointStorageImpl.java
deleted file mode 100644
index 6cc882ff91..0000000000
--- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/ExtensionsServiceEndpointStorageImpl.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.streampipes.storage.couchdb.impl;
-
-import org.apache.streampipes.model.client.endpoint.ExtensionsServiceEndpoint;
-import org.apache.streampipes.storage.api.IExtensionsServiceEndpointStorage;
-import org.apache.streampipes.storage.couchdb.dao.AbstractDao;
-import org.apache.streampipes.storage.couchdb.utils.Utils;
-
-import java.util.List;
-
-public class ExtensionsServiceEndpointStorageImpl extends AbstractDao<ExtensionsServiceEndpoint>
-    implements IExtensionsServiceEndpointStorage {
-
-  public ExtensionsServiceEndpointStorageImpl() {
-    super(Utils::getCouchDbRdfEndpointClient, ExtensionsServiceEndpoint.class);
-  }
-
-  @Override
-  public void addExtensionsServiceEndpoint(ExtensionsServiceEndpoint extensionsServiceEndpoint) {
-    persist(extensionsServiceEndpoint);
-  }
-
-  @Override
-  public void removeExtensionsServiceEndpoint(String rdfEndpointId) {
-    delete(rdfEndpointId);
-  }
-
-  @Override
-  public List<ExtensionsServiceEndpoint> getExtensionsServiceEndpoints() {
-    return findAll();
-  }
-
-}
diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/utils/Utils.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/utils/Utils.java
index 401001d9d4..1d4819cf1a 100644
--- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/utils/Utils.java
+++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/utils/Utils.java
@@ -114,12 +114,6 @@ public class Utils {
     return getCouchDbStandardSerializerClient("visualizations");
   }
 
-  //TODO: Remove??
-  public static CouchDbClient getCouchDbRdfEndpointClient() {
-    CouchDbClient dbClient = new CouchDbClient(props("rdfendpoint"));
-    return dbClient;
-  }
-
   public static CouchDbClient getCouchDbDataExplorerDashboardClient() {
     return getCouchDbGsonClient("dataexplorerdashboard");
   }
diff --git a/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/util/TokenUtil.java b/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/util/TokenUtil.java
index c16a126939..2233c8c20e 100644
--- a/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/util/TokenUtil.java
+++ b/streampipes-user-management/src/main/java/org/apache/streampipes/user/management/util/TokenUtil.java
@@ -21,7 +21,7 @@ import org.apache.streampipes.model.client.user.RawUserApiToken;
 import org.apache.streampipes.model.client.user.UserApiToken;
 
 import org.apache.commons.codec.digest.DigestUtils;
-import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.commons.text.RandomStringGenerator;
 
 import java.util.UUID;
 
@@ -53,7 +53,15 @@ public class TokenUtil {
   }
 
   private static String generateToken() {
-    return RandomStringUtils.randomAlphanumeric(TOKEN_LENGTH);
+    return generateToken(TOKEN_LENGTH);
+  }
+
+  public static String generateToken(int tokenLength){
+    // allowing all ASCII-characters from decimal id 33 to 125
+    // see https://www.cs.cmu.edu/~pattis/15-1XX/common/handouts/ascii.html for full list
+    var pwdGenerator = new RandomStringGenerator.Builder().withinRange(33, 125)
+                                                          .build();
+    return pwdGenerator.generate(tokenLength);
   }
 
   public static String hashToken(String token) {
diff --git a/ui/angular.json b/ui/angular.json
index e88495a46a..78e63d3fdb 100644
--- a/ui/angular.json
+++ b/ui/angular.json
@@ -30,7 +30,6 @@
             "styles": ["src/scss/main.scss"],
             "scripts": [
               "node_modules/jquery/dist/jquery.min.js",
-              "node_modules/datatables.net/js/jquery.dataTables.js",
               "node_modules/jquery-ui-dist/jquery-ui.js",
               "node_modules/quill/dist/quill.js"
             ],
diff --git a/ui/package-lock.json b/ui/package-lock.json
index 84cd1acda2..e15efaf62a 100644
--- a/ui/package-lock.json
+++ b/ui/package-lock.json
@@ -31,16 +31,12 @@
         "@ngx-loading-bar/http-client": "6.0.2",
         "@panzoom/panzoom": "^4.5.1",
         "@swimlane/ngx-charts": "^20.4.1",
-        "angular-datatables": "^16.0.1",
         "angular-gridster2": "^16.0.0",
-        "angular2-uuid": "1.1.1",
         "codemirror": "^5.65.11",
         "console-browserify": "^1.2.0",
         "d3-array": "^3.2.4",
         "d3-contour": "^4.0.2",
         "dagre": "0.8.5",
-        "datatables.net": "^1.13.1",
-        "datatables.net-dt": "^1.13.1",
         "date-fns": "^2.30.0",
         "echarts": "^5.4.3",
         "echarts-gl": "^2.0.9",
@@ -121,7 +117,7 @@
         "resize-observer-polyfill": "^1.5.1",
         "to-string-loader": "^1.2.0",
         "typescript": "4.9.3",
-        "webpack": "^5.89.0",
+        "webpack": "^5.91.0",
         "webpack-cli": "^5.1.4",
         "webpack-merge": "^5.8.0"
       },
@@ -1730,38 +1726,6 @@
         "node": ">=6.9.0"
       }
     },
-    "node_modules/@babel/helper-compilation-targets/node_modules/browserslist": {
-      "version": "4.22.2",
-      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz",
-      "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/browserslist"
-        },
-        {
-          "type": "tidelift",
-          "url": "https://tidelift.com/funding/github/npm/browserslist"
-        },
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "dependencies": {
-        "caniuse-lite": "^1.0.30001565",
-        "electron-to-chromium": "^1.4.601",
-        "node-releases": "^2.0.14",
-        "update-browserslist-db": "^1.0.13"
-      },
-      "bin": {
-        "browserslist": "cli.js"
-      },
-      "engines": {
-        "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
-      }
-    },
     "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": {
       "version": "5.1.1",
       "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@@ -4745,13 +4709,13 @@
       "dev": true
     },
     "node_modules/@jridgewell/trace-mapping": {
-      "version": "0.3.17",
-      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
-      "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
+      "version": "0.3.25",
+      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+      "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
       "dev": true,
       "dependencies": {
-        "@jridgewell/resolve-uri": "3.1.0",
-        "@jridgewell/sourcemap-codec": "1.4.14"
+        "@jridgewell/resolve-uri": "^3.1.0",
+        "@jridgewell/sourcemap-codec": "^1.4.14"
       }
     },
     "node_modules/@jsplumb/browser-ui": {
@@ -6870,9 +6834,9 @@
       }
     },
     "node_modules/@types/estree": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz",
-      "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ=="
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
+      "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw=="
     },
     "node_modules/@types/express": {
       "version": "4.17.21",
@@ -7691,9 +7655,9 @@
       }
     },
     "node_modules/@webassemblyjs/ast": {
-      "version": "1.11.6",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
-      "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==",
+      "version": "1.12.1",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz",
+      "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==",
       "dev": true,
       "dependencies": {
         "@webassemblyjs/helper-numbers": "1.11.6",
@@ -7713,9 +7677,9 @@
       "dev": true
     },
     "node_modules/@webassemblyjs/helper-buffer": {
-      "version": "1.11.6",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz",
-      "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==",
+      "version": "1.12.1",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz",
+      "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==",
       "dev": true
     },
     "node_modules/@webassemblyjs/helper-numbers": {
@@ -7736,15 +7700,15 @@
       "dev": true
     },
     "node_modules/@webassemblyjs/helper-wasm-section": {
-      "version": "1.11.6",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz",
-      "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==",
+      "version": "1.12.1",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz",
+      "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==",
       "dev": true,
       "dependencies": {
-        "@webassemblyjs/ast": "1.11.6",
-        "@webassemblyjs/helper-buffer": "1.11.6",
+        "@webassemblyjs/ast": "1.12.1",
+        "@webassemblyjs/helper-buffer": "1.12.1",
         "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
-        "@webassemblyjs/wasm-gen": "1.11.6"
+        "@webassemblyjs/wasm-gen": "1.12.1"
       }
     },
     "node_modules/@webassemblyjs/ieee754": {
@@ -7772,28 +7736,28 @@
       "dev": true
     },
     "node_modules/@webassemblyjs/wasm-edit": {
-      "version": "1.11.6",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz",
-      "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==",
+      "version": "1.12.1",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz",
+      "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==",
       "dev": true,
       "dependencies": {
-        "@webassemblyjs/ast": "1.11.6",
-        "@webassemblyjs/helper-buffer": "1.11.6",
+        "@webassemblyjs/ast": "1.12.1",
+        "@webassemblyjs/helper-buffer": "1.12.1",
         "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
-        "@webassemblyjs/helper-wasm-section": "1.11.6",
-        "@webassemblyjs/wasm-gen": "1.11.6",
-        "@webassemblyjs/wasm-opt": "1.11.6",
-        "@webassemblyjs/wasm-parser": "1.11.6",
-        "@webassemblyjs/wast-printer": "1.11.6"
+        "@webassemblyjs/helper-wasm-section": "1.12.1",
+        "@webassemblyjs/wasm-gen": "1.12.1",
+        "@webassemblyjs/wasm-opt": "1.12.1",
+        "@webassemblyjs/wasm-parser": "1.12.1",
+        "@webassemblyjs/wast-printer": "1.12.1"
       }
     },
     "node_modules/@webassemblyjs/wasm-gen": {
-      "version": "1.11.6",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz",
-      "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==",
+      "version": "1.12.1",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz",
+      "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==",
       "dev": true,
       "dependencies": {
-        "@webassemblyjs/ast": "1.11.6",
+        "@webassemblyjs/ast": "1.12.1",
         "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
         "@webassemblyjs/ieee754": "1.11.6",
         "@webassemblyjs/leb128": "1.11.6",
@@ -7801,24 +7765,24 @@
       }
     },
     "node_modules/@webassemblyjs/wasm-opt": {
-      "version": "1.11.6",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz",
-      "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==",
+      "version": "1.12.1",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz",
+      "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==",
       "dev": true,
       "dependencies": {
-        "@webassemblyjs/ast": "1.11.6",
-        "@webassemblyjs/helper-buffer": "1.11.6",
-        "@webassemblyjs/wasm-gen": "1.11.6",
-        "@webassemblyjs/wasm-parser": "1.11.6"
+        "@webassemblyjs/ast": "1.12.1",
+        "@webassemblyjs/helper-buffer": "1.12.1",
+        "@webassemblyjs/wasm-gen": "1.12.1",
+        "@webassemblyjs/wasm-parser": "1.12.1"
       }
     },
     "node_modules/@webassemblyjs/wasm-parser": {
-      "version": "1.11.6",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz",
-      "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==",
+      "version": "1.12.1",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz",
+      "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==",
       "dev": true,
       "dependencies": {
-        "@webassemblyjs/ast": "1.11.6",
+        "@webassemblyjs/ast": "1.12.1",
         "@webassemblyjs/helper-api-error": "1.11.6",
         "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
         "@webassemblyjs/ieee754": "1.11.6",
@@ -7827,12 +7791,12 @@
       }
     },
     "node_modules/@webassemblyjs/wast-printer": {
-      "version": "1.11.6",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz",
-      "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==",
+      "version": "1.12.1",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz",
+      "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==",
       "dev": true,
       "dependencies": {
-        "@webassemblyjs/ast": "1.11.6",
+        "@webassemblyjs/ast": "1.12.1",
         "@xtuc/long": "4.2.2"
       }
     },
@@ -8238,11 +8202,6 @@
         "ajv": "^8.8.2"
       }
     },
-    "node_modules/angular-datatables": {
-      "version": "16.0.1",
-      "resolved": "https://registry.npmjs.org/angular-datatables/-/angular-datatables-16.0.1.tgz",
-      "integrity": "sha512-RXDQQqIWAyFtpyGI800heT/sHho2+3vxIeNN+XxS5VmezZiQSjeeBBo+Lp2CpA3XD7q3ro08Rhks/i2FvbF7PA=="
-    },
     "node_modules/angular-gridster2": {
       "version": "16.0.0",
       "resolved": "https://registry.npmjs.org/angular-gridster2/-/angular-gridster2-16.0.0.tgz",
@@ -8256,11 +8215,6 @@
         "rxjs": "^7.0.0"
       }
     },
-    "node_modules/angular2-uuid": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/angular2-uuid/-/angular2-uuid-1.1.1.tgz",
-      "integrity": "sha512-6AXPyii9q8KBFGagybLNVmdGJLPcVZAhmv3odNGSJIA18LuJ3xOe6uN9GvjlQsGfdmYeuxlsGnFEUu7gPhkc+g=="
-    },
     "node_modules/ansi-colors": {
       "version": "4.1.3",
       "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
@@ -9132,9 +9086,9 @@
       }
     },
     "node_modules/browserslist": {
-      "version": "4.21.5",
-      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz",
-      "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==",
+      "version": "4.23.0",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz",
+      "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==",
       "dev": true,
       "funding": [
         {
@@ -9144,13 +9098,17 @@
         {
           "type": "tidelift",
           "url": "https://tidelift.com/funding/github/npm/browserslist"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
         }
       ],
       "dependencies": {
-        "caniuse-lite": "^1.0.30001449",
-        "electron-to-chromium": "^1.4.284",
-        "node-releases": "^2.0.8",
-        "update-browserslist-db": "^1.0.10"
+        "caniuse-lite": "^1.0.30001587",
+        "electron-to-chromium": "^1.4.668",
+        "node-releases": "^2.0.14",
+        "update-browserslist-db": "^1.0.13"
       },
       "bin": {
         "browserslist": "cli.js"
@@ -9321,9 +9279,9 @@
       }
     },
     "node_modules/caniuse-lite": {
-      "version": "1.0.30001572",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001572.tgz",
-      "integrity": "sha512-1Pbh5FLmn5y4+QhNyJE9j3/7dK44dGB83/ZMjv/qJk86TvDbjk0LosiZo0i0WB0Vx607qMX9jYrn1VLHCkN4rw==",
+      "version": "1.0.30001599",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001599.tgz",
+      "integrity": "sha512-LRAQHZ4yT1+f9LemSMeqdMpMxZcc4RMWdj4tiFe3G8tNkWK+E58g+/tzotb5cU6TbcVJLr4fySiAW7XmxQvZQA==",
       "dev": true,
       "funding": [
         {
@@ -10124,38 +10082,6 @@
         "url": "https://opencollective.com/core-js"
       }
     },
-    "node_modules/core-js-compat/node_modules/browserslist": {
-      "version": "4.22.2",
-      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz",
-      "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/browserslist"
-        },
-        {
-          "type": "tidelift",
-          "url": "https://tidelift.com/funding/github/npm/browserslist"
-        },
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "dependencies": {
-        "caniuse-lite": "^1.0.30001565",
-        "electron-to-chromium": "^1.4.601",
-        "node-releases": "^2.0.14",
-        "update-browserslist-db": "^1.0.13"
-      },
-      "bin": {
-        "browserslist": "cli.js"
-      },
-      "engines": {
-        "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
-      }
-    },
     "node_modules/core-js-pure": {
       "version": "3.33.2",
       "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.33.2.tgz",
@@ -11321,23 +11247,6 @@
         "node": ">=10"
       }
     },
-    "node_modules/datatables.net": {
-      "version": "1.13.1",
-      "resolved": "https://registry.npmjs.org/datatables.net/-/datatables.net-1.13.1.tgz",
-      "integrity": "sha512-cX5dDHsbVdLLYKsWOSE0MvuGUcV88zU5dZ/taK2puJV6F9Fw0CFsP3+U/kr+qpDSFOBLWISRyM4Q9wWWovPTNg==",
-      "dependencies": {
-        "jquery": ">=1.7"
-      }
-    },
-    "node_modules/datatables.net-dt": {
-      "version": "1.13.1",
-      "resolved": "https://registry.npmjs.org/datatables.net-dt/-/datatables.net-dt-1.13.1.tgz",
-      "integrity": "sha512-J5ul/Y+Hpyfh8y02DKwgbmUij4e4R6bstnx4iYvY7FV2b2XuCP0Qow/Uuc0gtxDHSz2bTsoeRHqg4teoGftVDg==",
-      "dependencies": {
-        "datatables.net": ">=1.12.1",
-        "jquery": ">=1.7"
-      }
-    },
     "node_modules/date-fns": {
       "version": "2.30.0",
       "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
@@ -11940,9 +11849,9 @@
       }
     },
     "node_modules/electron-to-chromium": {
-      "version": "1.4.616",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.616.tgz",
-      "integrity": "sha512-1n7zWYh8eS0L9Uy+GskE0lkBUNK83cXTVJI0pU3mGprFsbfSdAc15VTFbo+A+Bq4pwstmL30AVcEU3Fo463lNg==",
+      "version": "1.4.713",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.713.tgz",
+      "integrity": "sha512-vDarADhwntXiULEdmWd77g2dV6FrNGa8ecAC29MZ4TwPut2fvosD0/5sJd1qWNNe8HcJFAC+F5Lf9jW1NPtWmw==",
       "dev": true
     },
     "node_modules/elkjs": {
@@ -12063,9 +11972,9 @@
       }
     },
     "node_modules/enhanced-resolve": {
-      "version": "5.15.0",
-      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
-      "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==",
+      "version": "5.16.0",
+      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz",
+      "integrity": "sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==",
       "dev": true,
       "dependencies": {
         "graceful-fs": "^4.2.4",
@@ -13590,9 +13499,9 @@
       }
     },
     "node_modules/graceful-fs": {
-      "version": "4.2.10",
-      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
-      "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="
+      "version": "4.2.11",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
     },
     "node_modules/grapheme-splitter": {
       "version": "1.0.4",
@@ -23181,13 +23090,13 @@
       }
     },
     "node_modules/terser": {
-      "version": "5.16.3",
-      "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.3.tgz",
-      "integrity": "sha512-v8wWLaS/xt3nE9dgKEWhNUFP6q4kngO5B8eYFUuebsu7Dw/UNAnpUod6UHo04jSSkv8TzKHjZDSd7EXdDQAl8Q==",
+      "version": "5.29.2",
+      "resolved": "https://registry.npmjs.org/terser/-/terser-5.29.2.tgz",
+      "integrity": "sha512-ZiGkhUBIM+7LwkNjXYJq8svgkd+QK3UUr0wJqY4MieaezBSAIPgbSPZyIx0idM6XWK5CMzSWa8MJIzmRcB8Caw==",
       "dev": true,
       "dependencies": {
-        "@jridgewell/source-map": "^0.3.2",
-        "acorn": "^8.5.0",
+        "@jridgewell/source-map": "^0.3.3",
+        "acorn": "^8.8.2",
         "commander": "^2.20.0",
         "source-map-support": "~0.5.20"
       },
@@ -23199,16 +23108,16 @@
       }
     },
     "node_modules/terser-webpack-plugin": {
-      "version": "5.3.9",
-      "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz",
-      "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==",
+      "version": "5.3.10",
+      "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz",
+      "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==",
       "dev": true,
       "dependencies": {
-        "@jridgewell/trace-mapping": "^0.3.17",
+        "@jridgewell/trace-mapping": "^0.3.20",
         "jest-worker": "^27.4.5",
         "schema-utils": "^3.1.1",
         "serialize-javascript": "^6.0.1",
-        "terser": "^5.16.8"
+        "terser": "^5.26.0"
       },
       "engines": {
         "node": ">= 10.13.0"
@@ -23257,12 +23166,6 @@
         "ajv": "^6.9.1"
       }
     },
-    "node_modules/terser-webpack-plugin/node_modules/commander": {
-      "version": "2.20.3",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
-      "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
-      "dev": true
-    },
     "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": {
       "version": "0.4.1",
       "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
@@ -23287,24 +23190,6 @@
         "url": "https://opencollective.com/webpack"
       }
     },
-    "node_modules/terser-webpack-plugin/node_modules/terser": {
-      "version": "5.21.0",
-      "resolved": "https://registry.npmjs.org/terser/-/terser-5.21.0.tgz",
-      "integrity": "sha512-WtnFKrxu9kaoXuiZFSGrcAvvBqAdmKx0SFNmVNYdJamMu9yyN3I/QF0FbH4QcqJQ+y1CJnzxGIKH0cSj+FGYRw==",
-      "dev": true,
-      "dependencies": {
-        "@jridgewell/source-map": "^0.3.3",
-        "acorn": "^8.8.2",
-        "commander": "^2.20.0",
-        "source-map-support": "~0.5.20"
-      },
-      "bin": {
-        "terser": "bin/terser"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
     "node_modules/terser/node_modules/commander": {
       "version": "2.20.3",
       "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
@@ -24541,9 +24426,9 @@
       }
     },
     "node_modules/watchpack": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
-      "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz",
+      "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==",
       "dev": true,
       "dependencies": {
         "glob-to-regexp": "^0.4.1",
@@ -24597,34 +24482,34 @@
       "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
     },
     "node_modules/webpack": {
-      "version": "5.89.0",
-      "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.89.0.tgz",
-      "integrity": "sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==",
+      "version": "5.91.0",
+      "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz",
+      "integrity": "sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==",
       "dev": true,
       "dependencies": {
         "@types/eslint-scope": "^3.7.3",
-        "@types/estree": "^1.0.0",
-        "@webassemblyjs/ast": "^1.11.5",
-        "@webassemblyjs/wasm-edit": "^1.11.5",
-        "@webassemblyjs/wasm-parser": "^1.11.5",
+        "@types/estree": "^1.0.5",
+        "@webassemblyjs/ast": "^1.12.1",
+        "@webassemblyjs/wasm-edit": "^1.12.1",
+        "@webassemblyjs/wasm-parser": "^1.12.1",
         "acorn": "^8.7.1",
         "acorn-import-assertions": "^1.9.0",
-        "browserslist": "^4.14.5",
+        "browserslist": "^4.21.10",
         "chrome-trace-event": "^1.0.2",
-        "enhanced-resolve": "^5.15.0",
+        "enhanced-resolve": "^5.16.0",
         "es-module-lexer": "^1.2.1",
         "eslint-scope": "5.1.1",
         "events": "^3.2.0",
         "glob-to-regexp": "^0.4.1",
-        "graceful-fs": "^4.2.9",
+        "graceful-fs": "^4.2.11",
         "json-parse-even-better-errors": "^2.3.1",
         "loader-runner": "^4.2.0",
         "mime-types": "^2.1.27",
         "neo-async": "^2.6.2",
         "schema-utils": "^3.2.0",
         "tapable": "^2.1.1",
-        "terser-webpack-plugin": "^5.3.7",
-        "watchpack": "^2.4.0",
+        "terser-webpack-plugin": "^5.3.10",
+        "watchpack": "^2.4.1",
         "webpack-sources": "^3.2.3"
       },
       "bin": {
@@ -24785,9 +24670,9 @@
       }
     },
     "node_modules/webpack-dev-server/node_modules/webpack-dev-middleware": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz",
-      "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==",
+      "version": "5.3.4",
+      "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz",
+      "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==",
       "dev": true,
       "dependencies": {
         "colorette": "^2.0.10",
@@ -26461,18 +26346,6 @@
         "semver": "^6.3.1"
       },
       "dependencies": {
-        "browserslist": {
-          "version": "4.22.2",
-          "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz",
-          "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==",
-          "dev": true,
-          "requires": {
-            "caniuse-lite": "^1.0.30001565",
-            "electron-to-chromium": "^1.4.601",
-            "node-releases": "^2.0.14",
-            "update-browserslist-db": "^1.0.13"
-          }
-        },
         "lru-cache": {
           "version": "5.1.1",
           "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@@ -28534,13 +28407,13 @@
       "dev": true
     },
     "@jridgewell/trace-mapping": {
-      "version": "0.3.17",
-      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
-      "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
+      "version": "0.3.25",
+      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+      "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
       "dev": true,
       "requires": {
-        "@jridgewell/resolve-uri": "3.1.0",
-        "@jridgewell/sourcemap-codec": "1.4.14"
+        "@jridgewell/resolve-uri": "^3.1.0",
+        "@jridgewell/sourcemap-codec": "^1.4.14"
       }
     },
     "@jsplumb/browser-ui": {
@@ -30372,9 +30245,9 @@
       }
     },
     "@types/estree": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz",
-      "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ=="
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
+      "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw=="
     },
     "@types/express": {
       "version": "4.17.21",
@@ -31033,9 +30906,9 @@
       "requires": {}
     },
     "@webassemblyjs/ast": {
-      "version": "1.11.6",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
-      "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==",
+      "version": "1.12.1",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz",
+      "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==",
       "dev": true,
       "requires": {
         "@webassemblyjs/helper-numbers": "1.11.6",
@@ -31055,9 +30928,9 @@
       "dev": true
     },
     "@webassemblyjs/helper-buffer": {
-      "version": "1.11.6",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz",
-      "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==",
+      "version": "1.12.1",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz",
+      "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==",
       "dev": true
     },
     "@webassemblyjs/helper-numbers": {
@@ -31078,15 +30951,15 @@
       "dev": true
     },
     "@webassemblyjs/helper-wasm-section": {
-      "version": "1.11.6",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz",
-      "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==",
+      "version": "1.12.1",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz",
+      "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==",
       "dev": true,
       "requires": {
-        "@webassemblyjs/ast": "1.11.6",
-        "@webassemblyjs/helper-buffer": "1.11.6",
+        "@webassemblyjs/ast": "1.12.1",
+        "@webassemblyjs/helper-buffer": "1.12.1",
         "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
-        "@webassemblyjs/wasm-gen": "1.11.6"
+        "@webassemblyjs/wasm-gen": "1.12.1"
       }
     },
     "@webassemblyjs/ieee754": {
@@ -31114,28 +30987,28 @@
       "dev": true
     },
     "@webassemblyjs/wasm-edit": {
-      "version": "1.11.6",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz",
-      "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==",
+      "version": "1.12.1",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz",
+      "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==",
       "dev": true,
       "requires": {
-        "@webassemblyjs/ast": "1.11.6",
-        "@webassemblyjs/helper-buffer": "1.11.6",
+        "@webassemblyjs/ast": "1.12.1",
+        "@webassemblyjs/helper-buffer": "1.12.1",
         "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
-        "@webassemblyjs/helper-wasm-section": "1.11.6",
-        "@webassemblyjs/wasm-gen": "1.11.6",
-        "@webassemblyjs/wasm-opt": "1.11.6",
-        "@webassemblyjs/wasm-parser": "1.11.6",
-        "@webassemblyjs/wast-printer": "1.11.6"
+        "@webassemblyjs/helper-wasm-section": "1.12.1",
+        "@webassemblyjs/wasm-gen": "1.12.1",
+        "@webassemblyjs/wasm-opt": "1.12.1",
+        "@webassemblyjs/wasm-parser": "1.12.1",
+        "@webassemblyjs/wast-printer": "1.12.1"
       }
     },
     "@webassemblyjs/wasm-gen": {
-      "version": "1.11.6",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz",
-      "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==",
+      "version": "1.12.1",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz",
+      "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==",
       "dev": true,
       "requires": {
-        "@webassemblyjs/ast": "1.11.6",
+        "@webassemblyjs/ast": "1.12.1",
         "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
         "@webassemblyjs/ieee754": "1.11.6",
         "@webassemblyjs/leb128": "1.11.6",
@@ -31143,24 +31016,24 @@
       }
     },
     "@webassemblyjs/wasm-opt": {
-      "version": "1.11.6",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz",
-      "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==",
+      "version": "1.12.1",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz",
+      "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==",
       "dev": true,
       "requires": {
-        "@webassemblyjs/ast": "1.11.6",
-        "@webassemblyjs/helper-buffer": "1.11.6",
-        "@webassemblyjs/wasm-gen": "1.11.6",
-        "@webassemblyjs/wasm-parser": "1.11.6"
+        "@webassemblyjs/ast": "1.12.1",
+        "@webassemblyjs/helper-buffer": "1.12.1",
+        "@webassemblyjs/wasm-gen": "1.12.1",
+        "@webassemblyjs/wasm-parser": "1.12.1"
       }
     },
     "@webassemblyjs/wasm-parser": {
-      "version": "1.11.6",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz",
-      "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==",
+      "version": "1.12.1",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz",
+      "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==",
       "dev": true,
       "requires": {
-        "@webassemblyjs/ast": "1.11.6",
+        "@webassemblyjs/ast": "1.12.1",
         "@webassemblyjs/helper-api-error": "1.11.6",
         "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
         "@webassemblyjs/ieee754": "1.11.6",
@@ -31169,12 +31042,12 @@
       }
     },
     "@webassemblyjs/wast-printer": {
-      "version": "1.11.6",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz",
-      "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==",
+      "version": "1.12.1",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz",
+      "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==",
       "dev": true,
       "requires": {
-        "@webassemblyjs/ast": "1.11.6",
+        "@webassemblyjs/ast": "1.12.1",
         "@xtuc/long": "4.2.2"
       }
     },
@@ -31471,11 +31344,6 @@
         "fast-deep-equal": "^3.1.3"
       }
     },
-    "angular-datatables": {
-      "version": "16.0.1",
-      "resolved": "https://registry.npmjs.org/angular-datatables/-/angular-datatables-16.0.1.tgz",
-      "integrity": "sha512-RXDQQqIWAyFtpyGI800heT/sHho2+3vxIeNN+XxS5VmezZiQSjeeBBo+Lp2CpA3XD7q3ro08Rhks/i2FvbF7PA=="
-    },
     "angular-gridster2": {
       "version": "16.0.0",
       "resolved": "https://registry.npmjs.org/angular-gridster2/-/angular-gridster2-16.0.0.tgz",
@@ -31484,11 +31352,6 @@
         "tslib": "^2.4.0"
       }
     },
-    "angular2-uuid": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/angular2-uuid/-/angular2-uuid-1.1.1.tgz",
-      "integrity": "sha512-6AXPyii9q8KBFGagybLNVmdGJLPcVZAhmv3odNGSJIA18LuJ3xOe6uN9GvjlQsGfdmYeuxlsGnFEUu7gPhkc+g=="
-    },
     "ansi-colors": {
       "version": "4.1.3",
       "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
@@ -32177,15 +32040,15 @@
       }
     },
     "browserslist": {
-      "version": "4.21.5",
-      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz",
-      "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==",
+      "version": "4.23.0",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz",
+      "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==",
       "dev": true,
       "requires": {
-        "caniuse-lite": "^1.0.30001449",
-        "electron-to-chromium": "^1.4.284",
-        "node-releases": "^2.0.8",
-        "update-browserslist-db": "^1.0.10"
+        "caniuse-lite": "^1.0.30001587",
+        "electron-to-chromium": "^1.4.668",
+        "node-releases": "^2.0.14",
+        "update-browserslist-db": "^1.0.13"
       }
     },
     "buffer": {
@@ -32306,9 +32169,9 @@
       "dev": true
     },
     "caniuse-lite": {
-      "version": "1.0.30001572",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001572.tgz",
-      "integrity": "sha512-1Pbh5FLmn5y4+QhNyJE9j3/7dK44dGB83/ZMjv/qJk86TvDbjk0LosiZo0i0WB0Vx607qMX9jYrn1VLHCkN4rw==",
+      "version": "1.0.30001599",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001599.tgz",
+      "integrity": "sha512-LRAQHZ4yT1+f9LemSMeqdMpMxZcc4RMWdj4tiFe3G8tNkWK+E58g+/tzotb5cU6TbcVJLr4fySiAW7XmxQvZQA==",
       "dev": true
     },
     "caseless": {
@@ -32902,20 +32765,6 @@
       "dev": true,
       "requires": {
         "browserslist": "^4.22.2"
-      },
-      "dependencies": {
-        "browserslist": {
-          "version": "4.22.2",
-          "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz",
-          "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==",
-          "dev": true,
-          "requires": {
-            "caniuse-lite": "^1.0.30001565",
-            "electron-to-chromium": "^1.4.601",
-            "node-releases": "^2.0.14",
-            "update-browserslist-db": "^1.0.13"
-          }
-        }
       }
     },
     "core-js-pure": {
@@ -33830,23 +33679,6 @@
         }
       }
     },
-    "datatables.net": {
-      "version": "1.13.1",
-      "resolved": "https://registry.npmjs.org/datatables.net/-/datatables.net-1.13.1.tgz",
-      "integrity": "sha512-cX5dDHsbVdLLYKsWOSE0MvuGUcV88zU5dZ/taK2puJV6F9Fw0CFsP3+U/kr+qpDSFOBLWISRyM4Q9wWWovPTNg==",
-      "requires": {
-        "jquery": ">=1.7"
-      }
-    },
-    "datatables.net-dt": {
-      "version": "1.13.1",
-      "resolved": "https://registry.npmjs.org/datatables.net-dt/-/datatables.net-dt-1.13.1.tgz",
-      "integrity": "sha512-J5ul/Y+Hpyfh8y02DKwgbmUij4e4R6bstnx4iYvY7FV2b2XuCP0Qow/Uuc0gtxDHSz2bTsoeRHqg4teoGftVDg==",
-      "requires": {
-        "datatables.net": ">=1.12.1",
-        "jquery": ">=1.7"
-      }
-    },
     "date-fns": {
       "version": "2.30.0",
       "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
@@ -34316,9 +34148,9 @@
       }
     },
     "electron-to-chromium": {
-      "version": "1.4.616",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.616.tgz",
-      "integrity": "sha512-1n7zWYh8eS0L9Uy+GskE0lkBUNK83cXTVJI0pU3mGprFsbfSdAc15VTFbo+A+Bq4pwstmL30AVcEU3Fo463lNg==",
+      "version": "1.4.713",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.713.tgz",
+      "integrity": "sha512-vDarADhwntXiULEdmWd77g2dV6FrNGa8ecAC29MZ4TwPut2fvosD0/5sJd1qWNNe8HcJFAC+F5Lf9jW1NPtWmw==",
       "dev": true
     },
     "elkjs": {
@@ -34428,9 +34260,9 @@
       "dev": true
     },
     "enhanced-resolve": {
-      "version": "5.15.0",
-      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
-      "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==",
+      "version": "5.16.0",
+      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz",
+      "integrity": "sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==",
       "dev": true,
       "requires": {
         "graceful-fs": "^4.2.4",
@@ -35570,9 +35402,9 @@
       }
     },
     "graceful-fs": {
-      "version": "4.2.10",
-      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
-      "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="
+      "version": "4.2.11",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
     },
     "grapheme-splitter": {
       "version": "1.0.4",
@@ -42656,13 +42488,13 @@
       }
     },
     "terser": {
-      "version": "5.16.3",
-      "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.3.tgz",
-      "integrity": "sha512-v8wWLaS/xt3nE9dgKEWhNUFP6q4kngO5B8eYFUuebsu7Dw/UNAnpUod6UHo04jSSkv8TzKHjZDSd7EXdDQAl8Q==",
+      "version": "5.29.2",
+      "resolved": "https://registry.npmjs.org/terser/-/terser-5.29.2.tgz",
+      "integrity": "sha512-ZiGkhUBIM+7LwkNjXYJq8svgkd+QK3UUr0wJqY4MieaezBSAIPgbSPZyIx0idM6XWK5CMzSWa8MJIzmRcB8Caw==",
       "dev": true,
       "requires": {
-        "@jridgewell/source-map": "^0.3.2",
-        "acorn": "^8.5.0",
+        "@jridgewell/source-map": "^0.3.3",
+        "acorn": "^8.8.2",
         "commander": "^2.20.0",
         "source-map-support": "~0.5.20"
       },
@@ -42676,16 +42508,16 @@
       }
     },
     "terser-webpack-plugin": {
-      "version": "5.3.9",
-      "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz",
-      "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==",
+      "version": "5.3.10",
+      "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz",
+      "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==",
       "dev": true,
       "requires": {
-        "@jridgewell/trace-mapping": "^0.3.17",
+        "@jridgewell/trace-mapping": "^0.3.20",
         "jest-worker": "^27.4.5",
         "schema-utils": "^3.1.1",
         "serialize-javascript": "^6.0.1",
-        "terser": "^5.16.8"
+        "terser": "^5.26.0"
       },
       "dependencies": {
         "ajv": {
@@ -42707,12 +42539,6 @@
           "dev": true,
           "requires": {}
         },
-        "commander": {
-          "version": "2.20.3",
-          "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
-          "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
-          "dev": true
-        },
         "json-schema-traverse": {
           "version": "0.4.1",
           "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
@@ -42729,18 +42555,6 @@
             "ajv": "^6.12.5",
             "ajv-keywords": "^3.5.2"
           }
-        },
-        "terser": {
-          "version": "5.21.0",
-          "resolved": "https://registry.npmjs.org/terser/-/terser-5.21.0.tgz",
-          "integrity": "sha512-WtnFKrxu9kaoXuiZFSGrcAvvBqAdmKx0SFNmVNYdJamMu9yyN3I/QF0FbH4QcqJQ+y1CJnzxGIKH0cSj+FGYRw==",
-          "dev": true,
-          "requires": {
-            "@jridgewell/source-map": "^0.3.3",
-            "acorn": "^8.8.2",
-            "commander": "^2.20.0",
-            "source-map-support": "~0.5.20"
-          }
         }
       }
     },
@@ -43661,9 +43475,9 @@
       }
     },
     "watchpack": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
-      "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz",
+      "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==",
       "dev": true,
       "requires": {
         "glob-to-regexp": "^0.4.1",
@@ -43711,34 +43525,34 @@
       "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
     },
     "webpack": {
-      "version": "5.89.0",
-      "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.89.0.tgz",
-      "integrity": "sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==",
+      "version": "5.91.0",
+      "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz",
+      "integrity": "sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==",
       "dev": true,
       "requires": {
         "@types/eslint-scope": "^3.7.3",
-        "@types/estree": "^1.0.0",
-        "@webassemblyjs/ast": "^1.11.5",
-        "@webassemblyjs/wasm-edit": "^1.11.5",
-        "@webassemblyjs/wasm-parser": "^1.11.5",
+        "@types/estree": "^1.0.5",
+        "@webassemblyjs/ast": "^1.12.1",
+        "@webassemblyjs/wasm-edit": "^1.12.1",
+        "@webassemblyjs/wasm-parser": "^1.12.1",
         "acorn": "^8.7.1",
         "acorn-import-assertions": "^1.9.0",
-        "browserslist": "^4.14.5",
+        "browserslist": "^4.21.10",
         "chrome-trace-event": "^1.0.2",
-        "enhanced-resolve": "^5.15.0",
+        "enhanced-resolve": "^5.16.0",
         "es-module-lexer": "^1.2.1",
         "eslint-scope": "5.1.1",
         "events": "^3.2.0",
         "glob-to-regexp": "^0.4.1",
-        "graceful-fs": "^4.2.9",
+        "graceful-fs": "^4.2.11",
         "json-parse-even-better-errors": "^2.3.1",
         "loader-runner": "^4.2.0",
         "mime-types": "^2.1.27",
         "neo-async": "^2.6.2",
         "schema-utils": "^3.2.0",
         "tapable": "^2.1.1",
-        "terser-webpack-plugin": "^5.3.7",
-        "watchpack": "^2.4.0",
+        "terser-webpack-plugin": "^5.3.10",
+        "watchpack": "^2.4.1",
         "webpack-sources": "^3.2.3"
       },
       "dependencies": {
@@ -43877,9 +43691,9 @@
       },
       "dependencies": {
         "webpack-dev-middleware": {
-          "version": "5.3.3",
-          "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz",
-          "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==",
+          "version": "5.3.4",
+          "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz",
+          "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==",
           "dev": true,
           "requires": {
             "colorette": "^2.0.10",
diff --git a/ui/package.json b/ui/package.json
index 34e1b8100d..5b79b8c570 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -53,16 +53,12 @@
     "@ngx-loading-bar/http-client": "6.0.2",
     "@panzoom/panzoom": "^4.5.1",
     "@swimlane/ngx-charts": "^20.4.1",
-    "angular-datatables": "^16.0.1",
     "angular-gridster2": "^16.0.0",
-    "angular2-uuid": "1.1.1",
     "codemirror": "^5.65.11",
     "console-browserify": "^1.2.0",
     "d3-array": "^3.2.4",
     "d3-contour": "^4.0.2",
     "dagre": "0.8.5",
-    "datatables.net": "^1.13.1",
-    "datatables.net-dt": "^1.13.1",
     "date-fns": "^2.30.0",
     "echarts": "^5.4.3",
     "echarts-gl": "^2.0.9",
@@ -143,7 +139,7 @@
     "resize-observer-polyfill": "^1.5.1",
     "to-string-loader": "^1.2.0",
     "typescript": "4.9.3",
-    "webpack": "^5.89.0",
+    "webpack": "^5.91.0",
     "webpack-cli": "^5.1.4",
     "webpack-merge": "^5.8.0"
   },
diff --git a/ui/projects/streampipes/platform-services/src/lib/apis/semantic-types.service.ts b/ui/projects/streampipes/platform-services/src/lib/apis/semantic-types-rest.service.ts
similarity index 97%
rename from ui/projects/streampipes/platform-services/src/lib/apis/semantic-types.service.ts
rename to ui/projects/streampipes/platform-services/src/lib/apis/semantic-types-rest.service.ts
index 0f9c180df9..00b729fa92 100644
--- a/ui/projects/streampipes/platform-services/src/lib/apis/semantic-types.service.ts
+++ b/ui/projects/streampipes/platform-services/src/lib/apis/semantic-types-rest.service.ts
@@ -25,7 +25,7 @@ import { Observable } from 'rxjs';
 @Injectable({
     providedIn: 'root',
 })
-export class SemanticTypesService {
+export class SemanticTypesRestService {
     constructor(
         private http: HttpClient,
         private platformServicesCommons: PlatformServicesCommons,
diff --git a/ui/projects/streampipes/platform-services/src/public-api.ts b/ui/projects/streampipes/platform-services/src/public-api.ts
index d5cb1d61fc..2e44e5cf9a 100644
--- a/ui/projects/streampipes/platform-services/src/public-api.ts
+++ b/ui/projects/streampipes/platform-services/src/public-api.ts
@@ -44,7 +44,7 @@ export * from './lib/apis/pipeline-element-endpoint.service';
 export * from './lib/apis/pipeline-element-template.service';
 export * from './lib/apis/pipeline-monitoring.service';
 export * from './lib/apis/pipeline-template.service';
-export * from './lib/apis/semantic-types.service';
+export * from './lib/apis/semantic-types-rest.service';
 export * from './lib/apis/user.service';
 export * from './lib/apis/user-admin.service';
 export * from './lib/apis/user-group.service';
diff --git a/ui/src/app/add/add.component.html b/ui/src/app/add/add.component.html
index 624b881aea..78d0dcac10 100644
--- a/ui/src/app/add/add.component.html
+++ b/ui/src/app/add/add.component.html
@@ -131,14 +131,6 @@
                 <mat-icon>refresh</mat-icon>
             </button>
         </div>
-        <button
-            mat-icon-button
-            color="accent"
-            (click)="showManageRdfEndpointsDialog()"
-            matTooltip="Manage Endpoints"
-        >
-            <i class="material-icons">settings</i>
-        </button>
     </div>
     <div fxLayout="column" fxFlex="100">
         <div
diff --git a/ui/src/app/add/add.component.ts b/ui/src/app/add/add.component.ts
index 82e3f1f8de..f5bcffad7a 100644
--- a/ui/src/app/add/add.component.ts
+++ b/ui/src/app/add/add.component.ts
@@ -24,7 +24,6 @@ import {
     PanelType,
     SpBreadcrumbService,
 } from '@streampipes/shared-ui';
-import { AddEndpointComponent } from './dialogs/add-endpoint/add-endpoint.component';
 import { EndpointInstallationComponent } from './dialogs/endpoint-installation/endpoint-installation.component';
 import { ExtensionsServiceEndpointItem } from '@streampipes/platform-services';
 import { Router } from '@angular/router';
@@ -45,7 +44,6 @@ export class AddComponent implements OnInit {
     selectedTab: string;
     availableTypes: string[] = ['all', 'set', 'stream', 'sepa', 'action'];
 
-    selectedCategoryIndex = 0;
     selectedCategory = 'all';
 
     selectedEndpointItems: any[] = [];
@@ -92,12 +90,6 @@ export class AddComponent implements OnInit {
         }
     }
 
-    setSelectedTab(index: number) {
-        this.selectedEndpointItems = [];
-        this.selectAll(false);
-        this.selectedTab = this.availableTypes[index];
-    }
-
     isSelected(endpointItem) {
         return endpointItem.selected;
     }
@@ -124,21 +116,6 @@ export class AddComponent implements OnInit {
         this.changeDetectorRef.detectChanges();
     }
 
-    showManageRdfEndpointsDialog() {
-        const dialogRef: DialogRef<AddEndpointComponent> =
-            this.dialogService.open(AddEndpointComponent, {
-                panelType: PanelType.STANDARD_PANEL,
-                title: 'Manage Endpoints',
-                width: '70vw',
-                data: {},
-            });
-        dialogRef.afterClosed().subscribe(data => {
-            if (data) {
-                this.getEndpointItems();
-            }
-        });
-    }
-
     getEndpointItems() {
         this.endpointItemsLoadingComplete = false;
         this.addService.getRdfEndpointItems().subscribe(endpointItems => {
@@ -211,9 +188,4 @@ export class AddComponent implements OnInit {
     get selectedInstallationStatus(): string {
         return this._selectedInstallationStatus;
     }
-
-    navigateTo(routeId: string): void {
-        this.router.navigate(['add', routeId]);
-        this.activeLink = routeId;
-    }
 }
diff --git a/ui/src/app/add/add.module.ts b/ui/src/app/add/add.module.ts
index edcc92a1f4..baef466d46 100644
--- a/ui/src/app/add/add.module.ts
+++ b/ui/src/app/add/add.module.ts
@@ -28,7 +28,6 @@ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
 import { PipelineElementTypeFilter } from './filter/pipeline-element-type.pipe';
 import { EndpointItemComponent } from './components/endpoint-item/endpoint-item.component';
 import { AddService } from './services/add.service';
-import { AddEndpointComponent } from './dialogs/add-endpoint/add-endpoint.component';
 import { OrderByPipe } from './filter/order-by.pipe';
 import { EndpointInstallationComponent } from './dialogs/endpoint-installation/endpoint-installation.component';
 import { PipelineElementNameFilter } from './filter/pipeline-element-name.pipe';
@@ -60,7 +59,6 @@ import { SharedUiModule } from '../../../projects/streampipes/shared-ui/src/lib/
     ],
     declarations: [
         AddComponent,
-        AddEndpointComponent,
         EndpointInstallationComponent,
         EndpointItemComponent,
         OrderByPipe,
diff --git a/ui/src/app/add/dialogs/add-endpoint/add-endpoint.component.html b/ui/src/app/add/dialogs/add-endpoint/add-endpoint.component.html
deleted file mode 100644
index a67ac94208..0000000000
--- a/ui/src/app/add/dialogs/add-endpoint/add-endpoint.component.html
+++ /dev/null
@@ -1,111 +0,0 @@
-<!--
-  ~ Licensed to the Apache Software Foundation (ASF) under one or more
-  ~ contributor license agreements.  See the NOTICE file distributed with
-  ~ this work for additional information regarding copyright ownership.
-  ~ The ASF licenses this file to You under the Apache License, Version 2.0
-  ~ (the "License"); you may not use this file except in compliance with
-  ~ the License.  You may obtain a copy of the License at
-  ~
-  ~    http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  ~
-  -->
-
-<div class="sp-dialog-container">
-    <div class="sp-dialog-content p-15">
-        <h5><b>Existing Endpoints</b></h5>
-        <div>
-            <div
-                *ngFor="
-                    let rdfEndpoint of rdfEndpoints
-                        | orderBy: 'asc' : 'endpointUrl'
-                "
-            >
-                <div
-                    layout="row"
-                    class="md-with-secondary"
-                    *ngIf="rdfEndpoint._id !== undefined"
-                >
-                    <div
-                        class="md-list-item-text"
-                        fxFlex="80"
-                        fxLayout="column"
-                    >
-                        {{ rdfEndpoint.endpointUrl }}
-                    </div>
-                    <div
-                        class="md-list-item-text"
-                        fxFlex="20"
-                        fxLayout="column"
-                    >
-                        <button
-                            mat-button
-                            mat-flat-button
-                            (click)="removeRdfEndpoint(rdfEndpoint._id)"
-                        >
-                            <mat-icon color="accent">delete</mat-icon>
-                        </button>
-                    </div>
-                </div>
-            </div>
-            <mat-divider></mat-divider>
-            <div *ngIf="addSelected">
-                <div fxLayout="row" class="md-with-secondary">
-                    <div
-                        class="md-list-item-text"
-                        fxFlex="80"
-                        fxLayout="column"
-                    >
-                        <mat-form-field>
-                            <mat-label>Endpoint URL</mat-label>
-                            <input
-                                matInput
-                                type="text"
-                                [(ngModel)]="newEndpoint.endpointUrl"
-                            />
-                        </mat-form-field>
-                    </div>
-                    <div
-                        class="md-list-item-text"
-                        fxFlex="20"
-                        fxlayout="column"
-                    >
-                        <button
-                            mat-button
-                            mat-flat-button
-                            (click)="addRdfEndpoint(newEndpoint)"
-                        >
-                            <mat-icon>save</mat-icon>
-                        </button>
-                    </div>
-                </div>
-            </div>
-        </div>
-        <div style="margin-top: 10px">
-            <button
-                mat-button
-                mat-raised-button
-                color="accent"
-                (click)="showAddInput()"
-            >
-                Add Endpoint
-            </button>
-        </div>
-    </div>
-    <mat-divider></mat-divider>
-    <div class="sp-dialog-actions actions-align-right">
-        <button
-            mat-button
-            mat-raised-button
-            class="mat-basic"
-            (click)="close()"
-        >
-            Close
-        </button>
-    </div>
-</div>
diff --git a/ui/src/app/add/dialogs/add-endpoint/add-endpoint.component.scss b/ui/src/app/add/dialogs/add-endpoint/add-endpoint.component.scss
deleted file mode 100644
index fddade7bf6..0000000000
--- a/ui/src/app/add/dialogs/add-endpoint/add-endpoint.component.scss
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-@import '../../../../scss/sp/sp-dialog.scss';
diff --git a/ui/src/app/add/dialogs/add-endpoint/add-endpoint.component.ts b/ui/src/app/add/dialogs/add-endpoint/add-endpoint.component.ts
deleted file mode 100644
index d8d52bbd0e..0000000000
--- a/ui/src/app/add/dialogs/add-endpoint/add-endpoint.component.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-import { Component, OnInit } from '@angular/core';
-import { AddService } from '../../services/add.service';
-import { DialogRef } from '@streampipes/shared-ui';
-
-@Component({
-    selector: 'sp-add-endpoint-dialog',
-    templateUrl: './add-endpoint.component.html',
-    styleUrls: ['./add-endpoint.component.scss'],
-})
-export class AddEndpointComponent implements OnInit {
-    rdfEndpoints: any;
-    addSelected: any;
-    newEndpoint: any;
-
-    endpointsChanged = false;
-
-    constructor(
-        private addService: AddService,
-        private dialogRef: DialogRef<AddEndpointComponent>,
-    ) {
-        this.rdfEndpoints = [];
-        this.addSelected = false;
-        this.newEndpoint = {};
-    }
-
-    ngOnInit() {
-        this.loadRdfEndpoints();
-    }
-
-    showAddInput() {
-        this.addSelected = true;
-    }
-
-    loadRdfEndpoints() {
-        this.addService.getRdfEndpoints().subscribe(rdfEndpoints => {
-            this.rdfEndpoints = rdfEndpoints;
-        });
-    }
-
-    addRdfEndpoint(rdfEndpoint) {
-        console.log(rdfEndpoint);
-        this.addService.addRdfEndpoint(rdfEndpoint).subscribe(() => {
-            this.loadRdfEndpoints();
-            this.endpointsChanged = true;
-        });
-    }
-
-    removeRdfEndpoint(rdfEndpointId) {
-        this.addService.removeRdfEndpoint(rdfEndpointId).subscribe(() => {
-            this.loadRdfEndpoints();
-            this.endpointsChanged = true;
-        });
-    }
-
-    close() {
-        this.dialogRef.close(this.endpointsChanged);
-    }
-}
diff --git a/ui/src/app/add/services/add.service.ts b/ui/src/app/add/services/add.service.ts
index 225db527ed..f49b7c259e 100644
--- a/ui/src/app/add/services/add.service.ts
+++ b/ui/src/app/add/services/add.service.ts
@@ -32,12 +32,6 @@ export class AddService {
         private platformServicesCommons: PlatformServicesCommons,
     ) {}
 
-    getRdfEndpoints(): Observable<any> {
-        return this.http.get(
-            this.platformServicesCommons.apiBasePath + '/rdfendpoints',
-        );
-    }
-
     getRdfEndpointItems(): Observable<ExtensionsServiceEndpointItem[]> {
         return this.http
             .get(
@@ -53,21 +47,6 @@ export class AddService {
             );
     }
 
-    addRdfEndpoint(rdfEndpoint): Observable<any> {
-        return this.http.post(
-            this.platformServicesCommons.apiBasePath + '/rdfendpoints',
-            rdfEndpoint,
-        );
-    }
-
-    removeRdfEndpoint(rdfEndpointId): Observable<any> {
-        return this.http.delete(
-            this.platformServicesCommons.apiBasePath +
-                '/rdfendpoints/' +
-                rdfEndpointId,
-        );
-    }
-
     getRdfEndpointIcon(item: ExtensionsServiceEndpointItem): Observable<any> {
         return this.http.post(
             this.platformServicesCommons.apiBasePath +
diff --git a/ui/src/app/app-asset-monitoring/components/create-asset/create-asset.component.ts b/ui/src/app/app-asset-monitoring/components/create-asset/create-asset.component.ts
index a7e8f6ca8a..994318a82c 100644
--- a/ui/src/app/app-asset-monitoring/components/create-asset/create-asset.component.ts
+++ b/ui/src/app/app-asset-monitoring/components/create-asset/create-asset.component.ts
@@ -28,12 +28,12 @@ import Konva from 'konva';
 import { AddPipelineDialogComponent } from '../../dialog/add-pipeline/add-pipeline-dialog.component';
 import { MatDialog } from '@angular/material/dialog';
 import { ShapeService } from '../../services/shape.service';
-import { SelectedVisualizationData } from '../../model/selected-visualization-data.model';
 import { SaveDashboardDialogComponent } from '../../dialog/save-dashboard/save-dashboard-dialog.component';
 import { PanelType, DialogService } from '@streampipes/shared-ui';
 import { DashboardConfiguration } from '../../model/dashboard-configuration.model';
 import { RestService } from '../../services/rest.service';
 import { AddLinkDialogComponent } from '../../dialog/add-link/add-link-dialog.component';
+import { IdGeneratorService } from '../../../core-services/id-generator/id-generator.service';
 
 interface Window {
     Image: any;
@@ -57,7 +57,6 @@ export class CreateAssetComponent implements AfterViewInit {
     currentlySelectedShape: any;
 
     IMAGE_ID = 'main-image';
-    selectedVisualizationData: SelectedVisualizationData;
 
     backgroundImagePresent = false;
     measurementPresent = false;
@@ -75,6 +74,7 @@ export class CreateAssetComponent implements AfterViewInit {
         public shapeService: ShapeService,
         private dialogService: DialogService,
         private restService: RestService,
+        private idGeneratorService: IdGeneratorService,
     ) {}
 
     ngAfterViewInit() {
@@ -100,7 +100,7 @@ export class CreateAssetComponent implements AfterViewInit {
             this.mainLayer = this.mainCanvasStage.children[1];
             const groups = this.mainLayer.getChildren().find('Group');
             groups.forEach(g => {
-                const id = this.makeId();
+                const id = this.idGeneratorService.generate(6);
                 g.id(id);
                 g.setDraggable(true);
                 this.addTransformerToShape(id, g);
@@ -300,7 +300,7 @@ export class CreateAssetComponent implements AfterViewInit {
     }
 
     addNewVisulizationItem(visGroup) {
-        const id = this.makeId();
+        const id = this.idGeneratorService.generate(6);
         visGroup.id(id);
         this.mainLayer.add(visGroup);
         this.addTransformerToShape(id, visGroup);
@@ -326,20 +326,6 @@ export class CreateAssetComponent implements AfterViewInit {
         });
     }
 
-    makeId() {
-        let text = '';
-        const possible =
-            'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
-
-        for (let i = 0; i < 6; i++) {
-            text += possible.charAt(
-                Math.floor(Math.random() * possible.length),
-            );
-        }
-
-        return text;
-    }
-
     showImage() {
         const image = new window.Image();
         image.src = this.restService.getImageUrl(
diff --git a/ui/src/app/assets/components/asset-overview/asset-overview.component.ts b/ui/src/app/assets/components/asset-overview/asset-overview.component.ts
index 31c8ddf0ba..3b9e688b76 100644
--- a/ui/src/app/assets/components/asset-overview/asset-overview.component.ts
+++ b/ui/src/app/assets/components/asset-overview/asset-overview.component.ts
@@ -35,6 +35,7 @@ import { SpCreateAssetDialogComponent } from '../../dialog/create-asset/create-a
 import { DataExportService } from '../../../configuration/export/data-export.service';
 import { mergeMap } from 'rxjs/operators';
 import { saveAs } from 'file-saver';
+import { IdGeneratorService } from '../../../core-services/id-generator/id-generator.service';
 
 @Component({
     selector: 'sp-asset-overview-component',
@@ -54,6 +55,7 @@ export class SpAssetOverviewComponent implements OnInit {
         private dialogService: DialogService,
         private router: Router,
         private dataExportService: DataExportService,
+        private idGeneratorService: IdGeneratorService,
     ) {}
 
     ngOnInit(): void {
@@ -80,8 +82,8 @@ export class SpAssetOverviewComponent implements OnInit {
                 assetName: 'New Asset',
                 assetDescription: '',
                 assetLinks: [],
-                assetId: this.generateId(6),
-                _id: this.generateId(24),
+                assetId: this.idGeneratorService.generate(6),
+                _id: this.idGeneratorService.generate(24),
                 appDocType: 'asset-management',
                 removable: true,
                 _rev: undefined,
@@ -107,15 +109,6 @@ export class SpAssetOverviewComponent implements OnInit {
         });
     }
 
-    private generateId(length): string {
-        const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
-        let result = '';
-        for (let i = length; i > 0; --i) {
-            result += chars[Math.round(Math.random() * (chars.length - 1))];
-        }
-        return result;
-    }
-
     uploadAsset() {
         const dialogRef = this.dialogService.open(AssetUploadDialogComponent, {
             panelType: PanelType.SLIDE_IN_PANEL,
diff --git a/ui/src/app/configuration/extensions-service-management/extensions-service-configuration/service-configs/service-configs.component.html b/ui/src/app/configuration/extensions-service-management/extensions-service-configuration/service-configs/service-configs.component.html
index c379b1bd2a..589b5e5d8d 100644
--- a/ui/src/app/configuration/extensions-service-management/extensions-service-configuration/service-configs/service-configs.component.html
+++ b/ui/src/app/configuration/extensions-service-management/extensions-service-configuration/service-configs/service-configs.component.html
@@ -37,7 +37,7 @@
             <sp-service-configs-text
                 fxFlex="100"
                 *ngIf="
-                    configuration.valueType === service.XS_STRING &&
+                    configuration.valueType === semanticTypeService.XS_STRING &&
                     !configuration.isPassword
                 "
                 [configuration]="configuration"
@@ -47,8 +47,9 @@
             <sp-service-configs-number
                 fxFlex="100"
                 *ngIf="
-                    configuration.valueType === service.XS_INTEGER ||
-                    configuration.valueType === service.XS_DOUBLE
+                    configuration.valueType ===
+                        semanticTypeService.XS_INTEGER ||
+                    configuration.valueType === semanticTypeService.XS_DOUBLE
                 "
                 [configuration]="configuration"
             >
@@ -56,7 +57,9 @@
 
             <sp-service-configs-boolean
                 fxFlex="100"
-                *ngIf="configuration.valueType === service.XS_BOOLEAN"
+                *ngIf="
+                    configuration.valueType === semanticTypeService.XS_BOOLEAN
+                "
                 [configuration]="configuration"
             >
             </sp-service-configs-boolean>
diff --git a/ui/src/app/configuration/extensions-service-management/extensions-service-configuration/service-configs/service-configs.component.ts b/ui/src/app/configuration/extensions-service-management/extensions-service-configuration/service-configs/service-configs.component.ts
index 0de61e1af8..eb912a4147 100644
--- a/ui/src/app/configuration/extensions-service-management/extensions-service-configuration/service-configs/service-configs.component.ts
+++ b/ui/src/app/configuration/extensions-service-management/extensions-service-configuration/service-configs/service-configs.component.ts
@@ -17,20 +17,18 @@
  */
 
 import { Component, EventEmitter, Input, Output } from '@angular/core';
-import { XsService } from '../../../../NS/xs.service';
 import { SpServiceConfiguration } from '@streampipes/platform-services';
 
 @Component({
     selector: 'sp-service-configs',
     templateUrl: './service-configs.component.html',
-    providers: [XsService],
 })
 export class ServiceConfigsComponent {
     @Input() serviceConfiguration: SpServiceConfiguration;
     @Output() updateServiceConfiguration: EventEmitter<SpServiceConfiguration> =
         new EventEmitter<SpServiceConfiguration>();
 
-    constructor(private service: XsService) {}
+    constructor() {}
 
     updateConfiguration(): void {
         this.updateServiceConfiguration.emit(this.serviceConfiguration);
diff --git a/ui/src/app/connect/components/adapter-configuration/schema-editor/event-property-row/event-property-row.component.ts b/ui/src/app/connect/components/adapter-configuration/schema-editor/event-property-row/event-property-row.component.ts
index 9846cf2d0b..316af7e25c 100644
--- a/ui/src/app/connect/components/adapter-configuration/schema-editor/event-property-row/event-property-row.component.ts
+++ b/ui/src/app/connect/components/adapter-configuration/schema-editor/event-property-row/event-property-row.component.ts
@@ -17,7 +17,6 @@
  */
 
 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
-import { UUID } from 'angular2-uuid';
 import { TreeNode } from '@ali-hm/angular-tree-component';
 import {
     EventProperty,
@@ -27,13 +26,14 @@ import {
     EventPropertyUnion,
     EventSchema,
     FieldStatusInfo,
-    TransformationRuleDescription,
 } from '@streampipes/platform-services';
 import { EditEventPropertyComponent } from '../../../../dialog/edit-event-property/edit-event-property.component';
 import { DialogService, PanelType } from '@streampipes/shared-ui';
 import { StaticValueTransformService } from '../../../../services/static-value-transform.service';
 import { EventPropertyUtilsService } from '../../../../services/event-property-utils.service';
 import { ShepherdService } from '../../../../../services/tour/shepherd.service';
+import { IdGeneratorService } from '../../../../../core-services/id-generator/id-generator.service';
+import { SemanticTypeService } from '../../../../../core-services/types/semantic-type.service';
 
 @Component({
     selector: 'sp-event-property-row',
@@ -74,6 +74,8 @@ export class EventPropertyRowComponent implements OnInit {
         private dialogService: DialogService,
         private epUtils: EventPropertyUtilsService,
         private shepherdService: ShepherdService,
+        private idGeneratorService: IdGeneratorService,
+        private semanticTypeService: SemanticTypeService,
     ) {}
 
     ngOnInit() {
@@ -160,10 +162,10 @@ export class EventPropertyRowComponent implements OnInit {
         if (
             node.domainProperties &&
             node.domainProperties.some(
-                dp => dp === 'http://schema.org/DateTime',
+                dp => dp === this.semanticTypeService.TIMESTAMP,
             )
         ) {
-            node.runtimeType = 'http://www.w3.org/2001/XMLSchema#long';
+            node.runtimeType = this.semanticTypeService.XS_LONG;
             return true;
         } else {
             return false;
@@ -251,7 +253,7 @@ export class EventPropertyRowComponent implements OnInit {
     }
 
     public addNestedProperty(eventProperty: EventPropertyNested): void {
-        const uuid: string = UUID.UUID();
+        const uuid: string = this.idGeneratorService.generate(25);
         if (!eventProperty.eventProperties) {
             eventProperty.eventProperties = new Array<EventPropertyUnion>();
         }
diff --git a/ui/src/app/connect/components/adapter-configuration/schema-editor/event-schema/event-schema.component.ts b/ui/src/app/connect/components/adapter-configuration/schema-editor/event-schema/event-schema.component.ts
index c693c77fc2..8dfcb80598 100644
--- a/ui/src/app/connect/components/adapter-configuration/schema-editor/event-schema/event-schema.component.ts
+++ b/ui/src/app/connect/components/adapter-configuration/schema-editor/event-schema/event-schema.component.ts
@@ -27,11 +27,9 @@ import {
 } from '@angular/core';
 import { RestService } from '../../../../services/rest.service';
 import { ITreeOptions, TreeComponent } from '@ali-hm/angular-tree-component';
-import { UUID } from 'angular2-uuid';
 import { DataTypesService } from '../../../../services/data-type.service';
 import {
     AdapterDescription,
-    CorrectionValueTransformationRuleDescription,
     EventPropertyNested,
     EventPropertyPrimitive,
     EventPropertyUnion,
@@ -44,7 +42,8 @@ import { MatStepper } from '@angular/material/stepper';
 import { UserErrorMessage } from '../../../../../core-model/base/UserErrorMessage';
 import { TransformationRuleService } from '../../../../services/transformation-rule.service';
 import { StaticValueTransformService } from '../../../../services/static-value-transform.service';
-import { EventPropertyUtilsService } from '../../../../services/event-property-utils.service';
+import { IdGeneratorService } from '../../../../../core-services/id-generator/id-generator.service';
+import { SemanticTypeService } from '../../../../../core-services/types/semantic-type.service';
 
 @Component({
     selector: 'sp-event-schema',
@@ -57,7 +56,8 @@ export class EventSchemaComponent implements OnChanges {
         private dataTypesService: DataTypesService,
         private transformationRuleService: TransformationRuleService,
         private staticValueTransformService: StaticValueTransformService,
-        private epUtilsService: EventPropertyUtilsService,
+        private idGeneratorService: IdGeneratorService,
+        private semanticTypeService: SemanticTypeService,
     ) {}
 
     @Input()
@@ -189,7 +189,7 @@ export class EventSchemaComponent implements OnChanges {
     }
 
     public addNestedProperty(eventProperty?: EventPropertyNested): void {
-        const uuid: string = UUID.UUID();
+        const uuid: string = this.idGeneratorService.generate(25);
         const nested: EventPropertyNested = new EventPropertyNested();
         nested['@class'] =
             'org.apache.streampipes.model.schema.EventPropertyNested';
@@ -244,14 +244,15 @@ export class EventSchemaComponent implements OnChanges {
         eventProperty['@class'] =
             'org.apache.streampipes.model.schema.EventPropertyPrimitive';
         eventProperty.elementId =
-            'http://eventProperty.de/timestamp/' + UUID.UUID();
+            'http://eventProperty.de/timestamp/' +
+            this.idGeneratorService.generate(25);
 
         eventProperty.runtimeName = 'timestamp';
         eventProperty.label = 'Timestamp';
         eventProperty.description = 'The current timestamp value';
-        eventProperty.domainProperties = ['http://schema.org/DateTime'];
+        eventProperty.domainProperties = [this.semanticTypeService.TIMESTAMP];
         eventProperty.propertyScope = 'HEADER_PROPERTY';
-        eventProperty.runtimeType = 'http://www.w3.org/2001/XMLSchema#long';
+        eventProperty.runtimeType = this.semanticTypeService.XS_LONG;
         eventProperty.additionalMetadata = {};
 
         this.targetSchema.eventProperties.push(eventProperty);
diff --git a/ui/src/app/connect/connect.module.ts b/ui/src/app/connect/connect.module.ts
index 828f03cfa9..45a0234069 100644
--- a/ui/src/app/connect/connect.module.ts
+++ b/ui/src/app/connect/connect.module.ts
@@ -45,7 +45,6 @@ import { TimestampPipe } from './filter/timestamp.pipe';
 import { MatChipsModule } from '@angular/material/chips';
 import { MatSliderModule } from '@angular/material/slider';
 import { TreeModule } from '@ali-hm/angular-tree-component';
-import { XsService } from '../NS/xs.service';
 import { EditDataTypeComponent } from './dialog/edit-event-property/components/edit-schema-transformation/edit-data-type/edit-data-type.component';
 import { EditTimestampPropertyComponent } from './dialog/edit-event-property/components/edit-value-transformation/edit-timestamp-property/edit-timestamp-property.component';
 import { EditUnitTransformationComponent } from './dialog/edit-event-property/components/edit-unit-transformation/edit-unit-transformation.component';
@@ -198,7 +197,6 @@ import { MatDividerModule } from '@angular/material/divider';
         StaticPropertyUtilService,
         UnitProviderService,
         TimestampPipe,
-        XsService,
     ],
     schemas: [CUSTOM_ELEMENTS_SCHEMA],
 })
diff --git a/ui/src/app/connect/dialog/edit-event-property/components/edit-schema-transformation/edit-data-type/edit-data-type.component.ts b/ui/src/app/connect/dialog/edit-event-property/components/edit-schema-transformation/edit-data-type/edit-data-type.component.ts
index 8343d260f3..9bb08cfbe7 100644
--- a/ui/src/app/connect/dialog/edit-event-property/components/edit-schema-transformation/edit-data-type/edit-data-type.component.ts
+++ b/ui/src/app/connect/dialog/edit-event-property/components/edit-schema-transformation/edit-data-type/edit-data-type.component.ts
@@ -32,7 +32,7 @@ export class EditDataTypeComponent implements OnInit {
     constructor(private dataTypeService: DataTypesService) {}
 
     ngOnInit() {
-        this.runtimeDataTypes = this.dataTypeService.getDataTypes();
+        this.runtimeDataTypes = this.dataTypeService.dataTypes;
     }
 
     valueChanged() {
diff --git a/ui/src/app/connect/dialog/edit-event-property/components/edit-schema-transformation/edit-schema-transformation.component.ts b/ui/src/app/connect/dialog/edit-event-property/components/edit-schema-transformation/edit-schema-transformation.component.ts
index f65faa1c4f..f87d518b0b 100644
--- a/ui/src/app/connect/dialog/edit-event-property/components/edit-schema-transformation/edit-schema-transformation.component.ts
+++ b/ui/src/app/connect/dialog/edit-event-property/components/edit-schema-transformation/edit-schema-transformation.component.ts
@@ -17,10 +17,6 @@
  */
 
 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
-import {
-    EventPropertyUnion,
-    SemanticTypesService,
-} from '@streampipes/platform-services';
 import {
     debounceTime,
     distinctUntilChanged,
@@ -30,6 +26,8 @@ import {
 import { UntypedFormControl } from '@angular/forms';
 import { Observable } from 'rxjs';
 import { ShepherdService } from '../../../../../services/tour/shepherd.service';
+import { SemanticTypesRestService } from '../../../../../../../projects/streampipes/platform-services/src/lib/apis/semantic-types-rest.service';
+import { SemanticTypeService } from '../../../../../core-services/types/semantic-type.service';
 
 @Component({
     selector: 'sp-edit-schema-transformation',
@@ -37,8 +35,6 @@ import { ShepherdService } from '../../../../../services/tour/shepherd.service';
     styleUrls: ['./edit-schema-transformation.component.scss'],
 })
 export class EditSchemaTransformationComponent implements OnInit {
-    soTimestamp = 'http://schema.org/DateTime';
-
     @Input()
     cachedProperty: any;
 
@@ -54,7 +50,8 @@ export class EditSchemaTransformationComponent implements OnInit {
     semanticTypes: Observable<string[]>;
 
     constructor(
-        private semanticTypesService: SemanticTypesService,
+        private semanticTypesRestService: SemanticTypesRestService,
+        private semanticTypeService: SemanticTypeService,
         private shepherdService: ShepherdService,
     ) {}
 
@@ -65,7 +62,7 @@ export class EditSchemaTransformationComponent implements OnInit {
             distinctUntilChanged(),
             switchMap(val => {
                 return val
-                    ? this.semanticTypesService.getSemanticTypes(val)
+                    ? this.semanticTypesRestService.getSemanticTypes(val)
                     : [];
             }),
         );
@@ -74,10 +71,11 @@ export class EditSchemaTransformationComponent implements OnInit {
     editTimestampDomainProperty(checked: boolean) {
         if (checked) {
             this.isTimestampProperty = true;
-            this.cachedProperty.domainProperties = [this.soTimestamp];
+            this.cachedProperty.domainProperties = [
+                this.semanticTypeService.TIMESTAMP,
+            ];
             this.cachedProperty.propertyScope = 'HEADER_PROPERTY';
-            this.cachedProperty.runtimeType =
-                'http://www.w3.org/2001/XMLSchema#long';
+            this.cachedProperty.runtimeType = this.semanticTypeService.XS_LONG;
         } else {
             this.cachedProperty.domainProperties = [];
             this.cachedProperty.propertyScope = 'MEASUREMENT_PROPERTY';
diff --git a/ui/src/app/connect/dialog/edit-event-property/edit-event-property.component.ts b/ui/src/app/connect/dialog/edit-event-property/edit-event-property.component.ts
index fd89934f53..6f05628a27 100644
--- a/ui/src/app/connect/dialog/edit-event-property/edit-event-property.component.ts
+++ b/ui/src/app/connect/dialog/edit-event-property/edit-event-property.component.ts
@@ -35,13 +35,13 @@ import {
     EventPropertyPrimitive,
     EventPropertyUnion,
 } from '@streampipes/platform-services';
-import { SemanticTypeUtilsService } from '../../../core-services/semantic-type/semantic-type-utils.service';
 import { DataTypesService } from '../../services/data-type.service';
 import { DialogRef } from '@streampipes/shared-ui';
 import { EditSchemaTransformationComponent } from './components/edit-schema-transformation/edit-schema-transformation.component';
 import { EditValueTransformationComponent } from './components/edit-value-transformation/edit-value-transformation.component';
 import { EditUnitTransformationComponent } from './components/edit-unit-transformation/edit-unit-transformation.component';
 import { ShepherdService } from '../../../services/tour/shepherd.service';
+import { SemanticTypeService } from '../../../core-services/types/semantic-type.service';
 
 @Component({
     selector: 'sp-edit-event-property',
@@ -76,7 +76,7 @@ export class EditEventPropertyComponent implements OnInit {
         public dialogRef: DialogRef<EditEventPropertyComponent>,
         private formBuilder: UntypedFormBuilder,
         private dataTypeService: DataTypesService,
-        private semanticTypeUtilsService: SemanticTypeUtilsService,
+        private semanticTypeUtilsService: SemanticTypeService,
         private shepherdService: ShepherdService,
     ) {}
 
@@ -91,7 +91,7 @@ export class EditEventPropertyComponent implements OnInit {
         this.isEventPropertyNested =
             this.property instanceof EventPropertyNested;
         this.isNumericProperty =
-            this.semanticTypeUtilsService.isNumeric(this.cachedProperty) ||
+            this.semanticTypeUtilsService.isNumber(this.cachedProperty) ||
             this.dataTypeService.isNumeric(
                 (this.cachedProperty as any).runtimeType,
             );
diff --git a/ui/src/app/connect/filter/timestamp.pipe.ts b/ui/src/app/connect/filter/timestamp.pipe.ts
index fd729a384b..901c421c54 100644
--- a/ui/src/app/connect/filter/timestamp.pipe.ts
+++ b/ui/src/app/connect/filter/timestamp.pipe.ts
@@ -18,16 +18,19 @@
 
 import { Pipe, PipeTransform } from '@angular/core';
 import { EventPropertyUnion } from '@streampipes/platform-services';
+import { SemanticTypeService } from '../../core-services/types/semantic-type.service';
 
 @Pipe({
     name: 'timestampFilter',
     pure: false,
 })
 export class TimestampPipe implements PipeTransform {
+    constructor(private semanticTypeService: SemanticTypeService) {}
+
     transform(items: EventPropertyUnion[]): EventPropertyUnion[] {
         return items.filter(item =>
             item.domainProperties.some(
-                dp => dp === 'http://schema.org/DateTime',
+                dp => dp === this.semanticTypeService.TIMESTAMP,
             ),
         );
     }
diff --git a/ui/src/app/connect/services/data-type.service.ts b/ui/src/app/connect/services/data-type.service.ts
index 28b6335b8c..0d9036cadc 100644
--- a/ui/src/app/connect/services/data-type.service.ts
+++ b/ui/src/app/connect/services/data-type.service.ts
@@ -20,7 +20,7 @@ import { Injectable } from '@angular/core';
 
 @Injectable()
 export class DataTypesService {
-    private dataTypes: { label: string; url: string }[] = [
+    public dataTypes: { label: string; url: string }[] = [
         {
             label: "String - A textual datatype, e.g., 'machine1'",
             url: 'http://www.w3.org/2001/XMLSchema#string',
@@ -49,35 +49,10 @@ export class DataTypesService {
 
     constructor() {}
 
-    getLabel(url: string): string {
-        for (const dataType of this.dataTypes) {
-            if (dataType.url === url) {
-                return dataType.label;
-            }
-        }
-        return 'Invalid data type';
-    }
-
-    getUrl(id: number): string {
-        return this.dataTypes[id].url;
-    }
-
-    getDataTypes() {
-        return this.dataTypes;
-    }
-
-    getNumberTypeUrl(): string {
-        return String(this.dataTypes[2].url);
-    }
-
     getStringTypeUrl(): string {
         return String(this.dataTypes[0].url);
     }
 
-    getBooleanTypeUrl(): string {
-        return String(this.dataTypes[1].url);
-    }
-
     isNumeric(uri: string) {
         const numericDataTypes = [
             'http://www.w3.org/2001/XMLSchema#float',
diff --git a/ui/src/app/connect/services/transformation-rule.service.ts b/ui/src/app/connect/services/transformation-rule.service.ts
index 5dabaf821e..6c5dceab7a 100644
--- a/ui/src/app/connect/services/transformation-rule.service.ts
+++ b/ui/src/app/connect/services/transformation-rule.service.ts
@@ -37,11 +37,13 @@ import {
 } from '@streampipes/platform-services';
 import { TimestampTransformationRuleMode } from '../model/TimestampTransformationRuleMode';
 import { StaticValueTransformService } from './static-value-transform.service';
+import { SemanticTypeService } from '../../core-services/types/semantic-type.service';
 
 @Injectable({ providedIn: 'root' })
 export class TransformationRuleService {
     constructor(
         private staticValueTransformService: StaticValueTransformService,
+        private semanticTypeService: SemanticTypeService,
     ) {}
 
     public getTransformationRuleDescriptions(
@@ -583,7 +585,7 @@ export class TransformationRuleService {
 
     isTimestampProperty(property: EventPropertyPrimitive) {
         return property.domainProperties.some(
-            dp => dp === 'http://schema.org/DateTime',
+            dp => dp === this.semanticTypeService.TIMESTAMP,
         );
     }
 
diff --git a/ui/src/app/core-services/id-generator/id-generator.service.ts b/ui/src/app/core-services/id-generator/id-generator.service.ts
new file mode 100644
index 0000000000..d3d4a0b069
--- /dev/null
+++ b/ui/src/app/core-services/id-generator/id-generator.service.ts
@@ -0,0 +1,49 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+import { Injectable } from '@angular/core';
+
+@Injectable({ providedIn: 'root' })
+export class IdGeneratorService {
+    private possibleCharacters =
+        '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
+
+    private idPrefix = 'urn:streampipes.org:spi:';
+
+    /**
+     * Generates a random id with the given length
+     */
+    public generate(length: number): string {
+        let result = '';
+        for (let i = length; i > 0; --i) {
+            result +=
+                this.possibleCharacters[
+                    Math.round(
+                        Math.random() * (this.possibleCharacters.length - 1),
+                    )
+                ];
+        }
+        return result;
+    }
+
+    /**
+     * Generates a random id with a fix prefix
+     */
+    public generatePrefixedId(): string {
+        return this.idPrefix + this.generate(6);
+    }
+}
diff --git a/ui/src/app/core-services/semantic-type/semantic-type-utils.service.ts b/ui/src/app/core-services/types/semantic-type.service.ts
similarity index 55%
rename from ui/src/app/core-services/semantic-type/semantic-type-utils.service.ts
rename to ui/src/app/core-services/types/semantic-type.service.ts
index f93d2eeddf..35b0141db9 100644
--- a/ui/src/app/core-services/semantic-type/semantic-type-utils.service.ts
+++ b/ui/src/app/core-services/types/semantic-type.service.ts
@@ -19,15 +19,24 @@
 import { Injectable } from '@angular/core';
 import { EventProperty } from '@streampipes/platform-services';
 
-@Injectable()
-export class SemanticTypeUtilsService {
+@Injectable({ providedIn: 'root' })
+export class SemanticTypeService {
     public TIMESTAMP = 'http://schema.org/DateTime';
     public IMAGE = 'https://image.com';
-    public NUMBER = 'http://schema.org/Number';
+    public SO_NUMBER = 'http://schema.org/Number';
+    public SO_URL = 'https://schema.org/URL';
+
+    public XS_INTEGER = 'http://www.w3.org/2001/XMLSchema#integer';
+    public XS_FLOAT = 'http://www.w3.org/2001/XMLSchema#float';
+    public XS_LONG = 'http://www.w3.org/2001/XMLSchema#long';
+    public XS_DOUBLE = 'http://www.w3.org/2001/XMLSchema#double';
+    public XS_BOOLEAN = 'http://www.w3.org/2001/XMLSchema#boolean';
+    public XS_NUMBER = 'http://www.w3.org/2001/XMLSchema#number';
+    public XS_STRING = 'http://www.w3.org/2001/XMLSchema#string';
 
     constructor() {}
 
-    public getValue(inputValue, semanticType) {
+    public getValue(inputValue: any, semanticType: string) {
         if (semanticType === this.TIMESTAMP) {
             return new Date(inputValue).toLocaleString();
         } else {
@@ -43,11 +52,21 @@ export class SemanticTypeUtilsService {
         return property.domainProperties.includes(this.IMAGE);
     }
 
-    public is(property: EventProperty, uri: string): boolean {
-        return property.domainProperties.includes(uri);
+    public isNumber(property: EventProperty): boolean {
+        return property.domainProperties.includes(this.SO_NUMBER);
+    }
+
+    public isNumberType(datatype: string): boolean {
+        return (
+            datatype === this.XS_DOUBLE ||
+            datatype === this.XS_INTEGER ||
+            datatype === this.XS_LONG ||
+            datatype === this.XS_FLOAT ||
+            datatype === this.XS_NUMBER
+        );
     }
 
-    public isNumeric(property: EventProperty): boolean {
-        return property.domainProperties.includes(this.NUMBER);
+    isBooleanType(datatype: string): boolean {
+        return datatype === this.XS_BOOLEAN;
     }
 }
diff --git a/ui/src/app/core-ui/core-ui.module.ts b/ui/src/app/core-ui/core-ui.module.ts
index 2fb9be2263..718e2347cc 100644
--- a/ui/src/app/core-ui/core-ui.module.ts
+++ b/ui/src/app/core-ui/core-ui.module.ts
@@ -83,6 +83,7 @@ import { MarkdownModule } from 'ngx-markdown';
 import { LivePreviewLoadingComponent } from './pipeline-element-runtime-info/live-preview-loading/live-preview-loading.component';
 import { LivePreviewTableComponent } from './pipeline-element-runtime-info/live-preview-table/live-preview-table.component';
 import { LivePreviewErrorComponent } from './pipeline-element-runtime-info/live-preview-error/live-preview-error.component';
+import { FieldNamesTableComponent } from './help/field-names-table/field-names-table.component';
 
 @NgModule({
     imports: [
@@ -150,6 +151,7 @@ import { LivePreviewErrorComponent } from './pipeline-element-runtime-info/live-
         SpSimpleLogsComponent,
         SpSimpleMetricsComponent,
         StatusWidgetComponent,
+        FieldNamesTableComponent,
         LivePreviewLoadingComponent,
         LivePreviewTableComponent,
         LivePreviewErrorComponent,
diff --git a/ui/src/app/core-ui/help/field-names-table/field-names-table.component.html b/ui/src/app/core-ui/help/field-names-table/field-names-table.component.html
new file mode 100644
index 0000000000..b41f0f8e2c
--- /dev/null
+++ b/ui/src/app/core-ui/help/field-names-table/field-names-table.component.html
@@ -0,0 +1,64 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~    http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  ~
+  -->
+
+<div>
+    <div>
+        <table
+            mat-table
+            [dataSource]="eventSchema.eventProperties"
+            class="mat-mdc-table mdc-data-table__table"
+        >
+            <ng-container matColumnDef="label">
+                <th mat-header-cell *matHeaderCellDef>
+                    <strong>Field Name</strong>
+                </th>
+                <td mat-cell *matCellDef="let property">
+                    {{ property.label ? property.label : '(n/a)' }}
+                </td>
+            </ng-container>
+
+            <ng-container matColumnDef="description">
+                <th mat-header-cell *matHeaderCellDef>
+                    <strong>Description</strong>
+                </th>
+                <td mat-cell *matCellDef="let property">
+                    {{ property.description ? property.description : '(n/a)' }}
+                </td>
+            </ng-container>
+
+            <ng-container matColumnDef="runtimeName">
+                <th mat-header-cell *matHeaderCellDef>
+                    <strong>Runtime Name</strong>
+                </th>
+                <td mat-cell *matCellDef="let property">
+                    {{ property.runtimeName }}
+                </td>
+            </ng-container>
+
+            <ng-container matColumnDef="runtimeType">
+                <th mat-header-cell *matHeaderCellDef><strong>Type</strong></th>
+                <td mat-cell *matCellDef="let property">
+                    {{ getFriendlyRuntimeType(property.runtimeType) }}
+                </td>
+            </ng-container>
+
+            <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
+            <tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
+        </table>
+    </div>
+</div>
diff --git a/ui/projects/streampipes/platform-services/src/lib/contants/platform-services.constants.ts b/ui/src/app/core-ui/help/field-names-table/field-names-table.component.scss
similarity index 94%
rename from ui/projects/streampipes/platform-services/src/lib/contants/platform-services.constants.ts
rename to ui/src/app/core-ui/help/field-names-table/field-names-table.component.scss
index f64a1008e2..13cbc4aacb 100644
--- a/ui/projects/streampipes/platform-services/src/lib/contants/platform-services.constants.ts
+++ b/ui/src/app/core-ui/help/field-names-table/field-names-table.component.scss
@@ -15,5 +15,3 @@
  * limitations under the License.
  *
  */
-
-export class PlatformServicesConstants {}
diff --git a/ui/src/app/core-ui/help/field-names-table/field-names-table.component.ts b/ui/src/app/core-ui/help/field-names-table/field-names-table.component.ts
new file mode 100644
index 0000000000..3330d96a89
--- /dev/null
+++ b/ui/src/app/core-ui/help/field-names-table/field-names-table.component.ts
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import { Component, Input } from '@angular/core';
+import { EventSchema } from '@streampipes/platform-services';
+import { SemanticTypeService } from '../../../core-services/types/semantic-type.service';
+
+@Component({
+    selector: 'sp-field-names-table',
+    templateUrl: './field-names-table.component.html',
+    styleUrls: ['./field-names-table.component.scss'],
+})
+export class FieldNamesTableComponent {
+    @Input()
+    eventSchema: EventSchema;
+
+    displayedColumns: string[] = [
+        'label',
+        'description',
+        'runtimeName',
+        'runtimeType',
+    ];
+
+    constructor(private semanticTypeService: SemanticTypeService) {}
+
+    getFriendlyRuntimeType(runtimeType: string) {
+        if (this.semanticTypeService.isNumberType(runtimeType)) {
+            return 'Number';
+        } else if (this.semanticTypeService.isBooleanType(runtimeType)) {
+            return 'Boolean';
+        } else {
+            return 'Text';
+        }
+    }
+}
diff --git a/ui/src/app/core-ui/help/help.component.html b/ui/src/app/core-ui/help/help.component.html
index b17cd1f4bb..156f892059 100644
--- a/ui/src/app/core-ui/help/help.component.html
+++ b/ui/src/app/core-ui/help/help.component.html
@@ -25,78 +25,30 @@
 
         <mat-tab-group
             color="accent"
-            [selectedIndex]="selectedIndex"
-            (selectedIndexChange)="selectedIndex = $event"
+            [selectedIndex]="selectedTabIndex"
+            (selectedIndexChange)="selectedTabIndex = $event"
         >
-            <mat-tab *ngFor="let tab of tabs" label="{{ tab.title }}">
-            </mat-tab>
+            <mat-tab *ngFor="let tab of tabs" label="{{ tab }}"> </mat-tab>
         </mat-tab-group>
-        <div style="margin-top: 15px">
-            <div *ngIf="selectedIndex === 0 && streamMode">
-                <h5>Field Names</h5>
 
-                <div>
-                    <table class="dataTable row-border hover preview-table">
-                        <thead>
-                            <tr class="preview-row">
-                                <th>Field Name</th>
-                                <th>Description</th>
-                                <th>Runtime Name</th>
-                                <th>Type</th>
-                            </tr>
-                        </thead>
-                        <tbody id="preview-data-rows-id">
-                            <tr
-                                *ngFor="
-                                    let property of pipelineElement.eventSchema
-                                        .eventProperties
-                                "
-                                class="preview-row"
-                            >
-                                <td>
-                                    {{
-                                        property.label
-                                            ? property.label
-                                            : '(n/a)'
-                                    }}
-                                </td>
-                                <td>
-                                    {{
-                                        property.description
-                                            ? property.description
-                                            : '(n/a)'
-                                    }}
-                                </td>
-                                <td>{{ property.runtimeName }}</td>
-                                <td>
-                                    {{
-                                        getFriendlyRuntimeType(
-                                            property.runtimeType
-                                        )
-                                    }}
-                                </td>
-                            </tr>
-                        </tbody>
-                    </table>
-                </div>
-            </div>
-            <div *ngIf="selectedIndex === 1 && streamMode">
-                <div>
-                    <sp-pipeline-element-runtime-info
-                        [streamDescription]="pipelineElement"
-                        [pollingActive]="pollingActive"
-                    ></sp-pipeline-element-runtime-info>
-                </div>
-            </div>
-            <div *ngIf="selectedTab === 2 || !streamMode">
-                <sp-pipeline-element-documentation
-                    [useStyling]="false"
-                    [appId]="pipelineElement.appId"
-                ></sp-pipeline-element-documentation>
-            </div>
-        </div>
+        <sp-field-names-table
+            *ngIf="selectedTabIndex === 0"
+            [eventSchema]="pipelineElement.eventSchema"
+        ></sp-field-names-table>
+        <sp-pipeline-element-runtime-info
+            *ngIf="selectedTabIndex === 1"
+            [streamDescription]="pipelineElement"
+            [pollingActive]="pollingActive"
+        ></sp-pipeline-element-runtime-info>
+        <sp-pipeline-element-documentation
+            *ngIf="selectedTabIndex === 2"
+            [useStyling]="false"
+            [appId]="pipelineElement.appId"
+        ></sp-pipeline-element-documentation>
     </div>
+
     <mat-divider></mat-divider>
+
     <div class="sp-dialog-actions actions-align-right">
         <button
             mat-button
diff --git a/ui/src/app/core-ui/help/help.component.scss b/ui/src/app/core-ui/help/help.component.scss
index c95de1b0e5..ecf2724830 100644
--- a/ui/src/app/core-ui/help/help.component.scss
+++ b/ui/src/app/core-ui/help/help.component.scss
@@ -17,12 +17,3 @@
  */
 
 @import '../../../scss/sp/sp-dialog.scss';
-
-.preview-row,
-.preview-table {
-    background: var(--color-bg-dialog);
-}
-
-.dataTable tbody tr:hover {
-    background: var(--color-bg-1);
-}
diff --git a/ui/src/app/core-ui/help/help.component.ts b/ui/src/app/core-ui/help/help.component.ts
index d6d3cf0b08..59389287f1 100644
--- a/ui/src/app/core-ui/help/help.component.ts
+++ b/ui/src/app/core-ui/help/help.component.ts
@@ -27,32 +27,11 @@ import { PipelineElementUnion } from '../../editor/model/editor.model';
     styleUrls: ['./help.component.scss'],
 })
 export class HelpComponent implements OnInit {
-    selectedTab = 0;
     pollingActive: boolean;
+    selectedTabIndex = 0;
 
-    selectedIndex = 0;
-
-    nsPrefix = 'http://www.w3.org/2001/XMLSchema#';
-    availableTabs = [
-        {
-            title: 'Fields',
-            type: 'fields',
-            targets: ['set', 'stream'],
-        },
-        {
-            title: 'Values',
-            type: 'values',
-            targets: ['set', 'stream'],
-        },
-        {
-            title: 'Documentation',
-            type: 'documentation',
-            targets: ['set', 'stream', 'sepa', 'action'],
-        },
-    ];
-
-    tabs: any[] = [];
-    streamMode: boolean;
+    availableTabs = ['Fields', 'Values', 'Documentation'];
+    tabs: string[] = [];
 
     @Input()
     pipelineElement: PipelineElementUnion;
@@ -64,36 +43,12 @@ export class HelpComponent implements OnInit {
     ngOnInit() {
         if (this.pipelineElement instanceof SpDataStream) {
             this.tabs = this.availableTabs;
-            this.streamMode = true;
         } else {
             this.tabs.push(this.availableTabs[2]);
-            this.streamMode = false;
-        }
-    }
-
-    getFriendlyRuntimeType(runtimeType) {
-        if (this.isNumber(runtimeType)) {
-            return 'Number';
-        } else if (this.isBoolean(runtimeType)) {
-            return 'Boolean';
-        } else {
-            return 'Text';
+            this.selectedTabIndex = 2;
         }
     }
 
-    isNumber(runtimeType) {
-        return (
-            runtimeType === this.nsPrefix + 'float' ||
-            runtimeType === this.nsPrefix + 'integer' ||
-            runtimeType === this.nsPrefix + 'long' ||
-            runtimeType === this.nsPrefix + 'double'
-        );
-    }
-
-    isBoolean(runtimeType) {
-        return runtimeType === this.nsPrefix + 'boolean';
-    }
-
     close() {
         this.pollingActive = false;
         setTimeout(() => {
diff --git a/ui/src/app/core-ui/pipeline-element-runtime-info/live-preview-table/live-preview-table.component.ts b/ui/src/app/core-ui/pipeline-element-runtime-info/live-preview-table/live-preview-table.component.ts
index 9e9a64d2ed..1ae75a0c7a 100644
--- a/ui/src/app/core-ui/pipeline-element-runtime-info/live-preview-table/live-preview-table.component.ts
+++ b/ui/src/app/core-ui/pipeline-element-runtime-info/live-preview-table/live-preview-table.component.ts
@@ -18,7 +18,7 @@
 
 import { Component, Input } from '@angular/core';
 import { EventSchema } from '@streampipes/platform-services';
-import { SemanticTypeUtilsService } from '../../../core-services/semantic-type/semantic-type-utils.service';
+import { SemanticTypeService } from '../../../core-services/types/semantic-type.service';
 
 @Component({
     selector: 'sp-live-preview-table',
@@ -34,7 +34,7 @@ export class LivePreviewTableComponent {
 
     displayedColumns: string[] = ['runtimeName', 'value'];
 
-    constructor(private semanticTypeUtilsService: SemanticTypeUtilsService) {}
+    constructor(private semanticTypeUtilsService: SemanticTypeService) {}
 
     isImage(runtimeName: string) {
         const property = this.getProperty(runtimeName);
diff --git a/ui/src/app/core-ui/static-properties/static-free-input/static-free-input.component.ts b/ui/src/app/core-ui/static-properties/static-free-input/static-free-input.component.ts
index a927281c19..657610b0d3 100644
--- a/ui/src/app/core-ui/static-properties/static-free-input/static-free-input.component.ts
+++ b/ui/src/app/core-ui/static-properties/static-free-input/static-free-input.component.ts
@@ -18,10 +18,8 @@
 
 import { Component, OnInit, ViewChild } from '@angular/core';
 import { ValidatorFn, Validators } from '@angular/forms';
-import { StaticPropertyUtilService } from '../static-property-util.service';
 import { ConfigurationInfo } from '../../../connect/model/ConfigurationInfo';
 import { FreeTextStaticProperty } from '@streampipes/platform-services';
-import { XsService } from '../../../NS/xs.service';
 import {
     ValidateNumber,
     ValidateString,
@@ -29,6 +27,7 @@ import {
 } from '../input.validator';
 import { AbstractValidatedStaticPropertyRenderer } from '../base/abstract-validated-static-property';
 import { QuillEditorComponent } from 'ngx-quill';
+import { SemanticTypeService } from '../../../core-services/types/semantic-type.service';
 
 @Component({
     selector: 'sp-app-static-free-input',
@@ -56,10 +55,7 @@ export class StaticFreeInputComponent
     @ViewChild('textEditor', { static: false })
     quillEditorComponent: QuillEditorComponent;
 
-    constructor(
-        public staticPropertyUtil: StaticPropertyUtilService,
-        private xsService: XsService,
-    ) {
+    constructor(private semanticTypeService: SemanticTypeService) {
         super();
     }
 
@@ -73,18 +69,24 @@ export class StaticFreeInputComponent
         const validators: ValidatorFn[] = [];
         validators.push(Validators.required);
         if (
-            this.xsService.isNumber(this.staticProperty.requiredDatatype) ||
-            this.xsService.isNumber(this.staticProperty.requiredDomainProperty)
+            this.semanticTypeService.isNumberType(
+                this.staticProperty.requiredDatatype,
+            ) ||
+            this.semanticTypeService.isNumberType(
+                this.staticProperty.requiredDomainProperty,
+            )
         ) {
             validators.push(ValidateNumber);
             this.errorMessage = 'The value should be a number';
         } else if (
-            this.staticProperty.requiredDomainProperty === this.xsService.SO_URL
+            this.staticProperty.requiredDomainProperty ===
+            this.semanticTypeService.SO_URL
         ) {
             validators.push(ValidateUrl);
             this.errorMessage = 'Please enter a valid URL';
         } else if (
-            this.staticProperty.requiredDatatype === this.xsService.XS_STRING1
+            this.staticProperty.requiredDatatype ===
+            this.semanticTypeService.XS_STRING
         ) {
             validators.push(ValidateString);
             this.errorMessage = 'Please enter a valid String';
diff --git a/ui/src/app/core-ui/static-properties/static-property-util.service.ts b/ui/src/app/core-ui/static-properties/static-property-util.service.ts
index d93f2e3b32..81b8bfe87f 100644
--- a/ui/src/app/core-ui/static-properties/static-property-util.service.ts
+++ b/ui/src/app/core-ui/static-properties/static-property-util.service.ts
@@ -35,12 +35,15 @@ import {
     StaticPropertyAlternatives,
     StaticPropertyGroup,
 } from '@streampipes/platform-services';
+import { IdGeneratorService } from '../../core-services/id-generator/id-generator.service';
 
 @Injectable()
 export class StaticPropertyUtilService {
+    constructor(private idGeneratorService: IdGeneratorService) {}
+
     public clone(val: StaticProperty) {
         let clone;
-        const id = 'urn:streampipes.org:spi::' + this.generateID(6);
+        const id = this.idGeneratorService.generatePrefixedId();
         if (val instanceof FreeTextStaticProperty) {
             clone = new FreeTextStaticProperty();
             clone.elementId = id;
@@ -142,22 +145,13 @@ export class StaticPropertyUtilService {
     private cloneOption(val: Option) {
         const clone = new Option();
         clone['@class'] = 'org.apache.streampipes.model.staticproperty.Option';
-        clone.elementId = 'urn:streampipes.org:spi::' + this.generateID(6);
+        clone.elementId = this.idGeneratorService.generatePrefixedId();
         clone.name = val.name;
         clone.internalName = val.internalName;
         clone.selected = val.selected;
         return clone;
     }
 
-    private generateID(length): string {
-        const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
-        let result = '';
-        for (let i = length; i > 0; --i) {
-            result += chars[Math.round(Math.random() * (chars.length - 1))];
-        }
-        return result;
-    }
-
     public asFreeTextStaticProperty(
         val: StaticProperty,
     ): FreeTextStaticProperty {
@@ -169,12 +163,4 @@ export class StaticPropertyUtilService {
     ): ColorPickerStaticProperty {
         return val as ColorPickerStaticProperty;
     }
-
-    public asSecretStaticProperty(val: StaticProperty): SecretStaticProperty {
-        return val as SecretStaticProperty;
-    }
-
-    public asCollectionProperty(val: StaticProperty): CollectionStaticProperty {
-        return val as CollectionStaticProperty;
-    }
 }
diff --git a/ui/src/app/core-ui/static-properties/static-property.component.ts b/ui/src/app/core-ui/static-properties/static-property.component.ts
index a62c2f8392..ff579a3888 100644
--- a/ui/src/app/core-ui/static-properties/static-property.component.ts
+++ b/ui/src/app/core-ui/static-properties/static-property.component.ts
@@ -18,7 +18,6 @@
 
 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
 
-import { XsService } from '../../NS/xs.service';
 import { ConfigurationInfo } from '../../connect/model/ConfigurationInfo';
 import {
     AnyStaticProperty,
@@ -47,7 +46,6 @@ import { InvocablePipelineElementUnion } from '../../editor/model/editor.model';
     selector: 'sp-app-static-property',
     templateUrl: './static-property.component.html',
     styleUrls: ['./static-property.component.css'],
-    providers: [XsService],
 })
 export class StaticPropertyComponent implements OnInit {
     @Input()
diff --git a/ui/src/app/dashboard/components/widgets/table/table-widget.component.ts b/ui/src/app/dashboard/components/widgets/table/table-widget.component.ts
index 1a876ea3a9..3faf709cbc 100644
--- a/ui/src/app/dashboard/components/widgets/table/table-widget.component.ts
+++ b/ui/src/app/dashboard/components/widgets/table/table-widget.component.ts
@@ -21,10 +21,10 @@ import { BaseStreamPipesWidget } from '../base/base-widget';
 import { StaticPropertyExtractor } from '../../../sdk/extractor/static-property-extractor';
 import { MatTableDataSource } from '@angular/material/table';
 import { TableConfig } from './table-config';
-import { SemanticTypeUtilsService } from '../../../../core-services/semantic-type/semantic-type-utils.service';
 import { ResizeService } from '../../../services/resize.service';
 import { DatalakeRestService } from '@streampipes/platform-services';
 import { WidgetConfigBuilder } from '../../../registry/widget-config-builder';
+import { SemanticTypeService } from '../../../../core-services/types/semantic-type.service';
 
 @Component({
     selector: 'sp-table-widget',
@@ -46,7 +46,7 @@ export class TableWidgetComponent
     constructor(
         dataLakeService: DatalakeRestService,
         resizeService: ResizeService,
-        private semanticTypeUtils: SemanticTypeUtilsService,
+        private semanticTypeUtils: SemanticTypeService,
     ) {
         super(dataLakeService, resizeService, false);
     }
diff --git a/ui/src/app/dashboard/dashboard.module.ts b/ui/src/app/dashboard/dashboard.module.ts
index 9dd11be626..348e508518 100644
--- a/ui/src/app/dashboard/dashboard.module.ts
+++ b/ui/src/app/dashboard/dashboard.module.ts
@@ -37,7 +37,6 @@ import { ResizeService } from './services/resize.service';
 import { TableWidgetComponent } from './components/widgets/table/table-widget.component';
 import { CdkTableModule } from '@angular/cdk/table';
 import { RefreshDashboardService } from './services/refresh-dashboard.service';
-import { SemanticTypeUtilsService } from '../core-services/semantic-type/semantic-type-utils.service';
 import { GaugeWidgetComponent } from './components/widgets/gauge/gauge-widget.component';
 import { ImageWidgetComponent } from './components/widgets/image/image-widget.component';
 import { AreaWidgetComponent } from './components/widgets/area/area-widget.component';
@@ -132,7 +131,6 @@ import { DashboardPanelCanDeactivateGuard } from './dashboard.can-deactivate.gua
         ReloadPipelineService,
         ResizeService,
         RefreshDashboardService,
-        SemanticTypeUtilsService,
     ],
     exports: [DashboardWidgetComponent, StandaloneDashboardComponent],
 })
diff --git a/ui/src/app/data-explorer/components/widgets/time-series-chart/appearance-config/time-series-appearance-config.component.html b/ui/src/app/data-explorer/components/widgets/time-series-chart/appearance-config/time-series-appearance-config.component.html
new file mode 100644
index 0000000000..971b5c850c
--- /dev/null
+++ b/ui/src/app/data-explorer/components/widgets/time-series-chart/appearance-config/time-series-appearance-config.component.html
@@ -0,0 +1,31 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~    http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  ~
+  -->
+
+<div fxLayout="column">
+    <sp-echarts-widget-appearance-config
+        [appearanceConfig]="appearanceConfig"
+        [widgetId]="widgetId"
+    >
+    </sp-echarts-widget-appearance-config>
+
+    <sp-data-zoom-config
+        [appearanceConfig]="appearanceConfig"
+        (configChangedEmitter)="triggerViewUpdate()"
+    >
+    </sp-data-zoom-config>
+</div>
diff --git a/ui/src/app/NS/xs.service.ts b/ui/src/app/data-explorer/components/widgets/time-series-chart/appearance-config/time-series-appearance-config.component.ts
similarity index 50%
rename from ui/src/app/NS/xs.service.ts
rename to ui/src/app/data-explorer/components/widgets/time-series-chart/appearance-config/time-series-appearance-config.component.ts
index a8eea881e3..639e29fdae 100644
--- a/ui/src/app/NS/xs.service.ts
+++ b/ui/src/app/data-explorer/components/widgets/time-series-chart/appearance-config/time-series-appearance-config.component.ts
@@ -16,23 +16,30 @@
  *
  */
 
-import { Injectable } from '@angular/core';
+import { Component, Input } from '@angular/core';
+import { TimeSeriesAppearanceConfig } from '../../../../models/dataview-dashboard.model';
+import { WidgetConfigurationService } from '../../../../services/widget-configuration.service';
 
-@Injectable()
-export class XsService {
-    XS_STRING = 'xs:string';
-    XS_INTEGER = 'http://www.w3.org/2001/XMLSchema#integer';
-    XS_DOUBLE = 'http://www.w3.org/2001/XMLSchema#double';
-    XS_BOOLEAN = 'http://www.w3.org/2001/XMLSchema#boolean';
-    XS_NUMBER = 'http://www.w3.org/2001/XMLSchema#number';
-    XS_STRING1 = 'http://www.w3.org/2001/XMLSchema#string';
-    SO_URL = 'https://schema.org/URL';
+@Component({
+    selector: 'sp-time-series-appearance-config',
+    templateUrl: './time-series-appearance-config.component.html',
+})
+export class SpTimeSeriesAppearanceConfigComponent {
+    @Input()
+    appearanceConfig: TimeSeriesAppearanceConfig;
 
-    isNumber(datatype: string): boolean {
-        return (
-            datatype === this.XS_DOUBLE ||
-            datatype === this.XS_INTEGER ||
-            datatype === this.XS_NUMBER
-        );
+    @Input()
+    widgetId: string;
+
+    constructor(
+        private widgetConfigurationService: WidgetConfigurationService,
+    ) {}
+
+    triggerViewUpdate() {
+        this.widgetConfigurationService.notify({
+            widgetId: this.widgetId,
+            refreshView: true,
+            refreshData: false,
+        });
     }
 }
diff --git a/ui/src/app/data-explorer/components/widgets/time-series-chart/sp-timeseries-renderer.service.ts b/ui/src/app/data-explorer/components/widgets/time-series-chart/sp-timeseries-renderer.service.ts
index 73e027632f..565f12a741 100644
--- a/ui/src/app/data-explorer/components/widgets/time-series-chart/sp-timeseries-renderer.service.ts
+++ b/ui/src/app/data-explorer/components/widgets/time-series-chart/sp-timeseries-renderer.service.ts
@@ -16,7 +16,12 @@
  *
  */
 
-import { BarSeriesOption, EChartsOption, LineSeriesOption } from 'echarts';
+import {
+    BarSeriesOption,
+    EChartsOption,
+    LineSeriesOption,
+    ScatterSeriesOption,
+} from 'echarts';
 import { SeriesOption } from 'echarts/types/src/util/types';
 import { Injectable } from '@angular/core';
 import { TimeSeriesChartWidgetModel } from './model/time-series-chart-widget.model';
@@ -86,8 +91,11 @@ export class SpTimeseriesRendererService extends SpBaseEchartsRenderer<TimeSerie
             },
         );
 
+        this.addDataZoomOptions(widgetConfig, options);
+
         const showTooltip =
             widgetConfig.baseAppearanceConfig.chartAppearance?.showTooltip;
+
         Object.assign(options, {
             series: finalSeries,
             dataset:
@@ -152,13 +160,15 @@ export class SpTimeseriesRendererService extends SpBaseEchartsRenderer<TimeSerie
                 y: fieldIndex,
             },
             datasetIndex,
-        } as LineSeriesOption | BarSeriesOption;
+        } as LineSeriesOption | BarSeriesOption | ScatterSeriesOption;
         if (seriesType === 'line') {
             this.appendLineOptions(
                 series as LineSeriesOption,
                 widgetConfig,
                 field,
             );
+        } else if (seriesType === 'scatter') {
+            this.appendScatterOptions(series as ScatterSeriesOption);
         }
         return series;
     }
@@ -166,10 +176,12 @@ export class SpTimeseriesRendererService extends SpBaseEchartsRenderer<TimeSerie
     private makeSeriesType(
         displayTypes: Record<string, string>,
         field: DataExplorerField,
-    ) {
+    ): 'bar' | 'line' | 'scatter' {
         const type = this.getDisplayType(displayTypes, field);
         if (type === 'bar') {
             return 'bar';
+        } else if (type === 'normal_markers') {
+            return 'scatter';
         } else {
             return 'line';
         }
@@ -182,6 +194,10 @@ export class SpTimeseriesRendererService extends SpBaseEchartsRenderer<TimeSerie
         return displayTypes[field.fullDbName + field.sourceIndex];
     }
 
+    private appendScatterOptions(series: ScatterSeriesOption): void {
+        series.symbolSize = 4;
+    }
+
     private appendLineOptions(
         series: LineSeriesOption,
         conf: TimeSeriesChartWidgetModel,
@@ -225,6 +241,19 @@ export class SpTimeseriesRendererService extends SpBaseEchartsRenderer<TimeSerie
         }
     }
 
+    private addDataZoomOptions(
+        config: TimeSeriesChartWidgetModel,
+        options: EChartsOption,
+    ): void {
+        Object.assign(options, {
+            dataZoom: config.baseAppearanceConfig.dataZoom?.show
+                ? {
+                      type: config.baseAppearanceConfig.dataZoom?.type,
+                  }
+                : [],
+        });
+    }
+
     private addAxisOptions(
         config: TimeSeriesChartWidgetModel,
         options: EChartsOption,
diff --git a/ui/src/app/data-explorer/components/widgets/utils/data-zoom-config/data-zoom-config.component.html b/ui/src/app/data-explorer/components/widgets/utils/data-zoom-config/data-zoom-config.component.html
new file mode 100644
index 0000000000..c5c4d4a684
--- /dev/null
+++ b/ui/src/app/data-explorer/components/widgets/utils/data-zoom-config/data-zoom-config.component.html
@@ -0,0 +1,46 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~    http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  ~
+  -->
+
+<sp-configuration-box title="Data Zoom">
+    <div fxLayout="column">
+        <mat-checkbox
+            [(ngModel)]="appearanceConfig.dataZoom.show"
+            (ngModelChange)="configChangedEmitter.emit()"
+            >Active
+        </mat-checkbox>
+
+        <div fxFlex="100" fxLayoutAlign="start center" class="ml-10">
+            <div fxLayoutAlign="start center">
+                <span>Type</span>
+            </div>
+            <span fxFlex></span>
+            <div class="form-field-small w-100" fxLayoutAlign="end center">
+                <mat-form-field appearance="outline" color="accent" fxFlex="30">
+                    <mat-select
+                        (ngModelChange)="configChangedEmitter.emit()"
+                        [(ngModel)]="appearanceConfig.dataZoom.type"
+                        [disabled]="!appearanceConfig.dataZoom.show"
+                    >
+                        <mat-option value="inside">Wheel</mat-option>
+                        <mat-option value="slider">Slider</mat-option>
+                    </mat-select>
+                </mat-form-field>
+            </div>
+        </div>
+    </div>
+</sp-configuration-box>
diff --git a/ui/src/app/NS/XS.service.spec.ts b/ui/src/app/data-explorer/components/widgets/utils/data-zoom-config/data-zoom-config.component.ts
similarity index 56%
rename from ui/src/app/NS/XS.service.spec.ts
rename to ui/src/app/data-explorer/components/widgets/utils/data-zoom-config/data-zoom-config.component.ts
index 6db8f577a6..fadab18ace 100644
--- a/ui/src/app/NS/XS.service.spec.ts
+++ b/ui/src/app/data-explorer/components/widgets/utils/data-zoom-config/data-zoom-config.component.ts
@@ -16,19 +16,24 @@
  *
  */
 
-import { XsService } from './xs.service';
+import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
+import { TimeSeriesAppearanceConfig } from '../../../../models/dataview-dashboard.model';
 
-describe('XSService', () => {
-    const service: XsService = new XsService();
+@Component({
+    selector: 'sp-data-zoom-config',
+    templateUrl: './data-zoom-config.component.html',
+})
+export class SpDataZoomConfigComponent implements OnInit {
+    @Input()
+    appearanceConfig: TimeSeriesAppearanceConfig;
 
-    it('should get string XS String', () => {
-        expect(service.XS_STRING).toBe('xs:string');
-    });
+    @Output()
+    configChangedEmitter: EventEmitter<void> = new EventEmitter<void>();
 
-    it('should check for numbers', () => {
-        expect(service.isNumber(service.XS_DOUBLE)).toBeTrue();
-        expect(service.isNumber(service.XS_INTEGER)).toBeTrue();
-        expect(service.isNumber(service.XS_NUMBER)).toBeTrue();
-        expect(service.isNumber(service.XS_STRING)).toBeFalse();
-    });
-});
+    ngOnInit(): void {
+        this.appearanceConfig.dataZoom ??= {
+            show: true,
+            type: 'inside',
+        };
+    }
+}
diff --git a/ui/src/app/data-explorer/components/widgets/utils/select-color-properties/time-series-item-config/time-series-item-config.component.html b/ui/src/app/data-explorer/components/widgets/utils/select-color-properties/time-series-item-config/time-series-item-config.component.html
index 6d47d0081e..3c3ce3e51f 100644
--- a/ui/src/app/data-explorer/components/widgets/utils/select-color-properties/time-series-item-config/time-series-item-config.component.html
+++ b/ui/src/app/data-explorer/components/widgets/utils/select-color-properties/time-series-item-config/time-series-item-config.component.html
@@ -23,13 +23,14 @@
             [checked]="isSelected(field)"
             (change)="toggleFieldSelection(field)"
         >
-            <b>{{ field.runtimeName }}</b>
-            {{
-                '(' +
+            <b>{{ field.runtimeName }}</b
+            ><br />
+            <small>
+                {{
                     (field.aggregation ? field.aggregation + ', ' : '') +
-                    field.measure +
-                    ')'
-            }}
+                        field.measure
+                }}</small
+            >
         </mat-checkbox>
         <span fxFlex></span>
         <span
@@ -130,6 +131,7 @@
                         "
                         (selectionChange)="viewRefreshEmitter.emit()"
                     >
+                        <mat-option [value]="'bar'">Bar</mat-option>
                         <mat-option [value]="'lines'">Line</mat-option>
                         <mat-option [value]="'normal_markers'"
                             >Scatter
@@ -137,10 +139,6 @@
                         <mat-option [value]="'lines+markers'"
                             >Scattered Line
                         </mat-option>
-                        <mat-option [value]="'bar'">Bar</mat-option>
-                        <mat-option [value]="'symbol_markers'"
-                            >Symbol
-                        </mat-option>
                     </mat-select>
                 </mat-form-field>
             </div>
diff --git a/ui/src/app/data-explorer/data-explorer.module.ts b/ui/src/app/data-explorer/data-explorer.module.ts
index 67163e8087..da87156deb 100644
--- a/ui/src/app/data-explorer/data-explorer.module.ts
+++ b/ui/src/app/data-explorer/data-explorer.module.ts
@@ -34,7 +34,6 @@ import { LeafletModule } from '@asymmetrik/ngx-leaflet';
 import { NgxChartsModule } from '@swimlane/ngx-charts';
 import { GridsterModule } from 'angular-gridster2';
 import { ColorPickerModule } from 'ngx-color-picker';
-import { SemanticTypeUtilsService } from '../core-services/semantic-type/semantic-type-utils.service';
 import { PlatformServicesModule } from '@streampipes/platform-services';
 import { CoreUiModule } from '../core-ui/core-ui.module';
 import { CustomMaterialModule } from '../CustomMaterial/custom-material.module';
@@ -90,6 +89,8 @@ import { SpVisualizationConfigOuterComponent } from './components/widgets/utils/
 import { SpSelectAxisOptionsComponent } from './components/widgets/utils/select-axis-options/select-axis-options.component';
 import { SpTimeseriesItemConfigComponent } from './components/widgets/utils/select-color-properties/time-series-item-config/time-series-item-config.component';
 import { SpEchartsWidgetAppearanceConfigComponent } from './components/widgets/utils/echarts-widget-appearance-config/echarts-widget-appearance-config.component';
+import { SpTimeSeriesAppearanceConfigComponent } from './components/widgets/time-series-chart/appearance-config/time-series-appearance-config.component';
+import { SpDataZoomConfigComponent } from './components/widgets/utils/data-zoom-config/data-zoom-config.component';
 
 @NgModule({
     imports: [
@@ -188,8 +189,10 @@ import { SpEchartsWidgetAppearanceConfigComponent } from './components/widgets/u
         SpSelectAxisOptionsComponent,
         SpTimeseriesItemConfigComponent,
         SpEchartsWidgetAppearanceConfigComponent,
+        SpTimeSeriesAppearanceConfigComponent,
+        SpDataZoomConfigComponent,
     ],
-    providers: [SemanticTypeUtilsService],
+    providers: [],
     exports: [],
 })
 export class DataExplorerModule {
diff --git a/ui/src/app/data-explorer/models/dataview-dashboard.model.ts b/ui/src/app/data-explorer/models/dataview-dashboard.model.ts
index c3141f2ebc..e6d9ae5199 100644
--- a/ui/src/app/data-explorer/models/dataview-dashboard.model.ts
+++ b/ui/src/app/data-explorer/models/dataview-dashboard.model.ts
@@ -85,6 +85,16 @@ export interface WidgetChartAppearanceConfig {
     showTooltip: boolean;
 }
 
+export interface DataZoomConfig {
+    show: boolean;
+    type: 'slider' | 'inside';
+}
+
+export interface TimeSeriesAppearanceConfig
+    extends WidgetEchartsAppearanceConfig {
+    dataZoom: DataZoomConfig;
+}
+
 export interface WidgetEchartsAppearanceConfig {
     chartAppearance: WidgetChartAppearanceConfig;
 }
diff --git a/ui/src/app/data-explorer/registry/data-explorer-widget-registry.ts b/ui/src/app/data-explorer/registry/data-explorer-widget-registry.ts
index d36f5105e0..d08204cc34 100644
--- a/ui/src/app/data-explorer/registry/data-explorer-widget-registry.ts
+++ b/ui/src/app/data-explorer/registry/data-explorer-widget-registry.ts
@@ -48,6 +48,7 @@ import { SpIndicatorRendererService } from '../components/widgets/indicator/indi
 import { TimeSeriesChartWidgetModel } from '../components/widgets/time-series-chart/model/time-series-chart-widget.model';
 import { SpTimeseriesRendererService } from '../components/widgets/time-series-chart/sp-timeseries-renderer.service';
 import { SpEchartsWidgetAppearanceConfigComponent } from '../components/widgets/utils/echarts-widget-appearance-config/echarts-widget-appearance-config.component';
+import { SpTimeSeriesAppearanceConfigComponent } from '../components/widgets/time-series-chart/appearance-config/time-series-appearance-config.component';
 
 @Injectable({ providedIn: 'root' })
 export class DataExplorerWidgetRegistry {
@@ -89,7 +90,7 @@ export class DataExplorerWidgetRegistry {
                 id: 'time-series-chart',
                 label: 'Time Series Chart',
                 widgetAppearanceConfigurationComponent:
-                    SpEchartsWidgetAppearanceConfigComponent,
+                    SpTimeSeriesAppearanceConfigComponent,
                 widgetConfigurationComponent:
                     TimeSeriesChartWidgetConfigComponent,
                 widgetComponent:
diff --git a/ui/src/app/data-explorer/services/data-explorer-field-provider-service.ts b/ui/src/app/data-explorer/services/data-explorer-field-provider-service.ts
index 7142a430bb..d1a04626e2 100644
--- a/ui/src/app/data-explorer/services/data-explorer-field-provider-service.ts
+++ b/ui/src/app/data-explorer/services/data-explorer-field-provider-service.ts
@@ -26,9 +26,12 @@ import {
     FieldConfig,
     SourceConfig,
 } from '@streampipes/platform-services';
+import { SemanticTypeService } from '../../core-services/types/semantic-type.service';
 
 @Injectable({ providedIn: 'root' })
 export class DataExplorerFieldProviderService {
+    constructor(private semanticTypeService: SemanticTypeService) {}
+
     public generateFieldLists(sourceConfigs: SourceConfig[]): FieldProvider {
         const provider: FieldProvider = {
             allFields: [],
@@ -141,7 +144,7 @@ export class DataExplorerFieldProviderService {
         return (
             this.isPrimitive(p) &&
             (p as EventPropertyPrimitive).runtimeType ===
-                'http://www.w3.org/2001/XMLSchema#boolean'
+                this.semanticTypeService.XS_BOOLEAN
         );
     }
 
@@ -149,13 +152,13 @@ export class DataExplorerFieldProviderService {
         return (
             this.isPrimitive(p) &&
             (p as EventPropertyPrimitive).runtimeType ===
-                'http://www.w3.org/2001/XMLSchema#string'
+                this.semanticTypeService.XS_STRING
         );
     }
 
     public isTimestamp(p: EventProperty) {
         return p.domainProperties.some(
-            dp => dp === 'http://schema.org/DateTime',
+            dp => dp === this.semanticTypeService.TIMESTAMP,
         );
     }
 
@@ -188,14 +191,7 @@ export class DataExplorerFieldProviderService {
     isNumber(p: EventPropertyUnion): boolean {
         if (this.isPrimitive(p)) {
             const runtimeType = (p as EventPropertyPrimitive).runtimeType;
-
-            return (
-                runtimeType === 'http://schema.org/Number' ||
-                runtimeType === 'http://www.w3.org/2001/XMLSchema#float' ||
-                runtimeType === 'http://www.w3.org/2001/XMLSchema#double' ||
-                runtimeType === 'http://www.w3.org/2001/XMLSchema#integer' ||
-                runtimeType === 'http://www.w3.org/2001/XMLSchema#long'
-            );
+            return this.semanticTypeService.isNumberType(runtimeType);
         } else {
             return false;
         }
diff --git a/ui/src/app/editor/components/output-strategy/user-defined-output/user-defined-output.component.ts b/ui/src/app/editor/components/output-strategy/user-defined-output/user-defined-output.component.ts
index 737c8db9af..ecfe3ce1f3 100644
--- a/ui/src/app/editor/components/output-strategy/user-defined-output/user-defined-output.component.ts
+++ b/ui/src/app/editor/components/output-strategy/user-defined-output/user-defined-output.component.ts
@@ -23,6 +23,8 @@ import {
     UserDefinedOutputStrategy,
 } from '@streampipes/platform-services';
 import { UntypedFormControl } from '@angular/forms';
+import { IdGeneratorService } from '../../../../core-services/id-generator/id-generator.service';
+import { SemanticTypeService } from '../../../../core-services/types/semantic-type.service';
 
 @Component({
     selector: 'sp-user-defined-output-strategy',
@@ -33,23 +35,19 @@ export class UserDefinedOutputStrategyComponent
     extends BaseOutputStrategy<UserDefinedOutputStrategy>
     implements OnInit
 {
-    private prefix = 'urn:streampipes.org:spi:';
-    private chars =
-        '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
-
-    collectedPropertiesFirstStream: any;
-    collectedPropertiesSecondStream: any;
-
     primitiveClasses = [
-        { label: 'String', id: 'http://www.w3.org/2001/XMLSchema#string' },
-        { label: 'Boolean', id: 'http://www.w3.org/2001/XMLSchema#boolean' },
-        { label: 'Integer', id: 'http://www.w3.org/2001/XMLSchema#integer' },
-        { label: 'Long', id: 'http://www.w3.org/2001/XMLSchema#long' },
-        { label: 'Double', id: 'http://www.w3.org/2001/XMLSchema#double' },
-        { label: 'Float', id: 'http://www.w3.org/2001/XMLSchema#float' },
+        { label: 'String', id: this.semanticTypeService.XS_STRING },
+        { label: 'Boolean', id: this.semanticTypeService.XS_BOOLEAN },
+        { label: 'Integer', id: this.semanticTypeService.XS_INTEGER },
+        { label: 'Long', id: this.semanticTypeService.XS_LONG },
+        { label: 'Double', id: this.semanticTypeService.XS_DOUBLE },
+        { label: 'Float', id: this.semanticTypeService.XS_FLOAT },
     ];
 
-    constructor() {
+    constructor(
+        private idGeneratorService: IdGeneratorService,
+        private semanticTypeService: SemanticTypeService,
+    ) {
         super();
     }
 
@@ -87,23 +85,12 @@ export class UserDefinedOutputStrategyComponent
             'org.apache.streampipes.model.schema.EventPropertyPrimitive';
         ep.domainProperties = [];
         ep.elementId =
-            'urn:streampipes.org:spi:eventpropertyprimitive:' + this.makeId();
+            'urn:streampipes.org:spi:eventpropertyprimitive:' +
+            this.idGeneratorService.generatePrefixedId();
 
         return ep;
     }
 
-    makeId() {
-        return this.prefix + this.randomString(6);
-    }
-
-    randomString(length) {
-        let result = '';
-        for (let i = length; i > 0; --i) {
-            result += this.chars[Math.floor(Math.random() * this.chars.length)];
-        }
-        return result;
-    }
-
     checkFormValidity() {
         if (
             !this.outputStrategy.eventProperties ||
diff --git a/ui/src/app/editor/components/pipeline-element-preview/pipeline-element-preview.component.scss b/ui/src/app/editor/components/pipeline-element-preview/pipeline-element-preview.component.scss
index bf2c8f6439..3734f07db9 100644
--- a/ui/src/app/editor/components/pipeline-element-preview/pipeline-element-preview.component.scss
+++ b/ui/src/app/editor/components/pipeline-element-preview/pipeline-element-preview.component.scss
@@ -41,7 +41,3 @@
 .preview-table {
     background: var(--color-bg-dialog);
 }
-
-.dataTable tbody tr:hover {
-    background: var(--color-bg-1);
-}
diff --git a/ui/src/app/editor/components/pipeline/pipeline.component.ts b/ui/src/app/editor/components/pipeline/pipeline.component.ts
index b096493b68..416d373f94 100644
--- a/ui/src/app/editor/components/pipeline/pipeline.component.ts
+++ b/ui/src/app/editor/components/pipeline/pipeline.component.ts
@@ -69,6 +69,7 @@ import {
     EVENT_CONNECTION_MOVED,
 } from '@jsplumb/browser-ui';
 import { PipelineStyleService } from '../../services/pipeline-style.service';
+import { IdGeneratorService } from '../../../core-services/id-generator/id-generator.service';
 
 @Component({
     selector: 'sp-pipeline',
@@ -112,9 +113,6 @@ export class PipelineComponent implements OnInit, OnDestroy {
     idCounter: any;
     currentZoomLevel: any;
 
-    canvasWidth = '100%';
-    canvasHeight = '100%';
-
     JsplumbBridge: JsplumbBridge;
 
     previewModeActive = false;
@@ -127,6 +125,7 @@ export class PipelineComponent implements OnInit, OnDestroy {
         private jsplumbFactoryService: JsplumbFactoryService,
         private objectProvider: ObjectProvider,
         private editorService: EditorService,
+        private idGeneratorService: IdGeneratorService,
         private shepherdService: ShepherdService,
         private pipelineStyleService: PipelineStyleService,
         private pipelineValidationService: PipelineValidationService,
@@ -244,7 +243,7 @@ export class PipelineComponent implements OnInit, OnDestroy {
                     const newElementId =
                         pipelineElement.elementId +
                         ':' +
-                        this.jsplumbService.makeId(5);
+                        this.idGeneratorService.generate(5);
                     const pipelineElementConfig =
                         this.jsplumbService.createNewPipelineElementConfig(
                             pipelineElement,
diff --git a/ui/src/app/editor/dialog/matching-error/matching-error.component.html b/ui/src/app/editor/dialog/matching-error/matching-error.component.html
index c68c6ed8eb..a29b922058 100644
--- a/ui/src/app/editor/dialog/matching-error/matching-error.component.html
+++ b/ui/src/app/editor/dialog/matching-error/matching-error.component.html
@@ -41,11 +41,6 @@
                         style="margin-bottom: 10px"
                     >
                         <div fxFlex fxLayout="column" class="md-padding">
-                            <!--                            <div>-->
-                            <!--                                <i class="material-icons" *ngIf="entry.matchingResultMessage">done</i>-->
-                            <!--                                <i class="material-icons" *ngIf="entry.matchingSuccessful">warning</i>-->
-                            <!--                                <b>{{entry.title}} </b>-->
-                            <!--                            </div>-->
                             <div fxFlex="column">
                                 {{ entry.title }}<br />
                                 {{ entry.description }}
diff --git a/ui/src/app/editor/dialog/save-pipeline/save-pipeline.component.html b/ui/src/app/editor/dialog/save-pipeline/save-pipeline.component.html
index bfc2229788..94af6d9021 100644
--- a/ui/src/app/editor/dialog/save-pipeline/save-pipeline.component.html
+++ b/ui/src/app/editor/dialog/save-pipeline/save-pipeline.component.html
@@ -63,8 +63,6 @@
                                 matInput
                                 name="pipelineName"
                             />
-                            <!--                        <span ng-show="submitPipelineForm.pipelineName.$touched && submitPipelineForm.pipelineName.$error.required">Please provide a pipeline name.</span>-->
-                            <!--                        <span ng-show="submitPipelineForm.pipelineName.$error.maxlength">Please provide a shorter pipeline name.</span>-->
                         </mat-form-field>
                         <mat-form-field fxFlex color="accent">
                             <mat-label>Description</mat-label>
@@ -72,7 +70,6 @@
                                 [formControlName]="'pipelineDescription'"
                                 matInput
                             />
-                            <!--                        <span ng-show="submitPipelineForm.pipelineDescription.$error.maxlength">Please provide a shorter description.</span>-->
                         </mat-form-field>
                     </div>
                 </form>
diff --git a/ui/src/app/editor/dialog/save-pipeline/save-pipeline.component.ts b/ui/src/app/editor/dialog/save-pipeline/save-pipeline.component.ts
index b52f66ed86..4476366bba 100644
--- a/ui/src/app/editor/dialog/save-pipeline/save-pipeline.component.ts
+++ b/ui/src/app/editor/dialog/save-pipeline/save-pipeline.component.ts
@@ -25,7 +25,6 @@ import {
     PipelineService,
     PipelineCanvasMetadataService,
 } from '@streampipes/platform-services';
-import { ObjectProvider } from '../../services/object-provider.service';
 import { EditorService } from '../../services/editor.service';
 import { ShepherdService } from '../../../services/tour/shepherd.service';
 import {
@@ -35,7 +34,7 @@ import {
 } from '@angular/forms';
 import { Router } from '@angular/router';
 import { InvocablePipelineElementUnion } from '../../model/editor.model';
-import { JsplumbService } from '../../services/jsplumb.service';
+import { IdGeneratorService } from '../../../core-services/id-generator/id-generator.service';
 
 @Component({
     selector: 'sp-save-pipeline',
@@ -72,8 +71,7 @@ export class SavePipelineComponent implements OnInit {
     constructor(
         private editorService: EditorService,
         private dialogRef: DialogRef<SavePipelineComponent>,
-        private jsplumbService: JsplumbService,
-        private objectProvider: ObjectProvider,
+        private idGeneratorService: IdGeneratorService,
         private pipelineService: PipelineService,
         private router: Router,
         private shepherdService: ShepherdService,
@@ -178,7 +176,7 @@ export class SavePipelineComponent implements OnInit {
         const lastIdIndex = entity.elementId.lastIndexOf(':');
         const newElementId =
             entity.elementId.substring(0, lastIdIndex + 1) +
-            this.jsplumbService.makeId(5);
+            this.idGeneratorService.generate(5);
         entity.elementId = newElementId;
     }
 
diff --git a/ui/src/app/editor/editor.module.ts b/ui/src/app/editor/editor.module.ts
index afcc37f430..763bb41126 100644
--- a/ui/src/app/editor/editor.module.ts
+++ b/ui/src/app/editor/editor.module.ts
@@ -23,7 +23,6 @@ import { GridsterModule } from 'angular-gridster2';
 import { MatTabsModule } from '@angular/material/tabs';
 import { CustomMaterialModule } from '../CustomMaterial/custom-material.module';
 import { FormsModule, ReactiveFormsModule } from '@angular/forms';
-import { SemanticTypeUtilsService } from '../core-services/semantic-type/semantic-type-utils.service';
 import { EditorComponent } from './editor.component';
 import { PipelineElementIconStandComponent } from './components/pipeline-element-icon-stand/pipeline-element-icon-stand.component';
 import { PipelineAssemblyComponent } from './components/pipeline-assembly/pipeline-assembly.component';
@@ -93,7 +92,7 @@ import { PipelineElementGroupFilterPipe } from './services/pipeline-element-grou
         SavePipelineComponent,
         SafeCss,
     ],
-    providers: [SemanticTypeUtilsService, SafeCss],
+    providers: [SafeCss],
     exports: [EditorComponent, PipelineComponent, PipelineElementComponent],
 })
 export class EditorModule {
diff --git a/ui/src/app/editor/services/jsplumb.service.ts b/ui/src/app/editor/services/jsplumb.service.ts
index 4f6a813df2..6e6959aff4 100644
--- a/ui/src/app/editor/services/jsplumb.service.ts
+++ b/ui/src/app/editor/services/jsplumb.service.ts
@@ -16,7 +16,6 @@
  *
  */
 
-import { JsplumbConfigService } from './jsplumb-config.service';
 import { JsplumbBridge } from './jsplumb-bridge.service';
 import { Injectable } from '@angular/core';
 import {
@@ -34,17 +33,16 @@ import {
 } from '@streampipes/platform-services';
 import { JsplumbEndpointService } from './jsplumb-endpoint.service';
 import { JsplumbFactoryService } from './jsplumb-factory.service';
-import { EditorService } from './editor.service';
+import { IdGeneratorService } from '../../core-services/id-generator/id-generator.service';
 
 @Injectable({ providedIn: 'root' })
 export class JsplumbService {
     idCounter = 0;
 
     constructor(
-        private jsplumbConfigService: JsplumbConfigService,
         private jsplumbFactory: JsplumbFactoryService,
         private jsplumbEndpointService: JsplumbEndpointService,
-        private editorService: EditorService,
+        private idGeneratorService: IdGeneratorService,
     ) {}
 
     isFullyConnected(
@@ -270,7 +268,10 @@ export class JsplumbService {
         };
         if (!pipelineElementConfig.payload.dom) {
             pipelineElementConfig.payload.dom =
-                'jsplumb_' + this.idCounter + '_' + this.makeId(4);
+                'jsplumb_' +
+                this.idCounter +
+                '_' +
+                this.idGeneratorService.generate(4);
             this.idCounter++;
         }
 
@@ -312,20 +313,6 @@ export class JsplumbService {
         pipelineElement.elementId = newElementId;
     }
 
-    makeId(count: number) {
-        let text = '';
-        const possible =
-            'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
-
-        for (let i = 0; i < count; i++) {
-            text += possible.charAt(
-                Math.floor(Math.random() * possible.length),
-            );
-        }
-
-        return text;
-    }
-
     elementDropped(
         pipelineElementDomId: string,
         pipelineElement: PipelineElementUnion,
diff --git a/ui/src/scss/main.scss b/ui/src/scss/main.scss
index 1b028d5a25..0547827269 100644
--- a/ui/src/scss/main.scss
+++ b/ui/src/scss/main.scss
@@ -17,7 +17,6 @@
  */
 
 @import '~@ali-hm/angular-tree-component/css/angular-tree-component.css';
-@import '~datatables.net-dt/css/jquery.dataTables.css';
 @import '~@fortawesome/fontawesome-free/css/all.css';
 @import '~@jsplumb/browser-ui/css/jsplumbtoolkit.css';
 @import '~shepherd.js/dist/css/shepherd.css';
diff --git a/ui/src/scss/sp/layout.scss b/ui/src/scss/sp/layout.scss
index 3fde73aeb6..76195f9bb7 100644
--- a/ui/src/scss/sp/layout.scss
+++ b/ui/src/scss/sp/layout.scss
@@ -92,6 +92,10 @@
     margin-left: 5px;
 }
 
+.ml-10 {
+    margin-left: 10px;
+}
+
 .mr-15 {
     margin-right: 15px;
 }


Test patch:
diff --git a/streampipes-data-explorer/src/test/java/org/apache/streampipes/dataexplorer/query/writer/TestConfiguredOutputWriter.java b/streampipes-data-explorer/src/test/java/org/apache/streampipes/dataexplorer/query/writer/TestConfiguredOutputWriter.java
index 35e8ddece9..14f453fcee 100644
--- a/streampipes-data-explorer/src/test/java/org/apache/streampipes/dataexplorer/query/writer/TestConfiguredOutputWriter.java
+++ b/streampipes-data-explorer/src/test/java/org/apache/streampipes/dataexplorer/query/writer/TestConfiguredOutputWriter.java
@@ -31,8 +31,8 @@ public abstract class TestConfiguredOutputWriter {
   @BeforeEach
   public void before() {
     this.rows = Arrays.asList(
-        Arrays.asList("2022-11-16T05:54:37.051Z", "test", 1),
-        Arrays.asList("2022-11-16T05:55:27.05Z", "test2", 2)
+        Arrays.asList(1668578077051.0, "test", 1),
+        Arrays.asList(1668578127050.0, "test2", 2)
     );
 
     this.columns = Arrays.asList("time", "string", "number");
diff --git a/streampipes-data-explorer/src/test/java/org/apache/streampipes/dataexplorer/query/writer/item/TestItemWriter.java b/streampipes-data-explorer/src/test/java/org/apache/streampipes/dataexplorer/query/writer/item/TestItemWriter.java
index 6955f5feeb..0c113ca78d 100644
--- a/streampipes-data-explorer/src/test/java/org/apache/streampipes/dataexplorer/query/writer/item/TestItemWriter.java
+++ b/streampipes-data-explorer/src/test/java/org/apache/streampipes/dataexplorer/query/writer/item/TestItemWriter.java
@@ -30,7 +30,7 @@ public abstract class TestItemWriter {
 
   @BeforeEach
   public void before() {
-    this.row = Arrays.asList("2022-11-16T05:54:37.051Z", "test", 1);
+    this.row = Arrays.asList(1668578077051.0, "test", 1);
     this.columns = Arrays.asList("time", "string", "number");
   }
 }