From dfdcd612e0239f71f6583a4b4cfa5f24fd094bf2 Mon Sep 17 00:00:00 2001 From: Bastian Weltjen Date: Tue, 17 Aug 2021 10:21:48 +0200 Subject: [PATCH 01/13] docs: readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b12fb329..63915071 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ sudo docker-compose up ``` Access: [localhost:8083](http://localhost:8083) -### Change host/port & authentification of Dataspace Connector & UI backend on docker start +### Change host/port & authentification of Dataspace Connector on docker start Change in `docker-compose.yml`: ```bash From b196c2635a6d6d85886c58ebaff52bc0f8761d89 Mon Sep 17 00:00:00 2001 From: Bastian Weltjen Date: Tue, 17 Aug 2021 15:50:04 +0200 Subject: [PATCH 02/13] fix[data consumption]: provider connector URL does not need "api/ids/data" endpoint chore[data consumption]: rename "receive resources" to "request resource" --- src/components/infobox/InfoBox.html | 6 ++++++ src/pages/PageStructure.js | 4 ++-- .../dataconsumption/IDSDataConsumptionPage.js | 14 +++++++------- .../resources/IDSResourcesPageConsumption.html | 4 ++-- src/utils/validationUtils.js | 7 ------- 5 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/components/infobox/InfoBox.html b/src/components/infobox/InfoBox.html index 51516914..9f64fc6c 100644 --- a/src/components/infobox/InfoBox.html +++ b/src/components/infobox/InfoBox.html @@ -82,4 +82,10 @@ General settings of the DataSpaceConnector. + + + Request an IDS resource from the given connector URL.
+ When requesting a Dataspace Connector the "/api/ids/data" endpoint should be used. +
+
\ No newline at end of file diff --git a/src/pages/PageStructure.js b/src/pages/PageStructure.js index d40f7069..22156721 100644 --- a/src/pages/PageStructure.js +++ b/src/pages/PageStructure.js @@ -69,8 +69,8 @@ export default { name: "IDS Resources (Consumption)", component: IDSResourcesPageConsumption, subpages: [{ - path: "receiveresourcesconsumption", - name: "Receive Resources (Consumption)", + path: "requestresourceconsumption", + name: "Request Resource (Consumption)", component: IDSDataConsumptionPage, subpages: [] }, { diff --git a/src/pages/dataconsumption/dataconsumption/IDSDataConsumptionPage.js b/src/pages/dataconsumption/dataconsumption/IDSDataConsumptionPage.js index e55ae0bc..006315c6 100644 --- a/src/pages/dataconsumption/dataconsumption/IDSDataConsumptionPage.js +++ b/src/pages/dataconsumption/dataconsumption/IDSDataConsumptionPage.js @@ -28,7 +28,7 @@ export default { downloadLink: "", dialog: false, valid: false, - providerUrlRule: validationUtils.getProviderUrlRequiredRule(), + providerUrlRule: validationUtils.getUrlRequiredRule(), headers: [{ text: 'Creation date', value: 'creationDate', @@ -108,7 +108,7 @@ export default { try { this.$data.receivedCatalogs = await dataUtils.receiveCatalogs(this.$data.recipientId); } catch (error) { - errorUtils.showError(error, "Receive Catalogs"); + errorUtils.showError(error, "Request Catalogs"); } this.$data.noCatalogsFound = this.$data.receivedCatalogs.length == 0; this.$root.$emit('showBusyIndicator', false); @@ -119,7 +119,7 @@ export default { try { this.$data.resourcesInSelectedCatalog = await dataUtils.receiveResourcesInCatalog(this.$data.recipientId, catalogID); } catch (error) { - errorUtils.showError(error, "Receive Resources in Catalog"); + errorUtils.showError(error, "Request Resources in Catalog"); } this.$root.$emit('showBusyIndicator', false); }, @@ -134,7 +134,7 @@ export default { try { this.$data.idsResourceCatalog = await dataUtils.receiveIdsResourceCatalog(this.$data.recipientId, catalogId); } catch (error) { - errorUtils.showError(error, "Receive Resources in Catalog"); + errorUtils.showError(error, "Request Resources in Catalog"); } }, @@ -150,13 +150,13 @@ export default { try{ this.$data.selectedIdsArtifact = await dataUtils.receiveIdsArtifact(this.$data.recipientId, artifact["@id"]) } catch (error) { - errorUtils.showError(error, "Receive Artifact"); + errorUtils.showError(error, "Request Artifact"); } try{ this.$data.idsContractOffer = await dataUtils.receiveIdsContractOffer(this.$data.recipientId, artifact["@id"]) } catch (error) { - errorUtils.showError(error, "Receive Contract Offer"); + errorUtils.showError(error, "Request Contract Offer"); } }, */ @@ -170,7 +170,7 @@ export default { this.$data.requestContractResponse = await dataUtils.receiveContract(this.$data.recipientId, this.$data.selectedResource["@id"], this.$data.selectedResource["ids:contractOffer"], this.$data.selectedIdsArtifact, download); } catch (error) { - errorUtils.showError(error, "Receive Contract"); + errorUtils.showError(error, "Request Contract"); } }, diff --git a/src/pages/dataconsumption/resources/IDSResourcesPageConsumption.html b/src/pages/dataconsumption/resources/IDSResourcesPageConsumption.html index 77f8e8f5..ab321238 100644 --- a/src/pages/dataconsumption/resources/IDSResourcesPageConsumption.html +++ b/src/pages/dataconsumption/resources/IDSResourcesPageConsumption.html @@ -1,7 +1,7 @@
- - Receive Resources + + Request Resource diff --git a/src/utils/validationUtils.js b/src/utils/validationUtils.js index 093ed380..b9cbe279 100644 --- a/src/utils/validationUtils.js +++ b/src/utils/validationUtils.js @@ -50,13 +50,6 @@ export default { ]; }, - getProviderUrlRequiredRule() { - return [ - v => !!v || 'This data is required', - v => /^[h][t][t][p][s]{0,1}[:][/][/][^ ]+[/]api[/]ids[/]data$/.test(v == null ? v : v.trim()) || 'Only Provider-URIs (Start: http:// or https://, End: "/api/ids/data") allowed', - ]; - }, - getUrlNotRequiredRule() { return [ v => { From a024480a848c2e0732136d418e47c28e9eac3334 Mon Sep 17 00:00:00 2001 From: Bastian Weltjen Date: Tue, 17 Aug 2021 17:34:36 +0200 Subject: [PATCH 03/13] feat[data consumption]: show list of requested resources --- .../IDSResourcesPageConsumption.html | 15 +---- .../resources/IDSResourcesPageConsumption.js | 62 ++++++++----------- .../addresource/AddResourcePage.html | 2 +- .../resources/addresource/AddResourcePage.js | 27 +++++++- .../addresource/policy/ResourcePolicyPage.js | 23 +++++++ .../ResourceRepresentationPage.html | 2 +- .../ResourceRepresentationPage.js | 6 +- .../ResourceDetailsDialog.js | 5 ++ src/utils/dataUtils.js | 47 ++++++++++++++ 9 files changed, 131 insertions(+), 58 deletions(-) diff --git a/src/pages/dataconsumption/resources/IDSResourcesPageConsumption.html b/src/pages/dataconsumption/resources/IDSResourcesPageConsumption.html index ab321238..0011dd71 100644 --- a/src/pages/dataconsumption/resources/IDSResourcesPageConsumption.html +++ b/src/pages/dataconsumption/resources/IDSResourcesPageConsumption.html @@ -4,14 +4,6 @@ Request Resource - - - - - - - @@ -24,16 +16,11 @@ mdi-eye - - mdi-pencil - - - mdi-delete -
+
\ No newline at end of file diff --git a/src/pages/dataconsumption/resources/IDSResourcesPageConsumption.js b/src/pages/dataconsumption/resources/IDSResourcesPageConsumption.js index 5ddd3a27..2e72d02b 100644 --- a/src/pages/dataconsumption/resources/IDSResourcesPageConsumption.js +++ b/src/pages/dataconsumption/resources/IDSResourcesPageConsumption.js @@ -1,34 +1,35 @@ import dataUtils from "@/utils/dataUtils"; import ConfirmationDialog from "@/components/confirmationdialog/ConfirmationDialog.vue"; +import errorUtils from "../../../utils/errorUtils"; +import ResourceDetailsDialog from "../../dataoffering/resources/resourcedetailsdialog/ResourceDetailsDialog.vue"; export default { components: { - ConfirmationDialog + ConfirmationDialog, + ResourceDetailsDialog }, data() { return { search: '', headers: [{ + text: 'Creation date', + value: 'creationDate', + width: 135 + }, { text: 'Title', value: 'title' }, { - text: 'Description', - value: 'description' - }, - { - text: 'Type', - value: 'sourceType' - }, { - text: 'Policy', - value: 'policyName' + text: 'Keywords', + value: 'keywords' }, { text: '', value: 'actions', sortable: false, - align: 'right' + align: 'right', + width: 150 } ], resources: [], @@ -40,9 +41,17 @@ export default { this.getResources(); }, methods: { - getResources() { - // this.$root.$emit('showBusyIndicator', true); - // TODO Get resources + async getResources() { + this.$root.$emit('showBusyIndicator', true); + try { + let response = await dataUtils.getRequestedResources(); + this.$data.resources = response; + } catch (error) { + errorUtils.showError(error, "Get resources"); + } + this.filterChanged(); + this.$forceUpdate(); + this.$root.$emit('showBusyIndicator', false); }, filterChanged() { if (this.$data.filterResourceType == null | this.$data.filterResourceType == "All") { @@ -50,35 +59,14 @@ export default { } else { this.$data.filteredResources = []; for (var resource of this.$data.resources) { - if (resource.type == this.$data.filterResourceType) { + if (resource.fileType == this.$data.filterResourceType) { this.$data.filteredResources.push(resource); } } } }, - deleteItem(item) { - this.$refs.confirmationDialog.title = "Delete Resource"; - this.$refs.confirmationDialog.text = "Are you sure you want to delete the resource '" + item.title + "'?"; - this.$refs.confirmationDialog.callbackData = { - item: item - }; - this.$refs.confirmationDialog.callback = this.deleteCallback; - this.$refs.confirmationDialog.dialog = true; - }, - deleteCallback(choice, callbackData) { - if (choice == "yes") { - this.$root.$emit('showBusyIndicator', true); - dataUtils.deleteResource(callbackData.item.id, () => { - this.getResources(); - this.$root.$emit('showBusyIndicator', false); - }); - } - }, - editItem(item) { - this.$router.push('editresource?id=' + item.id); - }, showItem(item) { - this.$refs.resourceDetailsDialog.show(item); + this.$refs.resourceDetailsDialog.showRequest(item.id); } }, }; diff --git a/src/pages/dataoffering/resources/addresource/AddResourcePage.html b/src/pages/dataoffering/resources/addresource/AddResourcePage.html index 8c38b4b6..c594a1f8 100644 --- a/src/pages/dataoffering/resources/addresource/AddResourcePage.html +++ b/src/pages/dataoffering/resources/addresource/AddResourcePage.html @@ -4,7 +4,7 @@ Meta data Policy Representation - Brokers + Brokers diff --git a/src/pages/dataoffering/resources/addresource/AddResourcePage.js b/src/pages/dataoffering/resources/addresource/AddResourcePage.js index 9bc8b938..f8c23cab 100644 --- a/src/pages/dataoffering/resources/addresource/AddResourcePage.js +++ b/src/pages/dataoffering/resources/addresource/AddResourcePage.js @@ -25,7 +25,8 @@ export default { fileAttributes: null, fileRequiredAttributes: null, readonly: false, - onlyMetaData: false + onlyMetaData: false, + hideBrokers: false }; }, mounted: function () { @@ -63,6 +64,7 @@ export default { }, async loadResource(id) { this.$data.onlyMetaData = false; + this.$data.hideBrokers = false; this.$data.active_tab = 0; this.$root.$emit('showBusyIndicator', true); try { @@ -71,7 +73,26 @@ export default { this.$data.isNewResource = false; this.$refs.metaDataPage.loadResource(this.$data.currentResource, this.$data.onlyMetaData); this.$refs.policyPage.loadResource(this.$data.currentResource); - this.$refs.representationPage.loadResource(this.$data.currentResource); + this.$refs.representationPage.loadResource(this.$data.currentResource, false); + this.$refs.brokersPage.loadResource(this.$data.currentResource); + } catch (error) { + errorUtils.showError(error, "Get resource"); + } + this.$root.$emit('showBusyIndicator', false); + this.$forceUpdate(); + }, + async loadRequestedResource(id) { + this.$data.onlyMetaData = false; + this.$data.hideBrokers = true; + this.$data.active_tab = 0; + this.$root.$emit('showBusyIndicator', true); + try { + let response = await dataUtils.getRequestedResource(id); + this.$data.currentResource = response; + this.$data.isNewResource = false; + this.$refs.metaDataPage.loadResource(this.$data.currentResource, this.$data.onlyMetaData); + await this.$refs.policyPage.loadRequestedResource(this.$data.currentResource); + this.$refs.representationPage.loadResource(this.$data.currentResource, true); this.$refs.brokersPage.loadResource(this.$data.currentResource); } catch (error) { errorUtils.showError(error, "Get resource"); @@ -86,7 +107,7 @@ export default { this.$refs.metaDataPage.loadResource(this.$data.currentResource, this.$data.onlyMetaData); if (!onlyMetaData) { this.$refs.policyPage.loadResource(this.$data.currentResource); - this.$refs.representationPage.loadResource(this.$data.currentResource); + this.$refs.representationPage.loadResource(this.$data.currentResource, false); this.$refs.brokersPage.loadResource(this.$data.currentResource); } this.$data.active_tab = 0; diff --git a/src/pages/dataoffering/resources/addresource/policy/ResourcePolicyPage.js b/src/pages/dataoffering/resources/addresource/policy/ResourcePolicyPage.js index 9a41333d..9e4947ed 100644 --- a/src/pages/dataoffering/resources/addresource/policy/ResourcePolicyPage.js +++ b/src/pages/dataoffering/resources/addresource/policy/ResourcePolicyPage.js @@ -1,4 +1,5 @@ import PolicyLine from "@/components/policy/PolicyLine.vue"; +import dataUtils from "../../../../../utils/dataUtils"; export default { components: { @@ -52,6 +53,28 @@ export default { } } }, + async loadRequestedResource(resource) { + this.$data.policyLines = []; + let agreements = await dataUtils.getArtifactAgreements(resource.artifactId); + if (agreements.length > 0) { + let agreement = JSON.parse(agreements[0].value); + let i = 0; + for (let permission of agreement["ids:permission"]) { + permission["@context"] = { + "ids": "https://w3id.org/idsa/core/", + "idsc": "https://w3id.org/idsa/code/" + }; + let policyName = await dataUtils.getPolicyNameByPattern(JSON.stringify(permission)); + let policyLine = { + "name": Date.now() + i, + "ruleJson": permission, + "policyName": policyName + }; + this.$data.policyLines.push(policyLine); + i++; + } + } + }, getDescriptions() { let descriptions = []; for (let policyLine of this.$data.policyLines) { diff --git a/src/pages/dataoffering/resources/addresource/representation/ResourceRepresentationPage.html b/src/pages/dataoffering/resources/addresource/representation/ResourceRepresentationPage.html index 8901bc05..af5c3f54 100644 --- a/src/pages/dataoffering/resources/addresource/representation/ResourceRepresentationPage.html +++ b/src/pages/dataoffering/resources/addresource/representation/ResourceRepresentationPage.html @@ -1,5 +1,5 @@
-
diff --git a/src/pages/dataoffering/resources/addresource/representation/ResourceRepresentationPage.js b/src/pages/dataoffering/resources/addresource/representation/ResourceRepresentationPage.js index a7ff5c68..9eba0793 100644 --- a/src/pages/dataoffering/resources/addresource/representation/ResourceRepresentationPage.js +++ b/src/pages/dataoffering/resources/addresource/representation/ResourceRepresentationPage.js @@ -31,6 +31,7 @@ export default { readonly: false, newBackendConnection: false, filetype: "", + hideBackendConnections: false }; }, watch: { @@ -72,7 +73,8 @@ export default { errorUtils.showError(error, "Get backend connections"); } }, - async loadResource(resource) { + async loadResource(resource, hideBackendConnections) { + this.$data.hideBackendConnections = hideBackendConnections; if (resource.fileType === undefined) { this.$refs.form.reset(); } else { @@ -82,7 +84,7 @@ export default { } this.$data.selected = []; - if (resource.artifactId !== undefined && resource.artifactId != "") { + if (!hideBackendConnections && resource.artifactId !== undefined && resource.artifactId != "") { try { let route = await dataUtils.getRouteWithEnd(resource.artifactId); let ge = route.start; diff --git a/src/pages/dataoffering/resources/resourcedetailsdialog/ResourceDetailsDialog.js b/src/pages/dataoffering/resources/resourcedetailsdialog/ResourceDetailsDialog.js index 83f1ad11..1420c0aa 100644 --- a/src/pages/dataoffering/resources/resourcedetailsdialog/ResourceDetailsDialog.js +++ b/src/pages/dataoffering/resources/resourcedetailsdialog/ResourceDetailsDialog.js @@ -28,6 +28,11 @@ export default { this.$refs.addResourcePage.setReadOnly(true); this.$data.dialog = true; }, + showRequest(resourceId) { + this.$refs.addResourcePage.loadRequestedResource(resourceId); + this.$refs.addResourcePage.setReadOnly(true); + this.$data.dialog = true; + }, showResource(resource) { this.$refs.addResourcePage.set(resource, true); this.$refs.addResourcePage.setReadOnly(true); diff --git a/src/utils/dataUtils.js b/src/utils/dataUtils.js index e0d3ae50..2695e5f5 100644 --- a/src/utils/dataUtils.js +++ b/src/utils/dataUtils.js @@ -175,6 +175,15 @@ export default { return resources; }, + async getRequestedResources() { + let response = (await restUtils.callConnector("GET", "/api/requests"))["_embedded"].resources; + let resources = []; + for (let idsResource of response) { + resources.push(clientDataModel.convertIdsResource(idsResource)); + } + return resources; + }, + async getResource(resourceId) { let resource = await restUtils.callConnector("GET", "/api/offers/" + resourceId); let policyNames = []; @@ -207,6 +216,44 @@ export default { return clientDataModel.convertIdsResource(resource, representation, policyNames, ruleIds, ruleJsons, artifactId, brokerUris); }, + async getRequestedResource(resourceId) { + let resource = await restUtils.callConnector("GET", "/api/requests/" + resourceId); + let policyNames = []; + let ruleIds = []; + let ruleJsons = []; + let contracts = (await restUtils.callConnector("GET", "/api/requests/" + resourceId + "/contracts"))["_embedded"].contracts; + if (contracts.length > 0) { + let contract = contracts[0]; + let contractId = this.getIdOfConnectorResponse(contract); + let rules = (await restUtils.callConnector("GET", "/api/contracts/" + contractId + "/rules"))["_embedded"].rules; + for (let rule of rules) { + policyNames.push(await restUtils.callConnector("POST", "/api/examples/validation", null, rule.value)); + ruleIds.push(this.getIdOfConnectorResponse(rule)); + ruleJsons.push(JSON.parse(rule.value)); + } + } + let representations = (await restUtils.callConnector("GET", "/api/requests/" + resourceId + "/representations"))["_embedded"].representations; + let representation = undefined; + let artifactId = undefined; + if (representations.length > 0) { + representation = representations[0]; + let representationId = this.getIdOfConnectorResponse(representation); + let artifacts = (await restUtils.callConnector("GET", "/api/representations/" + representationId + "/artifacts"))["_embedded"].artifacts; + if (artifacts.length > 0) { + artifactId = this.getIdOfConnectorResponse(artifacts[0]); + } + } + return clientDataModel.convertIdsResource(resource, representation, policyNames, ruleIds, ruleJsons, artifactId); + }, + + async getPolicyNameByPattern(pattern) { + return await restUtils.callConnector("POST", "/api/examples/validation", null, pattern); + }, + + async getArtifactAgreements(artifactId) { + return (await restUtils.callConnector("GET", "/api/artifacts/" + artifactId + "/agreements"))["_embedded"].agreements; + }, + async getLanguages() { if (languages == null) { let languages = (await restUtils.callConnector("GET", "/api/configmanager/enum/Language")); From 0eab4d36edf6170ab4799a979146d97aa52a07ec Mon Sep 17 00:00:00 2001 From: Bastian Weltjen Date: Wed, 18 Aug 2021 11:16:18 +0200 Subject: [PATCH 04/13] fix[data consumption]: show download link to artifact of own connector --- .../dataconsumption/IDSDataConsumptionPage.html | 4 ++-- .../dataconsumption/IDSDataConsumptionPage.js | 3 ++- src/utils/dataUtils.js | 10 ++++++++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/pages/dataconsumption/dataconsumption/IDSDataConsumptionPage.html b/src/pages/dataconsumption/dataconsumption/IDSDataConsumptionPage.html index 58c4ab3d..8c4ccbce 100644 --- a/src/pages/dataconsumption/dataconsumption/IDSDataConsumptionPage.html +++ b/src/pages/dataconsumption/dataconsumption/IDSDataConsumptionPage.html @@ -104,8 +104,8 @@

License:

Download:

- {{ - selectedIdsArtifact["@id"] }}/data + + {{ downloadLink }}
diff --git a/src/pages/dataconsumption/dataconsumption/IDSDataConsumptionPage.js b/src/pages/dataconsumption/dataconsumption/IDSDataConsumptionPage.js index 006315c6..21ca2b6e 100644 --- a/src/pages/dataconsumption/dataconsumption/IDSDataConsumptionPage.js +++ b/src/pages/dataconsumption/dataconsumption/IDSDataConsumptionPage.js @@ -169,6 +169,8 @@ export default { try { this.$data.requestContractResponse = await dataUtils.receiveContract(this.$data.recipientId, this.$data.selectedResource["@id"], this.$data.selectedResource["ids:contractOffer"], this.$data.selectedIdsArtifact, download); + let agreementId = await dataUtils.getIdOfAgreement(this.$data.requestContractResponse._links.artifacts.href); + this.$data.downloadLink = (await dataUtils.getAgreementArtifacts(agreementId))[0]._links.data.href; } catch (error) { errorUtils.showError(error, "Request Contract"); } @@ -210,7 +212,6 @@ export default { clickAcceptContract(artifact) { this.$data.selectedIdsArtifact = artifact; - this.$data.downloadLink = artifact["@id"] + "/data"; this.requestContract(); this.subscribeToResource(); } diff --git a/src/utils/dataUtils.js b/src/utils/dataUtils.js index 2695e5f5..1b091623 100644 --- a/src/utils/dataUtils.js +++ b/src/utils/dataUtils.js @@ -254,6 +254,10 @@ export default { return (await restUtils.callConnector("GET", "/api/artifacts/" + artifactId + "/agreements"))["_embedded"].agreements; }, + async getAgreementArtifacts(agreementId) { + return (await restUtils.callConnector("GET", "/api/agreements/" + agreementId + "/artifacts"))["_embedded"].artifacts; + }, + async getLanguages() { if (languages == null) { let languages = (await restUtils.callConnector("GET", "/api/configmanager/enum/Language")); @@ -512,6 +516,12 @@ export default { return url.substring(url.lastIndexOf("/") + 1, url.length); }, + getIdOfAgreement(agreementLink) { + let id = agreementLink.replace("https://localhost:8080/api/agreements/", ""); + id = id.replace("/artifacts{?page,size}", ""); + return id; + }, + async getDefaultCatalogId() { if (defaultCatalogId == null) { let catalogs = (await restUtils.callConnector("GET", "/api/catalogs"))._embedded.catalogs; From 19f9e375ad7ec8c41dd7ccb055cf67106cc4f37c Mon Sep 17 00:00:00 2001 From: Bastian Weltjen Date: Wed, 18 Aug 2021 11:18:57 +0200 Subject: [PATCH 05/13] docs: changelog & version --- CHANGELOG.md | 8 ++++++++ package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 852a2381..9d2e30ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ All notable changes to this project will be documented in this file. (Skipped major version 1, 2 and 3 to match versioning of IDS DataSpaceConnector) +## [8.4.0] - 2021-08-18 + +### Added +- Data Consumption: Show list of requested resources + +### Fixes +- Data Consumption: Show download link to artifact of own connector + ## [8.3.2] - 2021-08-17 ### Fixes diff --git a/package.json b/package.json index 6320923c..9612dd41 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dataspaceconnector-ui", - "version": "8.3.2", + "version": "8.4.0", "private": true, "scripts": { "serve": "vue-cli-service serve --open --port 8082", From e58f1db19dc760b400a4b892fe1fdf7d8ea206c3 Mon Sep 17 00:00:00 2001 From: Bastian Weltjen Date: Wed, 18 Aug 2021 11:59:22 +0200 Subject: [PATCH 06/13] feat[backend connections]: API-Key authentication --- src/datamodel/clientDataModel.js | 11 ++++++-- .../dialog/AddBackendConnectionDialog.html | 26 +++++++++++++------ .../dialog/AddBackendConnectionDialog.js | 12 ++++++++- src/utils/dataUtils.js | 16 +++++++++--- 4 files changed, 50 insertions(+), 15 deletions(-) diff --git a/src/datamodel/clientDataModel.js b/src/datamodel/clientDataModel.js index 9534c88f..0a86b861 100644 --- a/src/datamodel/clientDataModel.js +++ b/src/datamodel/clientDataModel.js @@ -195,7 +195,7 @@ export default { return configuration; }, - createGenericEndpoint(id, accessUrl, dataSourceId, username, password, type) { + createGenericEndpoint(id, accessUrl, dataSourceId, username, password, apiKey, type) { let genericEndpoint = {}; if (id === undefined) { @@ -228,6 +228,12 @@ export default { genericEndpoint.password = password; } + if (apiKey === undefined) { + genericEndpoint.apiKey = ""; + } else { + genericEndpoint.apiKey = apiKey; + } + if (type === undefined) { genericEndpoint.type = ""; } else { @@ -244,7 +250,8 @@ export default { let dataSourceId = dataUtils.getIdOfLink(genericEndpoint, "dataSource"); let username = undefined; let password = undefined; - return this.createGenericEndpoint(id, accessUrl, dataSourceId, username, password, genericEndpoint.type); + let apiKey = undefined; + return this.createGenericEndpoint(id, accessUrl, dataSourceId, username, password, apiKey, genericEndpoint.type); }, createApp(id, title, description, type) { diff --git a/src/pages/dataoffering/backendconnections/dialog/AddBackendConnectionDialog.html b/src/pages/dataoffering/backendconnections/dialog/AddBackendConnectionDialog.html index 87c55b48..6d26c588 100644 --- a/src/pages/dataoffering/backendconnections/dialog/AddBackendConnectionDialog.html +++ b/src/pages/dataoffering/backendconnections/dialog/AddBackendConnectionDialog.html @@ -14,12 +14,22 @@ - - - - + + + Basic + API-Key + + + + + + + + + + @@ -29,10 +39,10 @@ Cancel - + Save - + \ No newline at end of file diff --git a/src/pages/dataoffering/backendconnections/dialog/AddBackendConnectionDialog.js b/src/pages/dataoffering/backendconnections/dialog/AddBackendConnectionDialog.js index 4c62b2e8..7d2ea4e0 100644 --- a/src/pages/dataoffering/backendconnections/dialog/AddBackendConnectionDialog.js +++ b/src/pages/dataoffering/backendconnections/dialog/AddBackendConnectionDialog.js @@ -6,6 +6,7 @@ export default { data() { return { dialog: false, + active_tab: 0, currentEndpoint: null, title: "", url: null, @@ -13,6 +14,7 @@ export default { sourceTypes: ["Database", "REST"], username: null, password: null, + apiKey: null, showPassword: false, valid: false, urlRule: validationUtils.getUrlRequiredRule() @@ -37,6 +39,7 @@ export default { this.$data.sourceType = this.$data.sourceTypes[0]; this.$data.username = ""; this.$data.password = ""; + this.$data.apiKey = ""; }, cancelBackendConnection() { this.$data.dialog = false; @@ -46,7 +49,13 @@ export default { this.$root.$emit('showBusyIndicator', true); this.$data.dialog = false; try { - await dataUtils.createGenericEndpoint(this.$data.url, this.$data.username, this.$data.password, this.$data.sourceType); + if (this.$data.active_tab == 0) { + this.$data.apiKey = null; + } else { + this.$data.username = null; + this.$data.password = null; + } + await dataUtils.createGenericEndpoint(this.$data.url, this.$data.username, this.$data.password, this.$data.apiKey, this.$data.sourceType); } catch (error) { console.log("Error on saveBackendConnection(): ", error); this.$root.$emit('error', "Create backend connection failed."); @@ -72,6 +81,7 @@ export default { this.$data.sourceType = (await dataUtils.getDataSource(endpoint.dataSourceId)).type; this.$data.username = endpoint.username; this.$data.password = endpoint.password; + this.$data.apiKey = endpoint.apiKey; this.$data.dialog = true; } } diff --git a/src/utils/dataUtils.js b/src/utils/dataUtils.js index 1b091623..b134aa54 100644 --- a/src/utils/dataUtils.js +++ b/src/utils/dataUtils.js @@ -366,18 +366,26 @@ export default { return genericEndpoints; }, - async createGenericEndpoint(url, username, password, sourceType) { + async createGenericEndpoint(url, username, password, apiKey, sourceType) { let response = await restUtils.callConnector("POST", "/api/endpoints", null, { "location": url, "type": "GENERIC" }); let genericEndpointId = this.getIdOfConnectorResponse(response); - response = await restUtils.callConnector("POST", "/api/datasources", null, { - "authentication": { + let authentication = null; + if (username != null) { + authentication = { "key": username, "value": password - }, + }; + } else { + authentication = { + "value": apiKey + }; + } + response = await restUtils.callConnector("POST", "/api/datasources", null, { + "authentication": authentication, "type": sourceType }); let dataSourceId = this.getIdOfConnectorResponse(response); From 544d92abc134d5838e45cf614dc11055d7f50359 Mon Sep 17 00:00:00 2001 From: Bastian Weltjen Date: Wed, 18 Aug 2021 11:59:54 +0200 Subject: [PATCH 07/13] docs: changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d2e30ea..7ab22903 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file. ### Added - Data Consumption: Show list of requested resources +- Backend Connections: API-Key authentication ### Fixes - Data Consumption: Show download link to artifact of own connector From 255527723de02c122fc53eca9a61fe611fcdb0cb Mon Sep 17 00:00:00 2001 From: Bastian Weltjen Date: Wed, 18 Aug 2021 15:07:54 +0200 Subject: [PATCH 08/13] fix[data consumption]: clear results --- .../dataconsumption/IDSDataConsumptionPage.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/pages/dataconsumption/dataconsumption/IDSDataConsumptionPage.js b/src/pages/dataconsumption/dataconsumption/IDSDataConsumptionPage.js index 21ca2b6e..1e78f0b5 100644 --- a/src/pages/dataconsumption/dataconsumption/IDSDataConsumptionPage.js +++ b/src/pages/dataconsumption/dataconsumption/IDSDataConsumptionPage.js @@ -121,6 +121,15 @@ export default { } catch (error) { errorUtils.showError(error, "Request Resources in Catalog"); } + this.$data.idsResourceCatalog = {}; + this.$data.selectedResource = {}; + this.$data.selectedRepresentations = []; + this.$data.selectedRepresentation = {}; + this.$data.selectedArtifacts = []; + this.$data.selectedIdsArtifact = {}; + this.$data.idsContractOffer = {}; + this.$data.requestContractResponse = {}; + this.$data.downloadLink = ""; this.$root.$emit('showBusyIndicator', false); }, @@ -197,7 +206,12 @@ export default { } } }); - + this.$data.selectedRepresentation = {}; + this.$data.selectedArtifacts = []; + this.$data.selectedIdsArtifact = {}; + this.$data.idsContractOffer = {}; + this.$data.requestContractResponse = {}; + this.$data.downloadLink = ""; }, From 1de746986ff1792e65969075f2a2e1d81a4c3058 Mon Sep 17 00:00:00 2001 From: Bastian Weltjen Date: Wed, 18 Aug 2021 16:49:16 +0200 Subject: [PATCH 09/13] feat[resources]: set payment method --- src/datamodel/clientDataModel.js | 9 +++- .../resources/addresource/AddResourcePage.js | 7 ++-- .../metadata/ResourceMetaDataPage.html | 3 ++ .../metadata/ResourceMetaDataPage.js | 7 ++++ .../EditIdsEndpointDialog.js | 3 +- src/utils/dataUtils.js | 41 +++++++++++++------ 6 files changed, 52 insertions(+), 18 deletions(-) diff --git a/src/datamodel/clientDataModel.js b/src/datamodel/clientDataModel.js index 0a86b861..a5b1a0fe 100644 --- a/src/datamodel/clientDataModel.js +++ b/src/datamodel/clientDataModel.js @@ -1,7 +1,7 @@ import dataUtils from "@/utils/dataUtils"; export default { - createResource(id, creationDate, title, description, language, keywords, version, standardlicense, + createResource(id, creationDate, title, description, language, paymentMethod, keywords, version, standardlicense, publisher, fileType, policyNames, ruleIds, ruleJsons, artifactId, representationId, brokerUris) { let resource = {}; if (id === undefined) { @@ -29,6 +29,11 @@ export default { } else { resource.language = language; } + if (paymentMethod === undefined) { + resource.paymentMethod = ""; + } else { + resource.paymentMethod = paymentMethod; + } if (keywords === undefined) { resource.keywords = ""; } else { @@ -305,7 +310,7 @@ export default { } return this.createResource(dataUtils.getIdOfConnectorResponse(idsResource), idsResource.creationDate, title, description, - idsResource.language.replace("https://w3id.org/idsa/code/", ""), idsResource.keywords, + idsResource.language.replace("https://w3id.org/idsa/code/", ""), idsResource.paymentModality, idsResource.keywords, idsResource.version, idsResource.license, idsResource.publisher, fileType, policyNames, ruleIds, ruleJsons, artifactId, representationId, brokerUris); }, diff --git a/src/pages/dataoffering/resources/addresource/AddResourcePage.js b/src/pages/dataoffering/resources/addresource/AddResourcePage.js index f8c23cab..e43878e0 100644 --- a/src/pages/dataoffering/resources/addresource/AddResourcePage.js +++ b/src/pages/dataoffering/resources/addresource/AddResourcePage.js @@ -127,6 +127,7 @@ export default { var title = this.$refs.metaDataPage.title; var description = this.$refs.metaDataPage.description; var language = this.$refs.metaDataPage.language; + var paymentMethod = this.$refs.metaDataPage.paymentMethod; var keywords = dataUtils.commaSeperatedStringToArray(this.$refs.metaDataPage.keywords); var standardlicense = this.$refs.metaDataPage.standardlicense; var publisher = this.$refs.metaDataPage.publisher; @@ -137,18 +138,18 @@ export default { if (this.fromRoutePage == 'true') { // On route page this data is initially stored only in the node and will be saved with the route. - this.$emit("saved", title, description, language, keywords, 0, standardlicense, publisher, + this.$emit("saved", title, description, language, paymentMethod, keywords, 0, standardlicense, publisher, policyDescriptions, filetype, 0, brokerList); } else { this.$root.$emit('showBusyIndicator', true); if (this.$data.currentResource == null) { - await dataUtils.createResourceWithMinimalRoute(title, description, language, keywords, standardlicense, publisher, + await dataUtils.createResourceWithMinimalRoute(title, description, language, paymentMethod, keywords, standardlicense, publisher, policyDescriptions, filetype, brokerList, genericEndpoint); this.$router.push('idresourcesoffering'); this.$root.$emit('showBusyIndicator', false); } else { await dataUtils.editResource(this.$data.currentResource.id, this.$data.currentResource.representationId, - title, description, language, keywords, standardlicense, publisher, policyDescriptions, + title, description, language, paymentMethod, keywords, standardlicense, publisher, policyDescriptions, filetype, brokerList, brokerDeleteList, genericEndpoint, this.$data.currentResource.ruleId, this.$data.currentResource.artifactId); this.$router.push('idresourcesoffering'); diff --git a/src/pages/dataoffering/resources/addresource/metadata/ResourceMetaDataPage.html b/src/pages/dataoffering/resources/addresource/metadata/ResourceMetaDataPage.html index e713ab38..8852690b 100644 --- a/src/pages/dataoffering/resources/addresource/metadata/ResourceMetaDataPage.html +++ b/src/pages/dataoffering/resources/addresource/metadata/ResourceMetaDataPage.html @@ -15,6 +15,9 @@ + + Next diff --git a/src/pages/dataoffering/resources/addresource/metadata/ResourceMetaDataPage.js b/src/pages/dataoffering/resources/addresource/metadata/ResourceMetaDataPage.js index 50c87c3b..aaaeac03 100644 --- a/src/pages/dataoffering/resources/addresource/metadata/ResourceMetaDataPage.js +++ b/src/pages/dataoffering/resources/addresource/metadata/ResourceMetaDataPage.js @@ -17,6 +17,12 @@ export default { standardlicense: "", language: "", languageItems: [], + paymentMethod: "undefined", + // TODO use enum API endpoint for payment methods + paymentMethods: [{ "originalName": "undefined", "displayName": "Undefined" }, + { "originalName": "fixedPrice", "displayName": "Fixed price" }, + { "originalName": "free", "displayName": "Free" }, + { "originalName": "negotiationBasis", "displayName": "Negotiation basis" }], valid: false, defaultRule: validationUtils.getRequiredRule(), urlRule: validationUtils.getUrlRequiredRule(), @@ -46,6 +52,7 @@ export default { this.$data.title = resource.title; this.$data.description = resource.description; this.$data.language = resource.language.substring(resource.language.lastIndexOf("/") + 1); + this.$data.paymentMethod = resource.paymentMethod; this.$data.keywords = dataUtils.arrayToCommaSeperatedString(resource.keywords); this.$data.standardlicense = resource.standardlicense; this.$data.publisher = resource.publisher; diff --git a/src/pages/dataoffering/routes/addroute/dialog/editidsendpointdialog/EditIdsEndpointDialog.js b/src/pages/dataoffering/routes/addroute/dialog/editidsendpointdialog/EditIdsEndpointDialog.js index 4ce6c254..a2683548 100644 --- a/src/pages/dataoffering/routes/addroute/dialog/editidsendpointdialog/EditIdsEndpointDialog.js +++ b/src/pages/dataoffering/routes/addroute/dialog/editidsendpointdialog/EditIdsEndpointDialog.js @@ -41,7 +41,7 @@ export default { this.$refs.addResourcePage.set(resource, false); this.$data.dialog = true; }, - saved(title, description, language, keywords, version, standardlicense, publisher, policyDescriptions, filetype, bytesize, brokerList) { + saved(title, description, language, paymentMethod, keywords, version, standardlicense, publisher, policyDescriptions, filetype, bytesize, brokerList) { let isNew = false; if (this.$data.node == null) { isNew = true; @@ -61,6 +61,7 @@ export default { resource.title = title; resource.description = description; resource.language = language; + resource.paymentMethod = paymentMethod; resource.keywords = keywords; resource.version = version; resource.standardlicense = standardlicense; diff --git a/src/utils/dataUtils.js b/src/utils/dataUtils.js index b134aa54..f8fb7808 100644 --- a/src/utils/dataUtils.js +++ b/src/utils/dataUtils.js @@ -46,6 +46,12 @@ const OPERATOR_TYPE_TO_SYMBOL = { "https://w3id.org/idsa/code/LT": "<", }; +const IDS_PAYMENT_METHOD_TO_NAME = { + "https://w3id.org/idsa/code/NEGOTIATION_BASIS": "negotiationBasis", + "https://w3id.org/idsa/code/FREE": "free", + "https://w3id.org/idsa/code/FIXED_PRICE": "fixedPrice", + "https://w3id.org/idsa/code/UNDEFINED": "undefined" +}; let languages = null; let defaultCatalogId = null; @@ -76,6 +82,10 @@ export default { return POLICY_TYPE_TO_DISPLAY_NAME[type]; }, + getPaymentMethodName(idsName) { + return IDS_PAYMENT_METHOD_TO_NAME[idsName]; + }, + getValue(data, name) { let value = "-"; if (data[name] !== undefined && data[name] != null) { @@ -557,10 +567,10 @@ export default { } }, - async createResourceWithMinimalRoute(title, description, language, keywords, standardlicense, publisher, policyDescriptions, + async createResourceWithMinimalRoute(title, description, language, paymentMethod, keywords, standardlicense, publisher, policyDescriptions, filetype, brokerUris, genericEndpoint) { try { - let resourceResponse = await this.createResource(title, description, language, keywords, standardlicense, publisher, policyDescriptions, filetype, genericEndpoint); + let resourceResponse = await this.createResource(title, description, language, paymentMethod, keywords, standardlicense, publisher, policyDescriptions, filetype, genericEndpoint); let response = await this.createNewRoute(this.getCurrentDate() + " - " + title); let routeId = this.getIdOfConnectorResponse(response); response = await this.createSubRoute(routeId, genericEndpoint.id, 20, 150, resourceResponse.endpointId, 220, 150, resourceResponse.artifactId); @@ -574,7 +584,7 @@ export default { } }, - async createResource(title, description, language, keywords, standardlicense, publisher, policyDescriptions, + async createResource(title, description, language, paymentMethod, keywords, standardlicense, publisher, policyDescriptions, filetype) { // TODO Sovereign, EndpointDocumentation let response = (await restUtils.callConnector("POST", "/api/offers", null, { @@ -583,6 +593,7 @@ export default { "keywords": keywords, "publisher": publisher, "language": language, + "paymentMethod": paymentMethod, "license": standardlicense })); @@ -630,7 +641,7 @@ export default { }; }, - async editResource(resourceId, representationId, title, description, language, keywords, standardlicense, publisher, + async editResource(resourceId, representationId, title, description, language, paymentMethod, keywords, standardlicense, publisher, policyDescriptions, filetype, brokerUris, brokerDeleteUris, genericEndpoint, ruleId, artifactId) { try { await restUtils.callConnector("PUT", "/api/offers/" + resourceId, null, { @@ -639,6 +650,7 @@ export default { "keywords": keywords, "publisher": publisher, "language": language, + "paymentMethod": paymentMethod, "license": standardlicense }); @@ -702,6 +714,7 @@ export default { let title = resource.title; let description = resource.description; let language = resource.language; + let paymentMethod = resource.paymentMethod; let keywords = resource.keywords; let standardlicense = resource.standardlicense; let publisher = resource.publisher; @@ -710,7 +723,7 @@ export default { let brokerUris = resource.brokerUris; try { - let resourceResponse = await this.createResource(title, description, language, keywords, standardlicense, publisher, policyDescriptions, filetype, genericEndpoint); + let resourceResponse = await this.createResource(title, description, language, paymentMethod, keywords, standardlicense, publisher, policyDescriptions, filetype, genericEndpoint); await this.createSubRoute(routeId, startId, sourceNode.x, sourceNode.y, resourceResponse.endpointId, destinationNode.x, destinationNode.y, resourceResponse.artifactId); this.addRouteStartAndEnd(routeId, startId, resourceResponse.endpointId); await this.updateResourceAtBrokers(brokerUris, resourceResponse.resourceId); @@ -873,7 +886,7 @@ export default { response = await restUtils.callConnector("POST", "/api/ids/description", params); if (response["ids:offeredResource"] !== undefined) { for (let resource of response["ids:offeredResource"]) { - addToLocalResources(resource, resources); + this.addToLocalResources(resource, resources); } } } @@ -907,7 +920,7 @@ export default { let response = await restUtils.callConnector("POST", "/api/ids/description", params); if (response["ids:offeredResource"] !== undefined) { for (let resource of response["ids:offeredResource"]) { - addToLocalResources(resource, resources); + this.addToLocalResources(resource, resources); } } return resources; @@ -973,16 +986,18 @@ export default { let response = await restUtils.callConnector("POST", "/api/ids/subscribe", params, body); return response; - } -} + }, -function addToLocalResources(resource, resources) { - { + addToLocalResources(resource, resources) { let id = resource["@id"].substring(resource["@id"].lastIndexOf("/"), resource["@id"].length); let creationDate = resource["ids:created"]["@value"]; let title = resource["ids:title"][0]["@value"]; let description = resource["ids:description"][0]["@value"]; let language = resource["ids:language"][0]["@id"].replace("https://w3id.org/idsa/code/", ""); + let paymentMethod = "undefined"; + if (resource["ids:paymentModality"][0] != null) { + paymentMethod = this.getPaymentMethodName(resource["ids:paymentModality"][0]["@id"]); + } let keywords = []; let idsKeywords = resource["ids:keyword"]; for (let idsKeyword of idsKeywords) { @@ -996,7 +1011,9 @@ function addToLocalResources(resource, resources) { fileType = resource["ids:representation"][0]["ids:mediaType"]["ids:filenameExtension"]; } - resources.push(clientDataModel.createResource(id, creationDate, title, description, language, keywords, version, standardlicense, + resources.push(clientDataModel.createResource(id, creationDate, title, description, language, paymentMethod, keywords, version, standardlicense, publisher, fileType, "", null)); } } + + From 55ee8c055bd16b1f49f6efcedb6ee24cdfe24aca Mon Sep 17 00:00:00 2001 From: Bastian Weltjen Date: Wed, 18 Aug 2021 16:49:48 +0200 Subject: [PATCH 10/13] docs: changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ab22903..8cd9e229 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. ### Added - Data Consumption: Show list of requested resources - Backend Connections: API-Key authentication +- Resources: Set payment method ### Fixes - Data Consumption: Show download link to artifact of own connector From 53eeea273c7f612bdb10516fb7baa04e213b72ad Mon Sep 17 00:00:00 2001 From: Bastian Weltjen Date: Wed, 18 Aug 2021 16:52:04 +0200 Subject: [PATCH 11/13] docs: changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cd9e229..82686634 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. (Skipped major version 1, 2 and 3 to match versioning of IDS DataSpaceConnector) -## [8.4.0] - 2021-08-18 +## [8.4.0] - XXX-XX-XX ### Added - Data Consumption: Show list of requested resources From 6550163e756d3d1685fd775a9deea17be4bc775a Mon Sep 17 00:00:00 2001 From: Bastian Weltjen Date: Fri, 20 Aug 2021 11:30:41 +0200 Subject: [PATCH 12/13] feat[resources]: set referenced resources --- src/datamodel/clientDataModel.js | 18 ++++- .../resources/IDSResourcesPage.html | 42 +++++++--- .../resources/IDSResourcesPage.js | 10 ++- .../resources/addresource/AddResourcePage.js | 3 +- .../metadata/ResourceMetaDataPage.js | 2 + .../ResourceReferenceDialog.css | 9 +++ .../ResourceReferenceDialog.html | 23 ++++++ .../ResourceReferenceDialog.js | 79 +++++++++++++++++++ .../ResourceReferenceDialog.vue | 3 + .../EditIdsEndpointDialog.js | 2 +- src/utils/dataUtils.js | 24 +++++- 11 files changed, 194 insertions(+), 21 deletions(-) create mode 100644 src/pages/dataoffering/resources/resourcereferencedialog/ResourceReferenceDialog.css create mode 100644 src/pages/dataoffering/resources/resourcereferencedialog/ResourceReferenceDialog.html create mode 100644 src/pages/dataoffering/resources/resourcereferencedialog/ResourceReferenceDialog.js create mode 100644 src/pages/dataoffering/resources/resourcereferencedialog/ResourceReferenceDialog.vue diff --git a/src/datamodel/clientDataModel.js b/src/datamodel/clientDataModel.js index a5b1a0fe..74b8ce0b 100644 --- a/src/datamodel/clientDataModel.js +++ b/src/datamodel/clientDataModel.js @@ -1,9 +1,14 @@ import dataUtils from "@/utils/dataUtils"; export default { - createResource(id, creationDate, title, description, language, paymentMethod, keywords, version, standardlicense, - publisher, fileType, policyNames, ruleIds, ruleJsons, artifactId, representationId, brokerUris) { + createResource(url, id, creationDate, title, description, language, paymentMethod, keywords, version, standardlicense, + publisher, fileType, policyNames, ruleIds, ruleJsons, artifactId, representationId, brokerUris, samples) { let resource = {}; + if (url === undefined) { + resource.url = ""; + } else { + resource.url = url; + } if (id === undefined) { resource.id = ""; } else { @@ -89,6 +94,11 @@ export default { } else { resource.brokerUris = brokerUris; } + if (samples === undefined) { + resource.samples = []; + } else { + resource.samples = samples; + } return resource; }, @@ -309,9 +319,9 @@ export default { representationId = dataUtils.getIdOfConnectorResponse(representation); } - return this.createResource(dataUtils.getIdOfConnectorResponse(idsResource), idsResource.creationDate, title, description, + return this.createResource(idsResource._links.self.href, dataUtils.getIdOfConnectorResponse(idsResource), idsResource.creationDate, title, description, idsResource.language.replace("https://w3id.org/idsa/code/", ""), idsResource.paymentModality, idsResource.keywords, - idsResource.version, idsResource.license, idsResource.publisher, fileType, policyNames, ruleIds, ruleJsons, artifactId, representationId, brokerUris); + idsResource.version, idsResource.license, idsResource.publisher, fileType, policyNames, ruleIds, ruleJsons, artifactId, representationId, brokerUris, idsResource.samples); }, diff --git a/src/pages/dataoffering/resources/IDSResourcesPage.html b/src/pages/dataoffering/resources/IDSResourcesPage.html index 526e5b92..f76a72df 100644 --- a/src/pages/dataoffering/resources/IDSResourcesPage.html +++ b/src/pages/dataoffering/resources/IDSResourcesPage.html @@ -12,15 +12,38 @@ @@ -28,4 +51,5 @@
+ \ No newline at end of file diff --git a/src/pages/dataoffering/resources/IDSResourcesPage.js b/src/pages/dataoffering/resources/IDSResourcesPage.js index 8493a368..73f66172 100644 --- a/src/pages/dataoffering/resources/IDSResourcesPage.js +++ b/src/pages/dataoffering/resources/IDSResourcesPage.js @@ -2,12 +2,13 @@ import dataUtils from "@/utils/dataUtils"; import errorUtils from "@/utils/errorUtils"; import ConfirmationDialog from "@/components/confirmationdialog/ConfirmationDialog.vue"; import ResourceDetailsDialog from "./resourcedetailsdialog/ResourceDetailsDialog.vue"; - +import ResourceReferenceDialog from "./resourcereferencedialog/ResourceReferenceDialog.vue"; export default { components: { ConfirmationDialog, - ResourceDetailsDialog + ResourceDetailsDialog, + ResourceReferenceDialog }, data() { return { @@ -33,7 +34,7 @@ export default { value: 'actions', sortable: false, align: 'right', - width: 150 + width: 170 } ], resources: [], @@ -105,6 +106,9 @@ export default { editItem(item) { this.$router.push('editresource?id=' + item.id); }, + editItemReferences(item) { + this.$refs.resourceReferenceDialog.show(item.id); + }, showItem(item) { this.$refs.resourceDetailsDialog.show(item.id); } diff --git a/src/pages/dataoffering/resources/addresource/AddResourcePage.js b/src/pages/dataoffering/resources/addresource/AddResourcePage.js index e43878e0..f9d57ef3 100644 --- a/src/pages/dataoffering/resources/addresource/AddResourcePage.js +++ b/src/pages/dataoffering/resources/addresource/AddResourcePage.js @@ -131,6 +131,7 @@ export default { var keywords = dataUtils.commaSeperatedStringToArray(this.$refs.metaDataPage.keywords); var standardlicense = this.$refs.metaDataPage.standardlicense; var publisher = this.$refs.metaDataPage.publisher; + var samples = this.$refs.metaDataPage.samples; var policyDescriptions = this.$refs.policyPage.getDescriptions(); var filetype = this.$refs.representationPage.filetype; var brokerList = this.$refs.brokersPage.getSelectedBrokerList() @@ -149,7 +150,7 @@ export default { this.$root.$emit('showBusyIndicator', false); } else { await dataUtils.editResource(this.$data.currentResource.id, this.$data.currentResource.representationId, - title, description, language, paymentMethod, keywords, standardlicense, publisher, policyDescriptions, + title, description, language, paymentMethod, keywords, standardlicense, publisher, samples, policyDescriptions, filetype, brokerList, brokerDeleteList, genericEndpoint, this.$data.currentResource.ruleId, this.$data.currentResource.artifactId); this.$router.push('idresourcesoffering'); diff --git a/src/pages/dataoffering/resources/addresource/metadata/ResourceMetaDataPage.js b/src/pages/dataoffering/resources/addresource/metadata/ResourceMetaDataPage.js index aaaeac03..6cf90652 100644 --- a/src/pages/dataoffering/resources/addresource/metadata/ResourceMetaDataPage.js +++ b/src/pages/dataoffering/resources/addresource/metadata/ResourceMetaDataPage.js @@ -16,6 +16,7 @@ export default { publisher: "", standardlicense: "", language: "", + samples: [], languageItems: [], paymentMethod: "undefined", // TODO use enum API endpoint for payment methods @@ -56,6 +57,7 @@ export default { this.$data.keywords = dataUtils.arrayToCommaSeperatedString(resource.keywords); this.$data.standardlicense = resource.standardlicense; this.$data.publisher = resource.publisher; + this.$data.samples = resource.samples; } } } diff --git a/src/pages/dataoffering/resources/resourcereferencedialog/ResourceReferenceDialog.css b/src/pages/dataoffering/resources/resourcereferencedialog/ResourceReferenceDialog.css new file mode 100644 index 00000000..077fc0f7 --- /dev/null +++ b/src/pages/dataoffering/resources/resourcereferencedialog/ResourceReferenceDialog.css @@ -0,0 +1,9 @@ +.res-ref-dialog-content { + padding-left: 30px !important; + padding-right: 30px !important; + min-height: 460px; +} + +.res-ref-search-tf { + margin-bottom: 15px; +} \ No newline at end of file diff --git a/src/pages/dataoffering/resources/resourcereferencedialog/ResourceReferenceDialog.html b/src/pages/dataoffering/resources/resourcereferencedialog/ResourceReferenceDialog.html new file mode 100644 index 00000000..4bfee29a --- /dev/null +++ b/src/pages/dataoffering/resources/resourcereferencedialog/ResourceReferenceDialog.html @@ -0,0 +1,23 @@ + + + + Resource References of {{ resource.title }} + + + + + + + + + + + + + + Save + + + \ No newline at end of file diff --git a/src/pages/dataoffering/resources/resourcereferencedialog/ResourceReferenceDialog.js b/src/pages/dataoffering/resources/resourcereferencedialog/ResourceReferenceDialog.js new file mode 100644 index 00000000..ee67b128 --- /dev/null +++ b/src/pages/dataoffering/resources/resourcereferencedialog/ResourceReferenceDialog.js @@ -0,0 +1,79 @@ +import dataUtils from "@/utils/dataUtils"; +import errorUtils from "../../../../utils/errorUtils"; + +export default { + data() { + return { + dialog: false, + search: '', + headers: [{ + text: 'Creation date', + value: 'creationDate', + width: 135 + }, { + text: 'Title', + value: 'title' + }, + { + text: 'Keywords', + value: 'keywords' + }, + { + text: 'Brokers', + value: 'brokerNames' + }, + { + text: '', + value: 'actions', + sortable: false, + align: 'right', + width: 170 + } + ], + resource: {}, + resources: [], + selected: [] + }; + }, + mounted: function () { }, + methods: { + async show(resourceId) { + this.$root.$emit('showBusyIndicator', true); + this.$data.selected = []; + try { + let allResources = await dataUtils.getResources(); + this.$data.resources = []; + for (let resource of allResources) { + if (resourceId != resource.id) { + this.$data.resources.push(resource); + } + } + this.$data.resource = await dataUtils.getResource(resourceId); + if (this.$data.resource.samples !== undefined) { + for (let sample of this.$data.resource.samples) { + this.$data.selected.push({ + "id": sample.substring(sample.lastIndexOf("/") + 1, sample.length), + "url": sample + }) + } + } + this.$data.dialog = true; + } catch (error) { + errorUtils.showError(error, "Get resources"); + } + this.$root.$emit('showBusyIndicator', false); + }, + async save() { + let samples = []; + for (let selectedResource of this.$data.selected) { + samples.push(selectedResource.url); + } + try { + dataUtils.updateResourceReferences(this.$data.resource, samples); + } catch (error) { + errorUtils.showError(error, "Update resource"); + } + this.$data.dialog = false; + } + } +}; diff --git a/src/pages/dataoffering/resources/resourcereferencedialog/ResourceReferenceDialog.vue b/src/pages/dataoffering/resources/resourcereferencedialog/ResourceReferenceDialog.vue new file mode 100644 index 00000000..c5fc1144 --- /dev/null +++ b/src/pages/dataoffering/resources/resourcereferencedialog/ResourceReferenceDialog.vue @@ -0,0 +1,3 @@ + + + diff --git a/src/pages/dataoffering/routes/addroute/dialog/editidsendpointdialog/EditIdsEndpointDialog.js b/src/pages/dataoffering/routes/addroute/dialog/editidsendpointdialog/EditIdsEndpointDialog.js index a2683548..75833fb8 100644 --- a/src/pages/dataoffering/routes/addroute/dialog/editidsendpointdialog/EditIdsEndpointDialog.js +++ b/src/pages/dataoffering/routes/addroute/dialog/editidsendpointdialog/EditIdsEndpointDialog.js @@ -32,7 +32,7 @@ export default { let resource; if (node == null) { this.$data.title = "Add IDS Endpoint"; - resource = clientDataModel.createResource(-1); + resource = clientDataModel.createResource("", -1); } else { this.$data.title = "Edit IDS Endpoint"; resource = node.resource; diff --git a/src/utils/dataUtils.js b/src/utils/dataUtils.js index f8fb7808..47b3d3dd 100644 --- a/src/utils/dataUtils.js +++ b/src/utils/dataUtils.js @@ -641,7 +641,7 @@ export default { }; }, - async editResource(resourceId, representationId, title, description, language, paymentMethod, keywords, standardlicense, publisher, + async editResource(resourceId, representationId, title, description, language, paymentMethod, keywords, standardlicense, publisher, samples, policyDescriptions, filetype, brokerUris, brokerDeleteUris, genericEndpoint, ruleId, artifactId) { try { await restUtils.callConnector("PUT", "/api/offers/" + resourceId, null, { @@ -651,7 +651,8 @@ export default { "publisher": publisher, "language": language, "paymentMethod": paymentMethod, - "license": standardlicense + "license": standardlicense, + "samples": samples }); // Delete all rules and create new ones. Rules that have not been edited in the UI are also deleted and recreated. @@ -699,6 +700,23 @@ export default { } }, + async updateResourceReferences(resource, samples) { + try { + await restUtils.callConnector("PUT", "/api/offers/" + resource.id, null, { + "title": resource.title, + "description": resource.description, + "keywords": resource.keywords, + "publisher": resource.publisher, + "language": resource.language, + "paymentMethod": resource.paymentMethod, + "license": resource.standardlicense, + "samples": samples + }); + } catch (error) { + errorUtils.showError(error, "Save resource"); + } + }, + async updateResourceBrokerRegistration(brokerUris, brokerDeleteUris, resourceId) { for (let brokerUri of brokerUris) { await this.updateResourceAtBroker(brokerUri, resourceId); @@ -1011,7 +1029,7 @@ export default { fileType = resource["ids:representation"][0]["ids:mediaType"]["ids:filenameExtension"]; } - resources.push(clientDataModel.createResource(id, creationDate, title, description, language, paymentMethod, keywords, version, standardlicense, + resources.push(clientDataModel.createResource(resource["@id"], id, creationDate, title, description, language, paymentMethod, keywords, version, standardlicense, publisher, fileType, "", null)); } } From 6caa6ba01a75eb4080c7334858edc948533bae94 Mon Sep 17 00:00:00 2001 From: Bastian Weltjen Date: Fri, 20 Aug 2021 11:33:17 +0200 Subject: [PATCH 13/13] docs: changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82686634..8791dbed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,13 @@ All notable changes to this project will be documented in this file. (Skipped major version 1, 2 and 3 to match versioning of IDS DataSpaceConnector) -## [8.4.0] - XXX-XX-XX +## [8.4.0] - 2021-08-20 ### Added - Data Consumption: Show list of requested resources - Backend Connections: API-Key authentication - Resources: Set payment method +- Resources: Set referenced resources ### Fixes - Data Consumption: Show download link to artifact of own connector