You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streampipes.apache.org by ri...@apache.org on 2022/07/25 15:50:25 UTC
[incubator-streampipes] branch STREAMPIPES-545 updated: [STREAMPIPES-545] Add feature to assign links to asset descriptions
This is an automated email from the ASF dual-hosted git repository.
riemer pushed a commit to branch STREAMPIPES-545
in repository https://gitbox.apache.org/repos/asf/incubator-streampipes.git
The following commit(s) were added to refs/heads/STREAMPIPES-545 by this push:
new 0c2a369e5 [STREAMPIPES-545] Add feature to assign links to asset descriptions
new 121f90058 Merge branch 'STREAMPIPES-545' of github.com:apache/incubator-streampipes into STREAMPIPES-545
0c2a369e5 is described below
commit 0c2a369e50e484cdaae720ca0c72d1cff0c2afd6
Author: Dominik Riemer <do...@gmail.com>
AuthorDate: Mon Jul 25 17:50:02 2022 +0200
[STREAMPIPES-545] Add feature to assign links to asset descriptions
---
.../backend/StreamPipesBackendApplication.java | 2 +
.../backend/migrations/AvailableMigrations.java | 24 ++---
.../streampipes/backend/migrations/Migration.java | 11 ++-
.../backend/migrations/MigrationsHandler.java | 43 ++++-----
.../v070/CreateAssetLinkTypeMigration.java | 49 ++++++++++
.../v070/CreateDefaultAssetMigration.java | 45 ++++-----
.../commons/constants/GenericDocTypes.java | 10 +-
.../apache/streampipes/model/assets/AssetLink.java | 62 ++++++++++++
.../streampipes/model/assets/AssetLinkType.java | 100 ++++++++++++++++++++
.../apache/streampipes/model/assets/AssetType.java | 62 ++++++++++++
.../apache/streampipes/model/assets/SpAsset.java | 87 +++++++++++++++++
.../streampipes/model/assets/SpAssetModel.java | 37 ++++++--
.../setup/tasks/CreateAssetLinkTypeTask.java | 60 ++++++++++++
.../setup/tasks/CreateDefaultAssetTask.java | 35 ++++---
.../manager/setup/tasks/InstallationTask.java | 6 +-
.../streampipes/storage/api/IGenericStorage.java | 2 +
.../storage/couchdb/impl/GenericStorageImpl.java | 8 ++
.../src/lib/model/assets/asset.model.ts | 12 ++-
ui/src/app/assets/assets.module.ts | 4 +
.../asset-details-panel.component.html | 35 +++++--
.../asset-details-panel.component.scss | 13 +++
.../asset-details-panel.component.ts | 76 ++++++++++++++-
.../asset-link-item/asset-link-item.component.html | 30 ++++++
.../asset-link-item.component.scss} | 10 +-
.../asset-link-item/asset-link-item.component.ts | 68 ++++++++++++++
.../asset-details/asset-details.component.html | 13 ++-
.../asset-details/asset-details.component.ts | 39 +++++++-
.../asset-selection-panel.component.html | 6 +-
.../asset-selection-panel.component.scss | 15 ++-
.../asset-selection-panel.component.ts | 27 +++++-
.../asset-overview/asset-overview.component.html | 20 ++--
.../asset-overview/asset-overview.component.ts | 9 +-
ui/src/app/assets/constants/asset.constants.ts | 1 +
.../edit-asset-link-dialog.component.html | 76 +++++++++++++++
.../edit-asset-link-dialog.component.scss} | 2 +
.../edit-asset-link-dialog.component.ts | 104 +++++++++++++++++++++
36 files changed, 1073 insertions(+), 130 deletions(-)
diff --git a/streampipes-backend/src/main/java/org/apache/streampipes/backend/StreamPipesBackendApplication.java b/streampipes-backend/src/main/java/org/apache/streampipes/backend/StreamPipesBackendApplication.java
index fb60350c7..f131581e0 100644
--- a/streampipes-backend/src/main/java/org/apache/streampipes/backend/StreamPipesBackendApplication.java
+++ b/streampipes-backend/src/main/java/org/apache/streampipes/backend/StreamPipesBackendApplication.java
@@ -17,6 +17,7 @@
*/
package org.apache.streampipes.backend;
+import org.apache.streampipes.backend.migrations.MigrationsHandler;
import org.apache.streampipes.config.backend.BackendConfig;
import org.apache.streampipes.manager.health.PipelineHealthCheck;
import org.apache.streampipes.manager.operations.Operations;
@@ -103,6 +104,7 @@ public class StreamPipesBackendApplication extends StreamPipesServiceBase {
new StreamPipesEnvChecker().updateEnvironmentVariables();
new CouchDbViewGenerator().createGenericDatabaseIfNotExists();
+ new MigrationsHandler().performMigrations();
executorService.schedule(this::startAllPreviouslyStoppedPipelines, 5, TimeUnit.SECONDS);
LOG.info("Pipeline health check will run every {} seconds", HEALTH_CHECK_INTERVAL);
diff --git a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IGenericStorage.java b/streampipes-backend/src/main/java/org/apache/streampipes/backend/migrations/AvailableMigrations.java
similarity index 64%
copy from streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IGenericStorage.java
copy to streampipes-backend/src/main/java/org/apache/streampipes/backend/migrations/AvailableMigrations.java
index 7855a3791..38aa9eda7 100644
--- a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IGenericStorage.java
+++ b/streampipes-backend/src/main/java/org/apache/streampipes/backend/migrations/AvailableMigrations.java
@@ -16,21 +16,21 @@
*
*/
-package org.apache.streampipes.storage.api;
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-
-public interface IGenericStorage {
+package org.apache.streampipes.backend.migrations;
- List<Map<String, Object>> findAll(String type) throws IOException;
+import org.apache.streampipes.backend.migrations.v070.CreateAssetLinkTypeMigration;
+import org.apache.streampipes.backend.migrations.v070.CreateDefaultAssetMigration;
- Map<String, Object> findOne(String id) throws IOException;
-
- Map<String, Object> create(String payload) throws IOException;
+import java.util.Arrays;
+import java.util.List;
- Map<String, Object> update(String id, String payload) throws IOException;
+public class AvailableMigrations {
- void delete(String id, String rev) throws IOException;
+ public List<Migration> getAvailableMigrations() {
+ return Arrays.asList(
+ new CreateAssetLinkTypeMigration(),
+ new CreateDefaultAssetMigration()
+ );
+ }
}
diff --git a/ui/src/app/assets/constants/asset.constants.ts b/streampipes-backend/src/main/java/org/apache/streampipes/backend/migrations/Migration.java
similarity index 83%
copy from ui/src/app/assets/constants/asset.constants.ts
copy to streampipes-backend/src/main/java/org/apache/streampipes/backend/migrations/Migration.java
index c0bcb1988..bb165c2b3 100644
--- a/ui/src/app/assets/constants/asset.constants.ts
+++ b/streampipes-backend/src/main/java/org/apache/streampipes/backend/migrations/Migration.java
@@ -16,7 +16,14 @@
*
*/
-export class AssetConstants {
- public static ASSET_APP_DOC_NAME = 'asset-management';
+package org.apache.streampipes.backend.migrations;
+
+public interface Migration {
+
+ boolean shouldExecute();
+
+ void executeMigration();
+
+ String getDescription();
}
diff --git a/ui/src/app/assets/components/asset-details/asset-selection-panel/asset-selection-panel.component.scss b/streampipes-backend/src/main/java/org/apache/streampipes/backend/migrations/MigrationsHandler.java
similarity index 55%
copy from ui/src/app/assets/components/asset-details/asset-selection-panel/asset-selection-panel.component.scss
copy to streampipes-backend/src/main/java/org/apache/streampipes/backend/migrations/MigrationsHandler.java
index 0435c97d6..63f800170 100644
--- a/ui/src/app/assets/components/asset-details/asset-selection-panel/asset-selection-panel.component.scss
+++ b/streampipes-backend/src/main/java/org/apache/streampipes/backend/migrations/MigrationsHandler.java
@@ -16,38 +16,27 @@
*
*/
-.designer-panel-content {
- padding: 0;
- overflow-y: auto;
-}
-.designer-panel-config {
- padding: 0;
-}
+package org.apache.streampipes.backend.migrations;
-.designer-panel-title {
- margin-left: 5px;
-}
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-.designer-panel-header {
- border-bottom:1px solid var(--color-tab-border);
-}
+public class MigrationsHandler {
-.sp-tree-invisible {
- display: none;
-}
+ private static final Logger LOG = LoggerFactory.getLogger(MigrationsHandler.class);
-.sp-tree ul,
-.sp-tree li {
- margin-top: 0;
- margin-bottom: 0;
- list-style-type: none;
-}
+ public void performMigrations() {
+ LOG.info("Checking for required migrations...");
+ var availableMigrations = new AvailableMigrations().getAvailableMigrations();
-.sp-tree .mat-nested-tree-node div[role=group] {
- padding-left: 40px;
-}
+ availableMigrations.forEach(migration -> {
+ if (migration.shouldExecute()) {
+ LOG.info("Performing migration: {}", migration.getDescription());
+ migration.executeMigration();
+ }
+ });
-.sp-tree div[role=group] > .mat-tree-node {
- padding-left: 40px;
+ LOG.info("All migrations completed.");
+ }
}
diff --git a/streampipes-backend/src/main/java/org/apache/streampipes/backend/migrations/v070/CreateAssetLinkTypeMigration.java b/streampipes-backend/src/main/java/org/apache/streampipes/backend/migrations/v070/CreateAssetLinkTypeMigration.java
new file mode 100644
index 000000000..27463d980
--- /dev/null
+++ b/streampipes-backend/src/main/java/org/apache/streampipes/backend/migrations/v070/CreateAssetLinkTypeMigration.java
@@ -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.
+ *
+ */
+
+
+package org.apache.streampipes.backend.migrations.v070;
+
+import org.apache.streampipes.backend.migrations.Migration;
+import org.apache.streampipes.commons.constants.GenericDocTypes;
+import org.apache.streampipes.manager.setup.tasks.CreateAssetLinkTypeTask;
+import org.apache.streampipes.storage.management.StorageDispatcher;
+
+import java.io.IOException;
+
+public class CreateAssetLinkTypeMigration implements Migration {
+
+ @Override
+ public boolean shouldExecute() {
+ try {
+ return StorageDispatcher.INSTANCE.getNoSqlStore().getGenericStorage().findAll(GenericDocTypes.DOC_ASSET_LINK_TYPE).size() == 0;
+ } catch (IOException e) {
+ return true;
+ }
+ }
+
+ @Override
+ public void executeMigration() {
+ new CreateAssetLinkTypeTask().execute();
+ }
+
+ @Override
+ public String getDescription() {
+ return "Populating database with default asset links";
+ }
+}
diff --git a/ui/src/app/assets/components/asset-details/asset-selection-panel/asset-selection-panel.component.scss b/streampipes-backend/src/main/java/org/apache/streampipes/backend/migrations/v070/CreateDefaultAssetMigration.java
similarity index 55%
copy from ui/src/app/assets/components/asset-details/asset-selection-panel/asset-selection-panel.component.scss
copy to streampipes-backend/src/main/java/org/apache/streampipes/backend/migrations/v070/CreateDefaultAssetMigration.java
index 0435c97d6..5cedcf4cf 100644
--- a/ui/src/app/assets/components/asset-details/asset-selection-panel/asset-selection-panel.component.scss
+++ b/streampipes-backend/src/main/java/org/apache/streampipes/backend/migrations/v070/CreateDefaultAssetMigration.java
@@ -16,38 +16,27 @@
*
*/
-.designer-panel-content {
- padding: 0;
- overflow-y: auto;
-}
-
-.designer-panel-config {
- padding: 0;
-}
-.designer-panel-title {
- margin-left: 5px;
-}
+package org.apache.streampipes.backend.migrations.v070;
-.designer-panel-header {
- border-bottom:1px solid var(--color-tab-border);
-}
+import org.apache.streampipes.backend.migrations.Migration;
+import org.apache.streampipes.manager.setup.tasks.CreateDefaultAssetTask;
-.sp-tree-invisible {
- display: none;
-}
+public class CreateDefaultAssetMigration implements Migration {
-.sp-tree ul,
-.sp-tree li {
- margin-top: 0;
- margin-bottom: 0;
- list-style-type: none;
-}
+ @Override
+ public boolean shouldExecute() {
+ return true;
+ //return StorageDispatcher.INSTANCE.getNoSqlStore().getGenericStorage().findOne(GenericDocTypes.DEFAULT_ASSET_DOC_ID) == null;
+ }
-.sp-tree .mat-nested-tree-node div[role=group] {
- padding-left: 40px;
-}
+ @Override
+ public void executeMigration() {
+ new CreateDefaultAssetTask().execute();
+ }
-.sp-tree div[role=group] > .mat-tree-node {
- padding-left: 40px;
+ @Override
+ public String getDescription() {
+ return "Creating a default asset representation";
+ }
}
diff --git a/ui/src/app/assets/constants/asset.constants.ts b/streampipes-commons/src/main/java/org/apache/streampipes/commons/constants/GenericDocTypes.java
similarity index 73%
copy from ui/src/app/assets/constants/asset.constants.ts
copy to streampipes-commons/src/main/java/org/apache/streampipes/commons/constants/GenericDocTypes.java
index c0bcb1988..813f06b90 100644
--- a/ui/src/app/assets/constants/asset.constants.ts
+++ b/streampipes-commons/src/main/java/org/apache/streampipes/commons/constants/GenericDocTypes.java
@@ -16,7 +16,13 @@
*
*/
-export class AssetConstants {
+package org.apache.streampipes.commons.constants;
- public static ASSET_APP_DOC_NAME = 'asset-management';
+public class GenericDocTypes {
+
+ public static final String DOC_ASSET_MANGEMENT = "asset-management";
+ public static final String DOC_ASSET_LINK_TYPE = "asset-link-type";
+
+
+ public static final String DEFAULT_ASSET_DOC_ID = "default-asset";
}
diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/assets/AssetLink.java b/streampipes-model/src/main/java/org/apache/streampipes/model/assets/AssetLink.java
new file mode 100644
index 000000000..b04dee4bc
--- /dev/null
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/assets/AssetLink.java
@@ -0,0 +1,62 @@
+/*
+ * 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.model.assets;
+
+public class AssetLink {
+
+ private String resourceId;
+ private String linkType;
+ private String linkLabel;
+ private boolean editingDisabled;
+
+ public AssetLink() {
+ }
+
+ public String getResourceId() {
+ return resourceId;
+ }
+
+ public void setResourceId(String resourceId) {
+ this.resourceId = resourceId;
+ }
+
+ public String getLinkType() {
+ return linkType;
+ }
+
+ public void setLinkType(String linkType) {
+ this.linkType = linkType;
+ }
+
+ public String getLinkLabel() {
+ return linkLabel;
+ }
+
+ public void setLinkLabel(String linkLabel) {
+ this.linkLabel = linkLabel;
+ }
+
+ public boolean isEditingDisabled() {
+ return editingDisabled;
+ }
+
+ public void setEditingDisabled(boolean editingDisabled) {
+ this.editingDisabled = editingDisabled;
+ }
+}
diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/assets/AssetLinkType.java b/streampipes-model/src/main/java/org/apache/streampipes/model/assets/AssetLinkType.java
new file mode 100644
index 000000000..2bb83b6f8
--- /dev/null
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/assets/AssetLinkType.java
@@ -0,0 +1,100 @@
+/*
+ * 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.model.assets;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.gson.annotations.SerializedName;
+import org.apache.streampipes.commons.constants.GenericDocTypes;
+
+public class AssetLinkType {
+
+ public final String appDocType = GenericDocTypes.DOC_ASSET_LINK_TYPE;
+
+ @JsonProperty("_id")
+ private @SerializedName("_id") String id;
+
+ private String linkType;
+ private String linkLabel;
+ private String linkColor;
+ private String linkIcon;
+ private String linkQueryHint;
+
+ public AssetLinkType(String linkType, String linkLabel, String linkColor, String linkIcon, String linkQueryHint) {
+ this.linkType = linkType;
+ this.linkLabel = linkLabel;
+ this.linkColor = linkColor;
+ this.linkIcon = linkIcon;
+ this.linkQueryHint = linkQueryHint;
+ }
+
+ public AssetLinkType() {
+ }
+
+ public String getLinkType() {
+ return linkType;
+ }
+
+ public void setLinkType(String linkType) {
+ this.linkType = linkType;
+ }
+
+ public String getLinkLabel() {
+ return linkLabel;
+ }
+
+ public void setLinkLabel(String linkLabel) {
+ this.linkLabel = linkLabel;
+ }
+
+ public String getLinkColor() {
+ return linkColor;
+ }
+
+ public void setLinkColor(String linkColor) {
+ this.linkColor = linkColor;
+ }
+
+ public String getLinkIcon() {
+ return linkIcon;
+ }
+
+ public void setLinkIcon(String linkIcon) {
+ this.linkIcon = linkIcon;
+ }
+
+ public String getLinkQueryHint() {
+ return linkQueryHint;
+ }
+
+ public void setLinkQueryHint(String linkQueryHint) {
+ this.linkQueryHint = linkQueryHint;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getAppDocType() {
+ return appDocType;
+ }
+}
diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/assets/AssetType.java b/streampipes-model/src/main/java/org/apache/streampipes/model/assets/AssetType.java
new file mode 100644
index 000000000..45b7151cf
--- /dev/null
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/assets/AssetType.java
@@ -0,0 +1,62 @@
+/*
+ * 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.model.assets;
+
+public class AssetType {
+
+ private String assetIcon;
+ private String assetIconColor;
+ private String assetTypeCategory;
+ private String assetTypeLabel;
+
+ public AssetType() {
+ }
+
+ public String getAssetIcon() {
+ return assetIcon;
+ }
+
+ public void setAssetIcon(String assetIcon) {
+ this.assetIcon = assetIcon;
+ }
+
+ public String getAssetIconColor() {
+ return assetIconColor;
+ }
+
+ public void setAssetIconColor(String assetIconColor) {
+ this.assetIconColor = assetIconColor;
+ }
+
+ public String getAssetTypeCategory() {
+ return assetTypeCategory;
+ }
+
+ public void setAssetTypeCategory(String assetTypeCategory) {
+ this.assetTypeCategory = assetTypeCategory;
+ }
+
+ public String getAssetTypeLabel() {
+ return assetTypeLabel;
+ }
+
+ public void setAssetTypeLabel(String assetTypeLabel) {
+ this.assetTypeLabel = assetTypeLabel;
+ }
+}
diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/assets/SpAsset.java b/streampipes-model/src/main/java/org/apache/streampipes/model/assets/SpAsset.java
new file mode 100644
index 000000000..eeee4c670
--- /dev/null
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/assets/SpAsset.java
@@ -0,0 +1,87 @@
+/*
+ * 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.model.assets;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SpAsset {
+
+ private String assetId;
+ private String assetName;
+ private String assetDescription;
+
+ private AssetType assetType;
+ private List<AssetLink> assetLinks;
+
+ private List<SpAsset> assets;
+
+ public SpAsset() {
+ this.assets = new ArrayList<>();
+ this.assetLinks = new ArrayList<>();
+ }
+
+ public String getAssetId() {
+ return assetId;
+ }
+
+ public void setAssetId(String assetId) {
+ this.assetId = assetId;
+ }
+
+ public String getAssetName() {
+ return assetName;
+ }
+
+ public void setAssetName(String assetName) {
+ this.assetName = assetName;
+ }
+
+ public String getAssetDescription() {
+ return assetDescription;
+ }
+
+ public void setAssetDescription(String assetDescription) {
+ this.assetDescription = assetDescription;
+ }
+
+ public AssetType getAssetType() {
+ return assetType;
+ }
+
+ public void setAssetType(AssetType assetType) {
+ this.assetType = assetType;
+ }
+
+ public List<AssetLink> getAssetLinks() {
+ return assetLinks;
+ }
+
+ public void setAssetLinks(List<AssetLink> assetLinks) {
+ this.assetLinks = assetLinks;
+ }
+
+ public List<SpAsset> getAssets() {
+ return assets;
+ }
+
+ public void setAssets(List<SpAsset> assets) {
+ this.assets = assets;
+ }
+}
diff --git a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IGenericStorage.java b/streampipes-model/src/main/java/org/apache/streampipes/model/assets/SpAssetModel.java
similarity index 53%
copy from streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IGenericStorage.java
copy to streampipes-model/src/main/java/org/apache/streampipes/model/assets/SpAssetModel.java
index 7855a3791..99787aa0b 100644
--- a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IGenericStorage.java
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/assets/SpAssetModel.java
@@ -16,21 +16,38 @@
*
*/
-package org.apache.streampipes.storage.api;
+package org.apache.streampipes.model.assets;
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.gson.annotations.SerializedName;
+import org.apache.streampipes.commons.constants.GenericDocTypes;
-public interface IGenericStorage {
+public class SpAssetModel extends SpAsset {
- List<Map<String, Object>> findAll(String type) throws IOException;
+ public static final String appDocType = GenericDocTypes.DOC_ASSET_MANGEMENT;
- Map<String, Object> findOne(String id) throws IOException;
+ @JsonProperty("_id")
+ private @SerializedName("_id") String id;
- Map<String, Object> create(String payload) throws IOException;
+ private boolean removable;
- Map<String, Object> update(String id, String payload) throws IOException;
+ public SpAssetModel() {
+ super();
+ }
- void delete(String id, String rev) throws IOException;
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public boolean isRemovable() {
+ return removable;
+ }
+
+ public void setRemovable(boolean removable) {
+ this.removable = removable;
+ }
}
diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/tasks/CreateAssetLinkTypeTask.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/tasks/CreateAssetLinkTypeTask.java
new file mode 100644
index 000000000..93ff1c07d
--- /dev/null
+++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/tasks/CreateAssetLinkTypeTask.java
@@ -0,0 +1,60 @@
+/*
+ * 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.manager.setup.tasks;
+
+import org.apache.streampipes.commons.exceptions.SpRuntimeException;
+import org.apache.streampipes.commons.random.UUIDGenerator;
+import org.apache.streampipes.model.assets.AssetLinkType;
+import org.apache.streampipes.storage.api.IGenericStorage;
+import org.apache.streampipes.storage.management.StorageDispatcher;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+
+public class CreateAssetLinkTypeTask implements InstallationTask {
+
+ private List<AssetLinkType> defaultLinkTypes = Arrays.asList(
+ new AssetLinkType("data-view", "Data View", "var(--color-data-view)", "search", "data-view"),
+ new AssetLinkType("dashboard", "Dashboard", "var(--color-dashboard)", "insert_chart", "dashboard"),
+ new AssetLinkType("adapter", "Adapter", "var(--color-adapter)", "power", "adapter"),
+ new AssetLinkType("data-source", "Data Source", "var(--color-data-source)", "", "data-source"),
+ new AssetLinkType("pipeline", "Pipeline", "var(--color-pipeline)", "play_arrow", "pipeline"),
+ new AssetLinkType("measurement", "Data Lake Storage", "var(--color-measurement", "", "measurement")
+ );
+
+ @Override
+ public void execute() {
+ var genericStorage = getGenericStorage();
+
+ this.defaultLinkTypes.forEach(link -> {
+ try {
+ link.setId(UUIDGenerator.generateUuid());
+ genericStorage.create(link, AssetLinkType.class);
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new SpRuntimeException("Could not create asset link document");
+ }
+ });
+ }
+
+ private IGenericStorage getGenericStorage() {
+ return StorageDispatcher.INSTANCE.getNoSqlStore().getGenericStorage();
+ }
+}
diff --git a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IGenericStorage.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/tasks/CreateDefaultAssetTask.java
similarity index 53%
copy from streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IGenericStorage.java
copy to streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/tasks/CreateDefaultAssetTask.java
index 7855a3791..9293592f6 100644
--- a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IGenericStorage.java
+++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/tasks/CreateDefaultAssetTask.java
@@ -16,21 +16,28 @@
*
*/
-package org.apache.streampipes.storage.api;
+package org.apache.streampipes.manager.setup.tasks;
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-
-public interface IGenericStorage {
-
- List<Map<String, Object>> findAll(String type) throws IOException;
+import org.apache.streampipes.commons.constants.GenericDocTypes;
+import org.apache.streampipes.model.assets.SpAssetModel;
+import org.apache.streampipes.storage.management.StorageDispatcher;
- Map<String, Object> findOne(String id) throws IOException;
-
- Map<String, Object> create(String payload) throws IOException;
-
- Map<String, Object> update(String id, String payload) throws IOException;
+import java.io.IOException;
- void delete(String id, String rev) throws IOException;
+public class CreateDefaultAssetTask implements InstallationTask {
+
+ @Override
+ public void execute() {
+ var asset = new SpAssetModel();
+ asset.setId(GenericDocTypes.DEFAULT_ASSET_DOC_ID);
+ asset.setAssetId("default-asset");
+ asset.setAssetName("Default Asset");
+ asset.setRemovable(true);
+
+ try {
+ StorageDispatcher.INSTANCE.getNoSqlStore().getGenericStorage().create(asset, SpAssetModel.class);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
}
diff --git a/ui/src/app/assets/constants/asset.constants.ts b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/tasks/InstallationTask.java
similarity index 88%
copy from ui/src/app/assets/constants/asset.constants.ts
copy to streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/tasks/InstallationTask.java
index c0bcb1988..39ec0f1cb 100644
--- a/ui/src/app/assets/constants/asset.constants.ts
+++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/setup/tasks/InstallationTask.java
@@ -16,7 +16,9 @@
*
*/
-export class AssetConstants {
+package org.apache.streampipes.manager.setup.tasks;
- public static ASSET_APP_DOC_NAME = 'asset-management';
+public interface InstallationTask {
+
+ void execute();
}
diff --git a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IGenericStorage.java b/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IGenericStorage.java
index 7855a3791..b74bbc5b3 100644
--- a/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IGenericStorage.java
+++ b/streampipes-storage-api/src/main/java/org/apache/streampipes/storage/api/IGenericStorage.java
@@ -30,6 +30,8 @@ public interface IGenericStorage {
Map<String, Object> create(String payload) throws IOException;
+ <T> T create(T payload, Class<T> targetClass) throws IOException;
+
Map<String, Object> update(String id, String payload) throws IOException;
void delete(String id, String rev) throws IOException;
diff --git a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/GenericStorageImpl.java b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/GenericStorageImpl.java
index afa3210b4..27606dd9c 100644
--- a/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/GenericStorageImpl.java
+++ b/streampipes-storage-couchdb/src/main/java/org/apache/streampipes/storage/couchdb/impl/GenericStorageImpl.java
@@ -20,6 +20,7 @@ package org.apache.streampipes.storage.couchdb.impl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.net.UrlEscapers;
import org.apache.http.client.fluent.Content;
@@ -44,6 +45,7 @@ public class GenericStorageImpl implements IGenericStorage {
public GenericStorageImpl() {
this.mapper = new ObjectMapper();
+ this.mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
@Override
@@ -77,6 +79,12 @@ public class GenericStorageImpl implements IGenericStorage {
return this.findOne((String) requestResult.get(ID));
}
+ @Override
+ public <T> T create(T payload, Class<T> targetClass) throws IOException {
+ Map<String, Object> result = this.create(this.mapper.writeValueAsString(payload));
+ return this.mapper.convertValue(result, targetClass);
+ }
+
@Override
public Map<String, Object> update(String id, String payload) throws IOException {
Request req = Utils.putRequest(getDatabaseRoute() + SLASH + id, payload);
diff --git a/ui/projects/streampipes/platform-services/src/lib/model/assets/asset.model.ts b/ui/projects/streampipes/platform-services/src/lib/model/assets/asset.model.ts
index 59e849dcc..6cb191a10 100644
--- a/ui/projects/streampipes/platform-services/src/lib/model/assets/asset.model.ts
+++ b/ui/projects/streampipes/platform-services/src/lib/model/assets/asset.model.ts
@@ -16,6 +16,14 @@
*
*/
+export interface AssetLinkType {
+ linkType: string;
+ linkLabel: string;
+ linkColor: string;
+ linkIcon?: string;
+ linkQueryHint?: string;
+}
+
export interface AssetType {
assetIcon: string;
assetIconColor: string;
@@ -25,7 +33,7 @@ export interface AssetType {
export interface AssetLink {
resourceId: string;
- linkType: 'data-view' | 'dashboard' | 'adapter' | 'stream' | string;
+ linkType: 'data-view' | 'dashboard' | 'adapter' | 'source' | string;
linkLabel: string;
editingDisabled: boolean;
}
@@ -45,6 +53,8 @@ export interface SpAssetModel extends SpAsset {
_id: string;
_rev: string;
+ appDocType: string;
+
removable: boolean;
}
diff --git a/ui/src/app/assets/assets.module.ts b/ui/src/app/assets/assets.module.ts
index f66dce7fe..3bcaa5d4c 100644
--- a/ui/src/app/assets/assets.module.ts
+++ b/ui/src/app/assets/assets.module.ts
@@ -40,6 +40,8 @@ import { SpAssetDetailsComponent } from './components/asset-details/asset-detail
import { SpAssetSelectionPanelComponent } from './components/asset-details/asset-selection-panel/asset-selection-panel.component';
import { SpAssetDetailsPanelComponent } from './components/asset-details/asset-details-panel/asset-details-panel.component';
import { MatTreeModule } from '@angular/material/tree';
+import { SpAssetLinkItemComponent } from './components/asset-details/asset-details-panel/asset-link-item/asset-link-item.component';
+import { EditAssetLinkDialogComponent } from './dialog/edit-asset-link/edit-asset-link-dialog.component';
@NgModule({
imports: [
@@ -84,8 +86,10 @@ import { MatTreeModule } from '@angular/material/tree';
],
declarations: [
AssetUploadDialogComponent,
+ EditAssetLinkDialogComponent,
SpAssetDetailsComponent,
SpAssetDetailsPanelComponent,
+ SpAssetLinkItemComponent,
SpAssetOverviewComponent,
SpAssetSelectionPanelComponent,
],
diff --git a/ui/src/app/assets/components/asset-details/asset-details-panel/asset-details-panel.component.html b/ui/src/app/assets/components/asset-details/asset-details-panel/asset-details-panel.component.html
index c14309519..65beaa635 100644
--- a/ui/src/app/assets/components/asset-details/asset-details-panel/asset-details-panel.component.html
+++ b/ui/src/app/assets/components/asset-details/asset-details-panel/asset-details-panel.component.html
@@ -21,18 +21,37 @@
<sp-basic-inner-panel panelTitle="Basics" outerMargin="20px 0px">
<div fxLayout="column" fxFlex="100">
- <div>Name: {{asset.assetName}}</div>
- <div>Description: {{asset.assetDescription}}</div>
+ <mat-form-field color="accent">
+ <mat-label>Name</mat-label>
+ <input matInput [(ngModel)]="asset.assetName" [disabled]="!editMode">
+ </mat-form-field>
+ <mat-form-field color="accent">
+ <mat-label>Description</mat-label>
+ <input matInput [(ngModel)]="asset.assetDescription" [disabled]="!editMode">
+ </mat-form-field>
+ <mat-form-field color="accent">
+ <mat-label>ID</mat-label>
+ <input matInput [(ngModel)]="asset.assetId" [disabled]="!editMode">
+ </mat-form-field>
</div>
</sp-basic-inner-panel>
- <sp-basic-inner-panel panelTitle="Asset Links" outerMargin="20px 0px">
- <div fxLayout="column" fxFlex="100">
- <div fxLayout="column" *ngFor="let link of asset.assetLinks">
- <div>ResourceId: {{link.resourceId}}</div>
- <div>Label: {{link.linkLabel}}</div>
- <div>Link Type: {{link.linkType}}</div>
+ <sp-basic-inner-panel panelTitle="Asset Links" outerMargin="0px 0px">
+ <div header fxLayoutAlign="end center" fxLayout="row" fxFlex="100">
+ <button mat-button color="accent" *ngIf="editMode" (click)="openCreateAssetLinkDialog()"><i class="material-icons">add</i><span> Add link</span></button>
+ </div>
+ <div fxLayout="column" fxFlex="100" *ngIf="assetLinkTypes">
+ <div fxLayout="column" *ngFor="let link of asset.assetLinks; let i = index">
+ <sp-asset-link-item-component [assetLink]="link"
+ [assetLinkIndex]="i"
+ [assetLinkTypes]="assetLinkTypes"
+ [editMode]="editMode"
+ (openEditAssetLinkEmitter)="openEditAssetLinkDialog($event.assetLink, $event.index, false)"
+ (deleteAssetLinkEmitter)="deleteAssetLink($event)"
+ class="asset-link-item">
+ </sp-asset-link-item-component>
+
</div>
</div>
</sp-basic-inner-panel>
diff --git a/ui/src/app/assets/components/asset-details/asset-details-panel/asset-details-panel.component.scss b/ui/src/app/assets/components/asset-details/asset-details-panel/asset-details-panel.component.scss
index 13cbc4aac..1dba0de23 100644
--- a/ui/src/app/assets/components/asset-details/asset-details-panel/asset-details-panel.component.scss
+++ b/ui/src/app/assets/components/asset-details/asset-details-panel/asset-details-panel.component.scss
@@ -15,3 +15,16 @@
* limitations under the License.
*
*/
+
+.asset-link-item:nth-child(odd) {
+ background: var(--color-bg-1);
+}
+
+.asset-link-item:nth-child(even) {
+ background: var(--color-bg-1);
+}
+
+.asset-link-item {
+ border-bottom: 1px solid var(--color-bg-3);
+ padding: 10px;
+}
diff --git a/ui/src/app/assets/components/asset-details/asset-details-panel/asset-details-panel.component.ts b/ui/src/app/assets/components/asset-details/asset-details-panel/asset-details-panel.component.ts
index ae668bc2d..d257342ae 100644
--- a/ui/src/app/assets/components/asset-details/asset-details-panel/asset-details-panel.component.ts
+++ b/ui/src/app/assets/components/asset-details/asset-details-panel/asset-details-panel.component.ts
@@ -1,5 +1,27 @@
-import { Component, Input, OnInit } from '@angular/core';
-import { SpAsset } from '@streampipes/platform-services';
+/*
+ * 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, EventEmitter, Input, OnInit, Output } from '@angular/core';
+import { AssetLink, AssetLinkType, GenericStorageService, SpAsset } from '@streampipes/platform-services';
+import { AssetConstants } from '../../../constants/asset.constants';
+import { AssetUploadDialogComponent } from '../../../dialog/asset-upload/asset-upload-dialog.component';
+import { DialogService, PanelType } from '../../../../../../dist/streampipes/shared-ui';
+import { EditAssetLinkDialogComponent } from '../../../dialog/edit-asset-link/edit-asset-link-dialog.component';
@Component({
@@ -12,7 +34,57 @@ export class SpAssetDetailsPanelComponent implements OnInit {
@Input()
asset: SpAsset;
+ @Input()
+ editMode: boolean;
+
+ @Output()
+ updateAssetEmitter: EventEmitter<SpAsset> = new EventEmitter<SpAsset>();
+
+ assetLinkTypes: AssetLinkType[];
+
+ constructor(private genericStorageService: GenericStorageService,
+ private dialogService: DialogService) {
+
+ }
+
ngOnInit(): void {
+ this.genericStorageService.getAllDocuments(AssetConstants.ASSET_LINK_TYPES_DOC_NAME).subscribe(assetLinkTypes => {
+ this.assetLinkTypes = assetLinkTypes;
+ });
+ }
+
+ openEditAssetLinkDialog(assetLink: AssetLink, index: number, createMode: boolean): void {
+ const dialogRef = this.dialogService.open(EditAssetLinkDialogComponent, {
+ panelType: PanelType.SLIDE_IN_PANEL,
+ title: createMode ? 'Create ' : 'Update ' + 'asset model',
+ width: '50vw',
+ data: {
+ 'assetLink': assetLink,
+ 'assetLinkTypes': this.assetLinkTypes,
+ 'createMode': createMode
+ }
+ });
+
+ dialogRef.afterClosed().subscribe(storedLink => {
+ if (storedLink) {
+ if (index > -1) {
+ this.asset.assetLinks[index] = storedLink;
+ } else {
+ this.asset.assetLinks.push(storedLink);
+ }
+ this.updateAssetEmitter.emit(this.asset);
+ }
+ });
+ }
+
+ openCreateAssetLinkDialog(): void {
+ const assetLink: AssetLink = {linkLabel: '', linkType: 'data-view', editingDisabled: false, resourceId: ''};
+ this.openEditAssetLinkDialog(assetLink, -1, true);
+ }
+
+ deleteAssetLink(index: number): void {
+ this.asset.assetLinks = this.asset.assetLinks.splice(index, 1);
+ this.updateAssetEmitter.emit(this.asset);
}
}
diff --git a/ui/src/app/assets/components/asset-details/asset-details-panel/asset-link-item/asset-link-item.component.html b/ui/src/app/assets/components/asset-details/asset-details-panel/asset-link-item/asset-link-item.component.html
new file mode 100644
index 000000000..3ca2204c3
--- /dev/null
+++ b/ui/src/app/assets/components/asset-details/asset-details-panel/asset-link-item/asset-link-item.component.html
@@ -0,0 +1,30 @@
+<!--
+ ~ 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 fxFlex="100" fxLayout="column">
+ <div fxLayout="row" fxLayoutGap="10px">
+ <div fxLayoutAlign="start center"><span class="link-label">{{assetLink.linkLabel}}</span></div>
+ <div fxLayoutAlign="start center"><span class="link-type" [ngStyle]="{'background': currentAssetLinkType.linkColor}">{{assetLink.linkType}}</span></div>
+ <div fxFlex></div>
+ <div fxLayoutAlign="end center">
+ <button mat-button mat-icon-button color="accent" (click)="openLink()"><i class="material-icons">link</i></button>
+ <button mat-button mat-icon-button color="accent" (click)="editLink()" *ngIf="editMode"><i class="material-icons">edit</i></button>
+ <button mat-button mat-icon-button color="accent" (click)="deleteLink()" *ngIf="editMode"><i class="material-icons">delete</i></button>
+ </div>
+ </div>
+</div>
diff --git a/ui/src/app/assets/constants/asset.constants.ts b/ui/src/app/assets/components/asset-details/asset-details-panel/asset-link-item/asset-link-item.component.scss
similarity index 84%
copy from ui/src/app/assets/constants/asset.constants.ts
copy to ui/src/app/assets/components/asset-details/asset-details-panel/asset-link-item/asset-link-item.component.scss
index c0bcb1988..8e80a29ae 100644
--- a/ui/src/app/assets/constants/asset.constants.ts
+++ b/ui/src/app/assets/components/asset-details/asset-details-panel/asset-link-item/asset-link-item.component.scss
@@ -16,7 +16,13 @@
*
*/
-export class AssetConstants {
+.link-type {
+ background: var(--color-primary);
+ padding: 5px;
+ border-radius: 5px;
+}
- public static ASSET_APP_DOC_NAME = 'asset-management';
+.link-label {
+ margin-right: 15px;
+ font-weight: 500;
}
diff --git a/ui/src/app/assets/components/asset-details/asset-details-panel/asset-link-item/asset-link-item.component.ts b/ui/src/app/assets/components/asset-details/asset-details-panel/asset-link-item/asset-link-item.component.ts
new file mode 100644
index 000000000..c012491fe
--- /dev/null
+++ b/ui/src/app/assets/components/asset-details/asset-details-panel/asset-link-item/asset-link-item.component.ts
@@ -0,0 +1,68 @@
+/*
+ * 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, EventEmitter, Input, OnInit, Output } from '@angular/core';
+import { AssetLink, AssetLinkType } from '@streampipes/platform-services';
+
+@Component({
+ selector: 'sp-asset-link-item-component',
+ templateUrl: './asset-link-item.component.html',
+ styleUrls: ['./asset-link-item.component.scss']
+})
+export class SpAssetLinkItemComponent implements OnInit {
+
+ @Input()
+ assetLink: AssetLink;
+
+ @Input()
+ assetLinkIndex: number;
+
+ @Input()
+ assetLinkTypes: AssetLinkType[];
+
+ @Input()
+ editMode: boolean;
+
+ @Output()
+ openEditAssetLinkEmitter: EventEmitter<{assetLink: AssetLink, index: number}> = new EventEmitter<{assetLink: AssetLink, index: number}>();
+
+ @Output()
+ deleteAssetLinkEmitter: EventEmitter<number> = new EventEmitter<number>();
+
+ currentAssetLinkType: AssetLinkType;
+
+ ngOnInit(): void {
+ console.log(this.assetLinkTypes);
+ console.log(this.assetLink);
+ this.currentAssetLinkType = this.assetLinkTypes.find(t => t.linkType === this.assetLink.linkType);
+ console.log(this.currentAssetLinkType);
+ }
+
+ openLink(): void {
+
+ }
+
+ editLink(): void {
+ this.openEditAssetLinkEmitter.emit({assetLink: this.assetLink, index: this.assetLinkIndex});
+ }
+
+ deleteLink(): void {
+ this.deleteAssetLinkEmitter.emit(this.assetLinkIndex);
+ }
+}
diff --git a/ui/src/app/assets/components/asset-details/asset-details.component.html b/ui/src/app/assets/components/asset-details/asset-details.component.html
index ce7849c72..4f22df2b4 100644
--- a/ui/src/app/assets/components/asset-details/asset-details.component.html
+++ b/ui/src/app/assets/components/asset-details/asset-details.component.html
@@ -15,10 +15,16 @@
~ limitations under the License.
~
-->
-<sp-basic-view [showBackLink]="true" [backLinkTarget]="['assets']" [padding]="false">
+<sp-basic-view [showBackLink]="true"
+ [backLinkTarget]="['assets']"
+ [padding]="false">
<div nav fxFlex="100" fxLayoutAlign="start center" fxLayout="row" class="pl-10">
-
+ <div fxLayout="row" fxLayoutAlign="start center" *ngIf="editMode">
+ <button mat-button mat-raised-button color="accent" (click)="updateAsset()">
+ <i class="material-icons">add</i><span> Save</span>
+ </button>
+ </div>
<div fxFlex fxLayout="row" fxLayoutAlign="end center">
</div>
@@ -33,6 +39,7 @@
<div fxLayout="column" fxFlex="100">
<sp-asset-selection-panel-component
[assetModel]="asset"
+ [selectedAsset]="selectedAsset"
(selectedAssetEmitter)="selectedAsset = $event">
</sp-asset-selection-panel-component>
</div>
@@ -41,6 +48,8 @@
<sp-asset-details-panel-component
*ngIf="selectedAsset"
[asset]="selectedAsset"
+ [editMode]="editMode"
+ (updateAssetEmitter)="updateAsset()"
fxFlex="100"
fxLayout="row">
diff --git a/ui/src/app/assets/components/asset-details/asset-details.component.ts b/ui/src/app/assets/components/asset-details/asset-details.component.ts
index 7cb5869bd..fc890dd88 100644
--- a/ui/src/app/assets/components/asset-details/asset-details.component.ts
+++ b/ui/src/app/assets/components/asset-details/asset-details.component.ts
@@ -1,3 +1,21 @@
+/*
+ * 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 { SpBreadcrumbService } from '@streampipes/shared-ui';
import { ActivatedRoute } from '@angular/router';
@@ -16,6 +34,10 @@ export class SpAssetDetailsComponent implements OnInit {
selectedAsset: SpAsset;
+ editMode: boolean;
+
+ assetModelId: string;
+
constructor(private breadcrumbService: SpBreadcrumbService,
private genericStorageService: GenericStorageService,
private route: ActivatedRoute) {
@@ -23,15 +45,22 @@ export class SpAssetDetailsComponent implements OnInit {
}
ngOnInit(): void {
- const assetId = this.route.snapshot.params.assetId;
- this.loadAsset(assetId);
+ this.assetModelId = this.route.snapshot.params.assetId;
+ this.editMode = this.route.snapshot.queryParams.editMode;
+ this.loadAsset();
}
- loadAsset(assetId: string): void {
- this.genericStorageService.getDocument(AssetConstants.ASSET_APP_DOC_NAME, assetId).subscribe(asset => {
+ loadAsset(): void {
+ this.genericStorageService.getDocument(AssetConstants.ASSET_APP_DOC_NAME, this.assetModelId).subscribe(asset => {
this.asset = asset;
+ this.selectedAsset = this.asset;
this.breadcrumbService.updateBreadcrumb([SpAssetRoutes.BASE, {label: this.asset.assetName}]);
- console.log(this.asset);
+ });
+ }
+
+ updateAsset() {
+ this.genericStorageService.updateDocument(AssetConstants.ASSET_APP_DOC_NAME, this.asset).subscribe(res => {
+ this.loadAsset();
});
}
}
diff --git a/ui/src/app/assets/components/asset-details/asset-selection-panel/asset-selection-panel.component.html b/ui/src/app/assets/components/asset-details/asset-selection-panel/asset-selection-panel.component.html
index 66eb05ca6..096968753 100644
--- a/ui/src/app/assets/components/asset-details/asset-selection-panel/asset-selection-panel.component.html
+++ b/ui/src/app/assets/components/asset-details/asset-selection-panel/asset-selection-panel.component.html
@@ -25,9 +25,11 @@
</div>
<div fxFlex="100" fxLayout="column">
<div fxFlex fxLayout="column" class="designer-panel-config">
- <mat-tree [dataSource]="dataSource" [treeControl]="treeControl" class="sp-tree">
+ <mat-tree [dataSource]="dataSource" [treeControl]="treeControl" class="sp-tree" #tree>
<mat-tree-node *matTreeNodeDef="let node" matTreeNodeToggle>
+ <div [ngClass]="node.assetId === selectedAsset.assetId ? 'asset-node selected-node' : 'asset-node'">
<span (click)="selectNode(node)">{{node.assetName}}</span>
+ </div>
</mat-tree-node>
<mat-nested-tree-node *matTreeNodeDef="let node; when: hasChild">
<div class="mat-tree-node">
@@ -38,7 +40,9 @@
{{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}
</mat-icon>
</button>
+ <div [ngClass]="node.assetId === selectedAsset.assetId ? 'asset-node selected-node' : 'asset-node'">
<span (click)="selectNode(node)">{{node.assetName}}</span>
+ </div>
</div>
<div [class.sp-tree-invisible]="!treeControl.isExpanded(node)"
role="group">
diff --git a/ui/src/app/assets/components/asset-details/asset-selection-panel/asset-selection-panel.component.scss b/ui/src/app/assets/components/asset-details/asset-selection-panel/asset-selection-panel.component.scss
index 0435c97d6..d277317df 100644
--- a/ui/src/app/assets/components/asset-details/asset-selection-panel/asset-selection-panel.component.scss
+++ b/ui/src/app/assets/components/asset-details/asset-selection-panel/asset-selection-panel.component.scss
@@ -45,9 +45,20 @@
}
.sp-tree .mat-nested-tree-node div[role=group] {
- padding-left: 40px;
+ padding-left: 20px;
}
.sp-tree div[role=group] > .mat-tree-node {
- padding-left: 40px;
+ padding-left: 20px;
+}
+
+.asset-node {
+ font-weight: normal;
+ cursor: pointer;
+ font-size: 13pt;
+}
+
+.selected-node {
+ font-weight: bold;
+ border-bottom: 4px solid var(--color-primary);
}
diff --git a/ui/src/app/assets/components/asset-details/asset-selection-panel/asset-selection-panel.component.ts b/ui/src/app/assets/components/asset-details/asset-selection-panel/asset-selection-panel.component.ts
index ad0c81692..da01568a6 100644
--- a/ui/src/app/assets/components/asset-details/asset-selection-panel/asset-selection-panel.component.ts
+++ b/ui/src/app/assets/components/asset-details/asset-selection-panel/asset-selection-panel.component.ts
@@ -1,4 +1,22 @@
-import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
+/*
+ * 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 { AfterViewInit, Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
import { SpAsset, SpAssetModel } from '@streampipes/platform-services';
import { NestedTreeControl } from '@angular/cdk/tree';
import { MatTreeNestedDataSource } from '@angular/material/tree';
@@ -13,18 +31,25 @@ export class SpAssetSelectionPanelComponent implements OnInit {
@Input()
assetModel: SpAssetModel;
+ @Input()
+ selectedAsset: SpAsset;
+
@Output()
selectedAssetEmitter: EventEmitter<SpAsset> = new EventEmitter<SpAsset>();
treeControl = new NestedTreeControl<SpAsset>(node => node.assets);
dataSource = new MatTreeNestedDataSource<SpAsset>();
+ @ViewChild('tree') tree;
+
hasChild = (_: number, node: SpAsset) => !!node.assets && node.assets.length > 0;
ngOnInit(): void {
this.treeControl = new NestedTreeControl<SpAsset>(node => node.assets);
this.dataSource = new MatTreeNestedDataSource<SpAsset>();
this.dataSource.data = [this.assetModel];
+ this.treeControl.dataNodes = [this.assetModel];
+ this.treeControl.expandAll();
}
selectNode(asset: SpAsset) {
diff --git a/ui/src/app/assets/components/asset-overview/asset-overview.component.html b/ui/src/app/assets/components/asset-overview/asset-overview.component.html
index 60c86d681..1d7c31e5c 100644
--- a/ui/src/app/assets/components/asset-overview/asset-overview.component.html
+++ b/ui/src/app/assets/components/asset-overview/asset-overview.component.html
@@ -68,18 +68,24 @@
<td mat-cell *matCellDef="let asset">
<div fxLayout="row">
<span fxFlex fxFlexOrder="1" fxLayout="row" fxLayoutAlign="center center">
- <button color="accent" mat-button mat-icon-button matTooltip="Show info"
- matTooltipPosition="above" (click)="goToDetailsView(asset)"><i
- class="material-icons">search</i>
- </button>
- </span>
- <span fxFlex fxFlexOrder="2" fxLayout="row" fxLayoutAlign="center center">
+ <button color="accent" mat-button mat-icon-button matTooltip="Show info"
+ matTooltipPosition="above" (click)="goToDetailsView(asset)"><i
+ class="material-icons">search</i>
+ </button>
+ </span>
+ <span fxFlex fxFlexOrder="2" fxLayout="row" fxLayoutAlign="center center">
+ <button color="accent" mat-button mat-icon-button matTooltip="Show info"
+ matTooltipPosition="above" (click)="goToDetailsView(asset, true)"><i
+ class="material-icons">edit</i>
+ </button>
+ </span>
+ <span fxFlex fxFlexOrder="3" fxLayout="row" fxLayoutAlign="center center">
<!-- <button color="accent" mat-button mat-icon-button matTooltip="Manage permissions"-->
<!-- matTooltipPosition="above" (click)="showPermissionsDialog(adapter)"><i-->
<!-- class="material-icons">share</i>-->
<!-- </button>-->
</span>
- <span fxFlex fxFlexOrder="3" fxLayout="row" fxLayoutAlign="center center">
+ <span fxFlex fxFlexOrder="4" fxLayout="row" fxLayoutAlign="center center">
<button color="accent" mat-button mat-icon-button matTooltip="Delete adapter"
data-cy="delete" matTooltipPosition="above" (click)="deleteAsset(asset)">
<i class="material-icons">delete</i>
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 225a0a9cd..1d6037ad0 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
@@ -75,8 +75,13 @@ export class SpAssetOverviewComponent implements OnInit {
});
}
- goToDetailsView(asset: SpAssetModel) {
- this.router.navigate(['assets', 'details', asset._id]);
+ goToDetailsView(asset: SpAssetModel,
+ editMode = false) {
+ if (!editMode) {
+ this.router.navigate(['assets', 'details', asset._id]);
+ } else {
+ this.router.navigate(['assets', 'details', asset._id], {queryParams: {'editMode': editMode}});
+ }
}
deleteAsset(asset: SpAssetModel) {
diff --git a/ui/src/app/assets/constants/asset.constants.ts b/ui/src/app/assets/constants/asset.constants.ts
index c0bcb1988..ee412ee6b 100644
--- a/ui/src/app/assets/constants/asset.constants.ts
+++ b/ui/src/app/assets/constants/asset.constants.ts
@@ -19,4 +19,5 @@
export class AssetConstants {
public static ASSET_APP_DOC_NAME = 'asset-management';
+ public static ASSET_LINK_TYPES_DOC_NAME = 'asset-link-type';
}
diff --git a/ui/src/app/assets/dialog/edit-asset-link/edit-asset-link-dialog.component.html b/ui/src/app/assets/dialog/edit-asset-link/edit-asset-link-dialog.component.html
new file mode 100644
index 000000000..5fe1e927c
--- /dev/null
+++ b/ui/src/app/assets/dialog/edit-asset-link/edit-asset-link-dialog.component.html
@@ -0,0 +1,76 @@
+<!--
+~ 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">
+ <div fxFlex="100" fxLayout="column" *ngIf="clonedAssetLink">
+ <div fxFlex style="margin:5px;width:100%" fxLayout="column">
+ <mat-form-field color="accent">
+ <mat-label>Link Type</mat-label>
+ <mat-select fxFlex [(ngModel)]="clonedAssetLink.linkType"
+ required (selectionChange)="onLinkTypeChanged($event)">
+ <mat-option *ngFor="let assetLinkType of assetLinkTypes"
+ [value]="assetLinkType.linkType">{{assetLinkType.linkLabel}}</mat-option>
+ </mat-select>
+ </mat-form-field>
+ </div>
+ <div *ngIf="selectedLinkType === 'pipeline'" fxLayout="column">
+ <mat-form-field color="accent" fxFlex="100">
+ <mat-label>Pipelines</mat-label>
+ <mat-select [(ngModel)]="clonedAssetLink.resourceId" fxFlex
+ required>
+ <mat-option *ngFor="let pipeline of pipelines"
+ [value]="pipeline._id">{{pipeline.name}}</mat-option>
+ </mat-select>
+ </mat-form-field>
+ </div>
+ <div *ngIf="selectedLinkType === 'data-view'" fxLayout="column">
+ <mat-form-field color="accent" fxFlex="100">
+ <mat-label>Data Views</mat-label>
+ <mat-select [(ngModel)]="clonedAssetLink.resourceId" fxFlex
+ required>
+ <mat-option *ngFor="let dataView of dataViews"
+ [value]="dataView._id">{{dataView.name}}</mat-option>
+ </mat-select>
+ </mat-form-field>
+ </div>
+ <div fxFlex="100" fxLayout="column">
+ <mat-form-field color="accent">
+ <mat-label>Resource ID</mat-label>
+ <input matInput [(ngModel)]="clonedAssetLink.resourceId" required [disabled]="true">
+ </mat-form-field>
+ </div>
+ <div fxFlex="100">
+
+ </div>
+ </div>
+ </div>
+ <mat-divider></mat-divider>
+ <div class="sp-dialog-actions">
+ <button mat-button
+ mat-raised-button
+ color="accent"
+ (click)="store()" data-cy="sp-file-management-store-file" style="margin-right:10px;">
+ {{createMode ? 'Create ' : 'Update' }} link
+ </button>
+ <button mat-button mat-raised-button class="mat-basic" (click)="cancel()" style="margin-right:10px;">
+ Cancel
+ </button>
+ </div>
+</div>
diff --git a/ui/src/app/assets/components/asset-details/asset-details-panel/asset-details-panel.component.scss b/ui/src/app/assets/dialog/edit-asset-link/edit-asset-link-dialog.component.scss
similarity index 95%
copy from ui/src/app/assets/components/asset-details/asset-details-panel/asset-details-panel.component.scss
copy to ui/src/app/assets/dialog/edit-asset-link/edit-asset-link-dialog.component.scss
index 13cbc4aac..704f843e4 100644
--- a/ui/src/app/assets/components/asset-details/asset-details-panel/asset-details-panel.component.scss
+++ b/ui/src/app/assets/dialog/edit-asset-link/edit-asset-link-dialog.component.scss
@@ -15,3 +15,5 @@
* limitations under the License.
*
*/
+
+@import 'src/scss/sp/sp-dialog';
diff --git a/ui/src/app/assets/dialog/edit-asset-link/edit-asset-link-dialog.component.ts b/ui/src/app/assets/dialog/edit-asset-link/edit-asset-link-dialog.component.ts
new file mode 100644
index 000000000..e94f3ea0c
--- /dev/null
+++ b/ui/src/app/assets/dialog/edit-asset-link/edit-asset-link-dialog.component.ts
@@ -0,0 +1,104 @@
+/*
+ * 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, OnInit } from '@angular/core';
+import { DialogRef } from '@streampipes/shared-ui';
+import {
+ AssetLink,
+ AssetLinkType, Dashboard, DashboardService,
+ DataViewDataExplorerService,
+ GenericStorageService, Pipeline,
+ PipelineService
+} from '@streampipes/platform-services';
+import { AssetConstants } from '../../constants/asset.constants';
+import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
+import { zip } from 'rxjs';
+import { MatSelectChange } from '@angular/material/select';
+
+@Component({
+ selector: 'sp-edit-asset-link-dialog-component',
+ templateUrl: './edit-asset-link-dialog.component.html',
+ styleUrls: ['./edit-asset-link-dialog.component.scss']
+})
+export class EditAssetLinkDialogComponent implements OnInit {
+
+ @Input()
+ assetLink: AssetLink;
+
+ @Input()
+ assetLinkTypes: AssetLinkType[];
+
+ @Input()
+ createMode: boolean;
+
+ parentForm: FormGroup;
+
+ clonedAssetLink: AssetLink;
+
+ // Resources
+ pipelines: Pipeline[];
+ dataViews: Dashboard[];
+ dashboards: Dashboard[];
+
+ selectedLinkType: string;
+
+ constructor(private dialogRef: DialogRef<EditAssetLinkDialogComponent>,
+ private genericStorageService: GenericStorageService,
+ private pipelineService: PipelineService,
+ private dataViewService: DataViewDataExplorerService,
+ private dashboardService: DashboardService) {
+ }
+
+ ngOnInit(): void {
+ this.getAllResources();
+ this.clonedAssetLink = {...this.assetLink};
+ }
+
+ getCurrAssetLinkType(): AssetLinkType {
+ if (this.createMode) {
+ return this.assetLinkTypes[0];
+ } else {
+ return this.assetLinkTypes.find(a => a.linkType === this.assetLink.linkType);
+ }
+ }
+
+ store() {
+ this.assetLink = this.clonedAssetLink;
+ this.dialogRef.close(this.assetLink);
+ }
+
+ cancel() {
+ this.dialogRef.close();
+ }
+
+ getAllResources() {
+ zip(
+ this.pipelineService.getOwnPipelines(),
+ this.dataViewService.getDataViews(),
+ this.dashboardService.getDashboards()).subscribe(response => {
+ this.pipelines = response[0];
+ this.dataViews = response[1];
+ this.dashboards = response[2];
+ });
+ }
+
+ onLinkTypeChanged(event: MatSelectChange): void {
+ this.selectedLinkType = event.value;
+ }
+
+}