From 090052ff5158221d0489d5d2edf2d5f317767d1f Mon Sep 17 00:00:00 2001 From: Sebastian Eicke Date: Sun, 17 Nov 2024 12:53:39 +0100 Subject: [PATCH 01/10] Add folder structure for Visualizations + move existent Visualizations --- .../Dashboard/DashboardEditElement.vue | 2 +- .../components/Dashboard/DashboardElement.vue | 2 +- .../SubmodelPlugins/_SubmodelEntrypoint.vue | 22 +- .../CADPreview.vue | 0 .../ImagePreview.vue | 0 .../PDFPreview.vue | 0 .../Visualizations/SubmodelElements/Awg.vue | 207 ++++++++++++++++++ .../HTWFuehrungskomponente.vue | 0 .../SubmodelElements}/JSONArrayProperty.vue | 0 .../Submodels}/BillsOfMaterial.vue | 0 .../Submodels}/ContactInformation.vue | 12 +- .../Submodels}/DigitalNameplate.vue | 117 +++++----- .../Submodels}/HandoverDocumentation.vue | 16 +- .../Submodels}/TechnicalData.vue | 1 + .../Submodels}/TimeSeriesData.vue | 0 15 files changed, 307 insertions(+), 72 deletions(-) rename aas-web-ui/src/components/{SubmodelPlugins => Visualizations}/CADPreview.vue (100%) rename aas-web-ui/src/components/{SubmodelPlugins => Visualizations}/ImagePreview.vue (100%) rename aas-web-ui/src/components/{SubmodelPlugins => Visualizations}/PDFPreview.vue (100%) create mode 100644 aas-web-ui/src/components/Visualizations/SubmodelElements/Awg.vue rename aas-web-ui/src/components/{SubmodelPlugins => Visualizations/SubmodelElements}/HTWFuehrungskomponente.vue (100%) rename aas-web-ui/src/components/{SubmodelPlugins => Visualizations/SubmodelElements}/JSONArrayProperty.vue (100%) rename aas-web-ui/src/components/{SubmodelPlugins => Visualizations/Submodels}/BillsOfMaterial.vue (100%) rename aas-web-ui/src/components/{SubmodelPlugins => Visualizations/Submodels}/ContactInformation.vue (98%) rename aas-web-ui/src/components/{SubmodelPlugins => Visualizations/Submodels}/DigitalNameplate.vue (90%) rename aas-web-ui/src/components/{SubmodelPlugins => Visualizations/Submodels}/HandoverDocumentation.vue (97%) rename aas-web-ui/src/components/{SubmodelPlugins => Visualizations/Submodels}/TechnicalData.vue (99%) rename aas-web-ui/src/components/{SubmodelPlugins => Visualizations/Submodels}/TimeSeriesData.vue (100%) diff --git a/aas-web-ui/src/components/Dashboard/DashboardEditElement.vue b/aas-web-ui/src/components/Dashboard/DashboardEditElement.vue index 8360995..35dd025 100644 --- a/aas-web-ui/src/components/Dashboard/DashboardEditElement.vue +++ b/aas-web-ui/src/components/Dashboard/DashboardEditElement.vue @@ -86,7 +86,7 @@ diff --git a/aas-web-ui/src/components/SubmodelPlugins/HTWFuehrungskomponente.vue b/aas-web-ui/src/components/Visualizations/SubmodelElements/HTWFuehrungskomponente.vue similarity index 100% rename from aas-web-ui/src/components/SubmodelPlugins/HTWFuehrungskomponente.vue rename to aas-web-ui/src/components/Visualizations/SubmodelElements/HTWFuehrungskomponente.vue diff --git a/aas-web-ui/src/components/SubmodelPlugins/JSONArrayProperty.vue b/aas-web-ui/src/components/Visualizations/SubmodelElements/JSONArrayProperty.vue similarity index 100% rename from aas-web-ui/src/components/SubmodelPlugins/JSONArrayProperty.vue rename to aas-web-ui/src/components/Visualizations/SubmodelElements/JSONArrayProperty.vue diff --git a/aas-web-ui/src/components/SubmodelPlugins/BillsOfMaterial.vue b/aas-web-ui/src/components/Visualizations/Submodels/BillsOfMaterial.vue similarity index 100% rename from aas-web-ui/src/components/SubmodelPlugins/BillsOfMaterial.vue rename to aas-web-ui/src/components/Visualizations/Submodels/BillsOfMaterial.vue diff --git a/aas-web-ui/src/components/SubmodelPlugins/ContactInformation.vue b/aas-web-ui/src/components/Visualizations/Submodels/ContactInformation.vue similarity index 98% rename from aas-web-ui/src/components/SubmodelPlugins/ContactInformation.vue rename to aas-web-ui/src/components/Visualizations/Submodels/ContactInformation.vue index 08461bb..57fe4b0 100644 --- a/aas-web-ui/src/components/SubmodelPlugins/ContactInformation.vue +++ b/aas-web-ui/src/components/Visualizations/Submodels/ContactInformation.vue @@ -126,13 +126,19 @@ methods: { async initContactInformation() { this.loading = true; - // console.log('Initialize Contact Information Plugin: ', this.submodelElementData); + // Check if a Node is selected + if (Object.keys(this.submodelElementData).length == 0) { + this.contactInformationData = {}; // Reset the DigitalNameplate Data when no Node is selected + this.loading = false; + return; + } + let submodelElementData = { ...this.submodelElementData }; - submodelElementData = await this.calculateSubmodelElementPathes( + this.contactInformationData = await this.calculateSubmodelElementPathes( submodelElementData, this.SelectedNode.path ); - this.contactInformationData = submodelElementData; + // create array of contacts let contacts = this.contactInformationData.submodelElements.filter((element: any) => { return ( diff --git a/aas-web-ui/src/components/SubmodelPlugins/DigitalNameplate.vue b/aas-web-ui/src/components/Visualizations/Submodels/DigitalNameplate.vue similarity index 90% rename from aas-web-ui/src/components/SubmodelPlugins/DigitalNameplate.vue rename to aas-web-ui/src/components/Visualizations/Submodels/DigitalNameplate.vue index d55944e..76d0cbd 100644 --- a/aas-web-ui/src/components/SubmodelPlugins/DigitalNameplate.vue +++ b/aas-web-ui/src/components/Visualizations/Submodels/DigitalNameplate.vue @@ -268,6 +268,7 @@ // Check if a Node is selected if (Object.keys(this.submodelElementData).length == 0) { this.digitalNameplateData = {}; // Reset the DigitalNameplate Data when no Node is selected + this.loading = false; return; } let digitalNameplateData = { ...this.submodelElementData }; // create local copy of the Nameplate Object @@ -289,86 +290,86 @@ let productProperties = []; // console.log('Extract Product Properties:', digitalNameplateData); // find property with the idShort "URIOfTheProduct" and add that element to the productProperties array - let uriOfTheProduct = digitalNameplateData.submodelElements.find( - (element: any) => this.checkIdShort(element, 'URIOfTheProduct') + let uriOfTheProduct = digitalNameplateData.submodelElements.find((element: any) => + this.checkIdShort(element, 'URIOfTheProduct') ); if (uriOfTheProduct) { productProperties.push(uriOfTheProduct); } // find property with the idShort "ManufacturerProductDesignation" and add that element to the productProperties array - let manufacturerProductDesignation = digitalNameplateData.submodelElements.find( - (element: any) => this.checkIdShort(element, 'ManufacturerProductDesignation') + let manufacturerProductDesignation = digitalNameplateData.submodelElements.find((element: any) => + this.checkIdShort(element, 'ManufacturerProductDesignation') ); if (manufacturerProductDesignation) { productProperties.push(manufacturerProductDesignation); } // find property with the idShort "ManufacturerProductRoot" and add that element to the productProperties array - let manufacturerProductRoot = digitalNameplateData.submodelElements.find( - (element: any) => this.checkIdShort(element, 'ManufacturerProductRoot') + let manufacturerProductRoot = digitalNameplateData.submodelElements.find((element: any) => + this.checkIdShort(element, 'ManufacturerProductRoot') ); if (manufacturerProductRoot) { productProperties.push(manufacturerProductRoot); } // find property with the idShort "ManufacturerProductFamily" and add that element to the productProperties array - let manufacturerProductFamily = digitalNameplateData.submodelElements.find( - (element: any) => this.checkIdShort(element, 'ManufacturerProductFamily') + let manufacturerProductFamily = digitalNameplateData.submodelElements.find((element: any) => + this.checkIdShort(element, 'ManufacturerProductFamily') ); if (manufacturerProductFamily) { productProperties.push(manufacturerProductFamily); } // find property with the idShort "ManufacturerProductType" and add that element to the productProperties array - let manufacturerProductType = digitalNameplateData.submodelElements.find( - (element: any) => this.checkIdShort(element, 'ManufacturerProductType') + let manufacturerProductType = digitalNameplateData.submodelElements.find((element: any) => + this.checkIdShort(element, 'ManufacturerProductType') ); if (manufacturerProductType) { productProperties.push(manufacturerProductType); } // find property with the idShort "ProductArticleNumberOfManufacturer" and add that element to the productProperties array - let productArticleNumberOfManufacturer = digitalNameplateData.submodelElements.find( - (element: any) => this.checkIdShort(element, 'ProductArticleNumberOfManufacturer') + let productArticleNumberOfManufacturer = digitalNameplateData.submodelElements.find((element: any) => + this.checkIdShort(element, 'ProductArticleNumberOfManufacturer') ); if (productArticleNumberOfManufacturer) { productProperties.push(productArticleNumberOfManufacturer); } // find property with the idShort "SerialNumber" and add that element to the productProperties array - let serialNumber = digitalNameplateData.submodelElements.find( - (element: any) => this.checkIdShort(element, 'SerialNumber') + let serialNumber = digitalNameplateData.submodelElements.find((element: any) => + this.checkIdShort(element, 'SerialNumber') ); if (serialNumber) { productProperties.push(serialNumber); } // find property with the idShort "YearOfConstruction" and add that element to the productProperties array - let yearOfConstruction = digitalNameplateData.submodelElements.find( - (element: any) => this.checkIdShort(element, 'YearOfConstruction') + let yearOfConstruction = digitalNameplateData.submodelElements.find((element: any) => + this.checkIdShort(element, 'YearOfConstruction') ); if (yearOfConstruction) { productProperties.push(yearOfConstruction); } // find property with the idShort "DateOfManufacture" and add that element to the productProperties array - let dateOfManufacture = digitalNameplateData.submodelElements.find( - (element: any) => this.checkIdShort(element, 'DateOfManufacture') + let dateOfManufacture = digitalNameplateData.submodelElements.find((element: any) => + this.checkIdShort(element, 'DateOfManufacture') ); if (dateOfManufacture) { productProperties.push(dateOfManufacture); } let versions = []; // find property with the idShort "HardwareVersion" and add that element to the productProperties array - let hardwareVersion = digitalNameplateData.submodelElements.find( - (element: any) => this.checkIdShort(element, 'HardwareVersion') + let hardwareVersion = digitalNameplateData.submodelElements.find((element: any) => + this.checkIdShort(element, 'HardwareVersion') ); if (hardwareVersion) { versions.push(hardwareVersion); } // find property with the idShort "FirmwareVersion" and add that element to the productProperties array - let firmwareVersion = digitalNameplateData.submodelElements.find( - (element: any) => this.checkIdShort(element, 'FirmwareVersion') + let firmwareVersion = digitalNameplateData.submodelElements.find((element: any) => + this.checkIdShort(element, 'FirmwareVersion') ); if (firmwareVersion) { versions.push(firmwareVersion); } // find property with the idShort "SoftwareVersion" and add that element to the productProperties array - let softwareVersion = digitalNameplateData.submodelElements.find( - (element: any) => this.checkIdShort(element, 'SoftwareVersion') + let softwareVersion = digitalNameplateData.submodelElements.find((element: any) => + this.checkIdShort(element, 'SoftwareVersion') ); if (softwareVersion) { versions.push(softwareVersion); @@ -385,23 +386,23 @@ let manufacturerProperties = []; // console.log('Extract Manufacturer Properties:', digitalNameplateData); // find property with the idShort "CompanyLogo" and add that element to the manufacturerProperties array - let companyLogo = digitalNameplateData.submodelElements.find( - (element: any) => this.checkIdShort(element, 'CompanyLogo') + let companyLogo = digitalNameplateData.submodelElements.find((element: any) => + this.checkIdShort(element, 'CompanyLogo') ); if (companyLogo) { this.getImageUrl(companyLogo, 'companyLogoUrl'); manufacturerProperties.push(companyLogo); } // find property with the idShort "ManufacturerName" and add that element to the manufacturerProperties array - let manufacturerName = digitalNameplateData.submodelElements.find( - (element: any) => this.checkIdShort(element, 'ManufacturerName') + let manufacturerName = digitalNameplateData.submodelElements.find((element: any) => + this.checkIdShort(element, 'ManufacturerName') ); if (manufacturerName) { manufacturerProperties.push(manufacturerName); } // get the Contact Information - let contactInformation = digitalNameplateData.submodelElements.find( - (element: any) => this.checkIdShort(element, 'ContactInformation') + let contactInformation = digitalNameplateData.submodelElements.find((element: any) => + this.checkIdShort(element, 'ContactInformation') ); if (contactInformation) { // console.log('Contact Information:', contactInformation) @@ -412,19 +413,23 @@ } let address = ''; // find property with the idShort "NationalCode" and add that element to the manufacturerProperties array - let nationalCode = contactInformation.value.find( - (element: any) => this.checkIdShort(element, 'NationalCode') + let nationalCode = contactInformation.value.find((element: any) => + this.checkIdShort(element, 'NationalCode') ); if (nationalCode) { address += nationalCode.value[0].text + ' '; } // find property with the idShort "Zipcode" and add that element to the manufacturerProperties array - let zipcode = contactInformation.value.find((element: any) => this.checkIdShort(element, 'Zipcode')); + let zipcode = contactInformation.value.find((element: any) => + this.checkIdShort(element, 'Zipcode') + ); if (zipcode) { address += zipcode.value[0].text + ' '; } // find property with the idShort "City" and add that element to the manufacturerProperties array - let cityTown = contactInformation.value.find((element: any) => this.checkIdShort(element, 'CityTown')); + let cityTown = contactInformation.value.find((element: any) => + this.checkIdShort(element, 'CityTown') + ); if (cityTown) { address += cityTown.value[0].text; } @@ -436,7 +441,9 @@ let phone = contactInformation.value.find((element: any) => this.checkIdShort(element, 'Phone')); if (phone) { // find property with the idShort "TelephoneNumber" and add that element to the manufacturerProperties array - let telephoneNumber = phone.value.find((element: any) => this.checkIdShort(element, 'TelephoneNumber')); + let telephoneNumber = phone.value.find((element: any) => + this.checkIdShort(element, 'TelephoneNumber') + ); if (telephoneNumber) { manufacturerProperties.push(telephoneNumber); } @@ -454,15 +461,17 @@ let email = contactInformation.value.find((element: any) => this.checkIdShort(element, 'Email')); if (email) { // find property with the idShort "EmailAddress" and add that element to the manufacturerProperties array - let emailAddress = email.value.find((element: any) => this.checkIdShort(element, 'EmailAddress')); + let emailAddress = email.value.find((element: any) => + this.checkIdShort(element, 'EmailAddress') + ); if (emailAddress) { manufacturerProperties.push(emailAddress); } } } // find property with the idShort "OrderCodeOfManufacturer" and add that element to the manufacturerProperties array - let orderCodeOfManufacturer = digitalNameplateData.submodelElements.find( - (element: any) => this.checkIdShort(element, 'OrderCodeOfManufacturer') + let orderCodeOfManufacturer = digitalNameplateData.submodelElements.find((element: any) => + this.checkIdShort(element, 'OrderCodeOfManufacturer') ); if (orderCodeOfManufacturer) { manufacturerProperties.push(orderCodeOfManufacturer); @@ -473,16 +482,20 @@ // Function to extract the Markings extractMarkings(digitalNameplateData: any) { - let markings = digitalNameplateData.submodelElements.find( - (element: any) => this.checkIdShort(element, 'Markings') + let markings = digitalNameplateData.submodelElements.find((element: any) => + this.checkIdShort(element, 'Markings') ); let formattedMarkings = [] as Array; if (markings?.value) { markings.value.forEach((marking: any) => { // find property with the idShort "MarkingFile" - let markingFile = marking.value.find((element: any) => this.checkIdShort(element, 'MarkingFile')); + let markingFile = marking.value.find((element: any) => + this.checkIdShort(element, 'MarkingFile') + ); // find property with the idShort "MarkingName" - let markingName = marking.value.find((element: any) => this.checkIdShort(element, 'MarkingName')); + let markingName = marking.value.find((element: any) => + this.checkIdShort(element, 'MarkingName') + ); // create the formatted Marking Object let formattedMarking = { idShort: marking.idShort, @@ -500,8 +513,8 @@ // Function to extract the Asset Specific Properties extractAssetSpecificProperties(digitalNameplateData: any) { - let assetSpecificProperties = digitalNameplateData.submodelElements.find( - (element: any) => this.checkIdShort(element, 'AssetSpecificProperties') + let assetSpecificProperties = digitalNameplateData.submodelElements.find((element: any) => + this.checkIdShort(element, 'AssetSpecificProperties') ); if (assetSpecificProperties) { // console.log('Asset Specific Properties:', assetSpecificProperties); @@ -512,14 +525,16 @@ generateVCard(manufacturerProperties: any[]): string { let vCard = 'BEGIN:VCARD\nVERSION:3.0\n'; - let manufacturerName = manufacturerProperties.find( - (element: any) => this.checkIdShort(element, 'ManufacturerName') + let manufacturerName = manufacturerProperties.find((element: any) => + this.checkIdShort(element, 'ManufacturerName') ); if (manufacturerName) { vCard += 'FN:' + manufacturerName.value[0].text + '\n'; } - let companyLogo = manufacturerProperties.find((element: any) => this.checkIdShort(element, 'CompanyLogo')); + let companyLogo = manufacturerProperties.find((element: any) => + this.checkIdShort(element, 'CompanyLogo') + ); if (companyLogo) { vCard += 'PHOTO;MEDIATYPE=image/jpeg:' + companyLogo.value[0].text + '\n'; } @@ -529,8 +544,8 @@ vCard += 'ADR;TYPE=WORK:;;' + address.value + ';;;\n'; } - let telephoneNumber = manufacturerProperties.find( - (element: any) => this.checkIdShort(element, 'TelephoneNumber') + let telephoneNumber = manufacturerProperties.find((element: any) => + this.checkIdShort(element, 'TelephoneNumber') ); if (telephoneNumber) { vCard += 'TEL;TYPE=WORK,VOICE:' + telephoneNumber.value[0].text + '\n'; @@ -541,7 +556,9 @@ vCard += 'TEL;TYPE=WORK,FAX:' + faxNumber.value[0].text + '\n'; } - let emailAddress = manufacturerProperties.find((element: any) => this.checkIdShort(element, 'EmailAddress')); + let emailAddress = manufacturerProperties.find((element: any) => + this.checkIdShort(element, 'EmailAddress') + ); if (emailAddress) { vCard += 'EMAIL;TYPE=WORK:' + emailAddress.value + '\n'; } diff --git a/aas-web-ui/src/components/SubmodelPlugins/HandoverDocumentation.vue b/aas-web-ui/src/components/Visualizations/Submodels/HandoverDocumentation.vue similarity index 97% rename from aas-web-ui/src/components/SubmodelPlugins/HandoverDocumentation.vue rename to aas-web-ui/src/components/Visualizations/Submodels/HandoverDocumentation.vue index da43f12..ca96624 100644 --- a/aas-web-ui/src/components/SubmodelPlugins/HandoverDocumentation.vue +++ b/aas-web-ui/src/components/Visualizations/Submodels/HandoverDocumentation.vue @@ -266,12 +266,12 @@ diff --git a/aas-web-ui/src/components/Visualizations/SubmodelElements/Awg.vue b/aas-web-ui/src/components/Visualizations/SubmodelElements/Awg.vue deleted file mode 100644 index 1b57ab0..0000000 --- a/aas-web-ui/src/components/Visualizations/SubmodelElements/Awg.vue +++ /dev/null @@ -1,207 +0,0 @@ - - - diff --git a/aas-web-ui/src/components/Visualizations/SubmodelElements/HTWFuehrungskomponente.vue b/aas-web-ui/src/components/Visualizations/SubmodelElements/HTWFuehrungskomponente.vue index 9e074a6..d8a9d80 100644 --- a/aas-web-ui/src/components/Visualizations/SubmodelElements/HTWFuehrungskomponente.vue +++ b/aas-web-ui/src/components/Visualizations/SubmodelElements/HTWFuehrungskomponente.vue @@ -1118,6 +1118,7 @@ export default defineComponent({ name: 'HTWFuehrungskomponente', + semanticId: 'http://htw-berlin.de/smc_statemachine', mixins: [RequestHandling, SubmodelElementHandling], props: ['submodelElementData', 'selectedNode'], diff --git a/aas-web-ui/src/components/Visualizations/SubmodelElements/JSONArrayProperty.vue b/aas-web-ui/src/components/Visualizations/SubmodelElements/JSONArrayProperty.vue index d739dfa..3000249 100644 --- a/aas-web-ui/src/components/Visualizations/SubmodelElements/JSONArrayProperty.vue +++ b/aas-web-ui/src/components/Visualizations/SubmodelElements/JSONArrayProperty.vue @@ -13,6 +13,7 @@ export default defineComponent({ name: 'JSONArrayProperty', + semanticId: 'http://iese.fraunhofer.de/prop_jsonarray', props: ['submodelElementData'], setup() { diff --git a/aas-web-ui/src/components/Visualizations/Submodels/BillsOfMaterial.vue b/aas-web-ui/src/components/Visualizations/Submodels/BillsOfMaterial.vue index 259581e..33a7602 100644 --- a/aas-web-ui/src/components/Visualizations/Submodels/BillsOfMaterial.vue +++ b/aas-web-ui/src/components/Visualizations/Submodels/BillsOfMaterial.vue @@ -41,6 +41,10 @@ export default defineComponent({ name: 'BillsOfMaterial', + semanticId: [ + 'https://admin-shell.io/idta/HierarchicalStructures/1/0/Submodel', + 'https://admin-shell.io/idta/HierarchicalStructures/1/1/Submodel', + ], mixins: [RequestHandling, SubmodelElementHandling], props: ['submodelElementData'], diff --git a/aas-web-ui/src/components/Visualizations/Submodels/ContactInformation.vue b/aas-web-ui/src/components/Visualizations/Submodels/ContactInformation.vue index 57fe4b0..0c2c0cb 100644 --- a/aas-web-ui/src/components/Visualizations/Submodels/ContactInformation.vue +++ b/aas-web-ui/src/components/Visualizations/Submodels/ContactInformation.vue @@ -90,6 +90,7 @@ export default defineComponent({ name: 'ContactInformation', + semanticId: 'https://admin-shell.io/zvei/nameplate/1/0/ContactInformations', mixins: [RequestHandling, SubmodelElementHandling], props: ['submodelElementData'], diff --git a/aas-web-ui/src/components/Visualizations/Submodels/DigitalNameplate.vue b/aas-web-ui/src/components/Visualizations/Submodels/DigitalNameplate.vue index 76d0cbd..89c7e21 100644 --- a/aas-web-ui/src/components/Visualizations/Submodels/DigitalNameplate.vue +++ b/aas-web-ui/src/components/Visualizations/Submodels/DigitalNameplate.vue @@ -211,6 +211,7 @@ export default defineComponent({ name: 'DigitalNameplate', + semanticId: 'https://admin-shell.io/zvei/nameplate/2/0/Nameplate', components: { GenericDataVisu, diff --git a/aas-web-ui/src/components/Visualizations/Submodels/HandoverDocumentation.vue b/aas-web-ui/src/components/Visualizations/Submodels/HandoverDocumentation.vue index ca96624..150aa31 100644 --- a/aas-web-ui/src/components/Visualizations/Submodels/HandoverDocumentation.vue +++ b/aas-web-ui/src/components/Visualizations/Submodels/HandoverDocumentation.vue @@ -275,6 +275,7 @@ export default defineComponent({ name: 'HandoverDocumentation', + semanticId: '0173-1#01-AHF578#001', components: { ImagePreview, PDFPreview, diff --git a/aas-web-ui/src/components/Visualizations/Submodels/TechnicalData.vue b/aas-web-ui/src/components/Visualizations/Submodels/TechnicalData.vue index 52d2552..4d1191d 100644 --- a/aas-web-ui/src/components/Visualizations/Submodels/TechnicalData.vue +++ b/aas-web-ui/src/components/Visualizations/Submodels/TechnicalData.vue @@ -256,6 +256,7 @@ export default defineComponent({ name: 'TechnicalData', + semanticId: 'https://admin-shell.io/ZVEI/TechnicalData/Submodel/1/2', components: { GenericDataVisu, GenericDataTableView, diff --git a/aas-web-ui/src/components/Visualizations/Submodels/TimeSeriesData.vue b/aas-web-ui/src/components/Visualizations/Submodels/TimeSeriesData.vue index 8a032e1..cd02ca0 100644 --- a/aas-web-ui/src/components/Visualizations/Submodels/TimeSeriesData.vue +++ b/aas-web-ui/src/components/Visualizations/Submodels/TimeSeriesData.vue @@ -208,6 +208,7 @@ export default defineComponent({ name: 'TimeSeriesData', + semanticId: 'https://admin-shell.io/idta/TimeSeries/1/1', components: { LineChart, AreaChart, diff --git a/aas-web-ui/src/main.ts b/aas-web-ui/src/main.ts index 8f23faf..4506d19 100644 --- a/aas-web-ui/src/main.ts +++ b/aas-web-ui/src/main.ts @@ -4,12 +4,6 @@ * Bootstraps Vuetify and other plugins then mounts the App` */ -// Types -interface PluginType { - name: string; - semanticId: string; -} - // Components import Keycloak from 'keycloak-js'; import { KeycloakOnLoad } from 'keycloak-js'; @@ -24,13 +18,13 @@ import App from './App.vue'; import { createAppRouter } from './router'; import { useAuthStore } from './store/AuthStore'; import { useEnvStore } from './store/EnvironmentStore'; -import { useNavigationStore } from './store/NavigationStore'; +import { useNavigationStore, VisualizationType } from './store/NavigationStore'; const app = createApp(App); const pinia = createPinia(); -async function loadUserPlugins() { +async function loadVisualizations() { const router = await createAppRouter(); app.use(router); @@ -52,23 +46,33 @@ async function loadUserPlugins() { await registerPlugins(app); - // Load all components in the components folder - const pluginFiles = import.meta.glob('./UserPlugins/*.vue'); - const files = Object.keys(pluginFiles); + const visualizationFileRecords = { + ...import.meta.glob('./components/Visualizations/Submodels/*.vue'), + ...import.meta.glob('./components/Visualizations/SubmodelElements/*.vue'), + ...import.meta.glob('./UserVisualizations/*.vue'), + }; + + const visualizationFiles = Object.keys(visualizationFileRecords); - const plugins = [] as Array; + const visualizations = [] as Array; await Promise.all( - files.map(async (path) => { - const componentName = path.replace('./UserPlugins/', '').replace('.vue', ''); - const component: any = await pluginFiles[path](); - app.component(componentName, (component.default || component) as ReturnType); - plugins.push({ name: componentName, semanticId: component.default.semanticId }); + visualizationFiles.map(async (path) => { + const componentName = path + .replace('./components/Visualizations/Submodels/', '') + .replace('./components/Visualizations/SubmodelElements/', '') + .replace('./UserVisualizations/', '') + .replace('.vue', ''); + const component: any = await visualizationFileRecords[path](); + if (component.default.semanticId) { + app.component(componentName, (component.default || component) as ReturnType); + visualizations.push({ name: componentName, semanticId: component.default.semanticId }); + } }) ); - const navigationStore = useNavigationStore(); // Get the store instance - navigationStore.dispatchPlugins(plugins); // Update the plugins state + const navigationStore = useNavigationStore(); + navigationStore.dispatchVisualizations(visualizations); app.mount('#app'); } @@ -135,4 +139,4 @@ async function initKeycloak(keycloakUrl: string, keycloakRealm: string, keycloak }); } -loadUserPlugins(); +loadVisualizations(); diff --git a/aas-web-ui/src/store/NavigationStore.ts b/aas-web-ui/src/store/NavigationStore.ts index a9ce91d..3d4f10d 100644 --- a/aas-web-ui/src/store/NavigationStore.ts +++ b/aas-web-ui/src/store/NavigationStore.ts @@ -29,7 +29,7 @@ export interface PlatformType { win: boolean; } -export interface PluginType { +export interface VisualizationType { name: string; semanticId: string; } @@ -53,7 +53,7 @@ export const useNavigationStore = defineStore({ StatusCheck: false as boolean, isMobile: false as boolean, platform: {} as PlatformType, - plugins: [] as PluginType[], + visualizations: [] as VisualizationType[], triggerAASListReload: false as boolean, triggerAASListScroll: false as boolean, triggerAASSelected: false as boolean, @@ -72,7 +72,7 @@ export const useNavigationStore = defineStore({ getStatusCheck: (state) => state.StatusCheck, getIsMobile: (state) => state.isMobile, getPlatform: (state) => state.platform, - getPlugins: (state) => state.plugins, + getVisualizations: (state) => state.visualizations, getTriggerAASListReload: (state) => state.triggerAASListReload, getTriggerAASListScroll: (state) => state.triggerAASListScroll, getTriggerAASSelected: (state) => state.triggerAASSelected, @@ -121,8 +121,8 @@ export const useNavigationStore = defineStore({ dispatchPlatform(platform: PlatformType) { this.platform = platform; }, - dispatchPlugins(plugins: Array) { - this.plugins = plugins; + dispatchVisualizations(visualizations: Array) { + this.visualizations = visualizations; }, dispatchTriggerAASListReload(triggerAASListReload: boolean) { this.triggerAASListReload = triggerAASListReload; From d6fb54e8c3e573b196308f782ab9f17df73e9b90 Mon Sep 17 00:00:00 2001 From: Sebastian Eicke Date: Sun, 17 Nov 2024 14:25:19 +0100 Subject: [PATCH 03/10] Cleanup --- .../src/UserVisualizations/HelloWorldVisualization.vue | 2 +- .../Visualizations/SubmodelElements/JSONArrayProperty.vue | 2 +- .../Visualizations/Submodels/ContactInformation.vue | 2 +- .../Visualizations/Submodels/DigitalNameplate.vue | 6 ++++-- .../Visualizations/Submodels/HandoverDocumentation.vue | 3 ++- .../components/Visualizations/Submodels/TechnicalData.vue | 3 ++- .../components/Visualizations/Submodels/TimeSeriesData.vue | 2 +- 7 files changed, 12 insertions(+), 8 deletions(-) diff --git a/aas-web-ui/src/UserVisualizations/HelloWorldVisualization.vue b/aas-web-ui/src/UserVisualizations/HelloWorldVisualization.vue index 54dab20..0468dbc 100644 --- a/aas-web-ui/src/UserVisualizations/HelloWorldVisualization.vue +++ b/aas-web-ui/src/UserVisualizations/HelloWorldVisualization.vue @@ -65,11 +65,11 @@ methods: { // Function to initialize the HelloWorld-Plugin initializePlugin() { - // Check if a Node is selected if (Object.keys(this.submodelElementData).length == 0) { this.pluginData = {}; // Reset the Plugin Data when no Node is selected return; } + let pluginData = { ...this.submodelElementData }; // Get the SubmodelElement from the AAS let pluginSubmodelElements = pluginData.submodelElements; // add pathes and id's to the SubmodelElements diff --git a/aas-web-ui/src/components/Visualizations/SubmodelElements/JSONArrayProperty.vue b/aas-web-ui/src/components/Visualizations/SubmodelElements/JSONArrayProperty.vue index 3000249..6fd7e9b 100644 --- a/aas-web-ui/src/components/Visualizations/SubmodelElements/JSONArrayProperty.vue +++ b/aas-web-ui/src/components/Visualizations/SubmodelElements/JSONArrayProperty.vue @@ -113,10 +113,10 @@ methods: { initChart() { - // Check if a Node is selected if (Object.keys(this.submodelElementData).length == 0) { return; } + let chartData = JSON.parse(this.submodelElementData.value); // parse the value of the SubmodelElement let seriesName = this.submodelElementData.idShort; // get the idShort of the SubmodelElement // check if the value is an array or an object diff --git a/aas-web-ui/src/components/Visualizations/Submodels/ContactInformation.vue b/aas-web-ui/src/components/Visualizations/Submodels/ContactInformation.vue index 0c2c0cb..16b72e9 100644 --- a/aas-web-ui/src/components/Visualizations/Submodels/ContactInformation.vue +++ b/aas-web-ui/src/components/Visualizations/Submodels/ContactInformation.vue @@ -127,7 +127,7 @@ methods: { async initContactInformation() { this.loading = true; - // Check if a Node is selected + if (Object.keys(this.submodelElementData).length == 0) { this.contactInformationData = {}; // Reset the DigitalNameplate Data when no Node is selected this.loading = false; diff --git a/aas-web-ui/src/components/Visualizations/Submodels/DigitalNameplate.vue b/aas-web-ui/src/components/Visualizations/Submodels/DigitalNameplate.vue index 89c7e21..00c36de 100644 --- a/aas-web-ui/src/components/Visualizations/Submodels/DigitalNameplate.vue +++ b/aas-web-ui/src/components/Visualizations/Submodels/DigitalNameplate.vue @@ -266,17 +266,19 @@ // Function to initialize the Digital Nameplate async initializeDigitalNameplate() { this.loading = true; - // Check if a Node is selected + if (Object.keys(this.submodelElementData).length == 0) { this.digitalNameplateData = {}; // Reset the DigitalNameplate Data when no Node is selected this.loading = false; return; } + let digitalNameplateData = { ...this.submodelElementData }; // create local copy of the Nameplate Object this.digitalNameplateData = await this.calculateSubmodelElementPathes( digitalNameplateData, this.SelectedNode.path - ); // Set the DigitalNameplate Data + ); + // console.log('Digital Nameplate Data:', this.digitalNameplateData); this.extractProductProperties(digitalNameplateData); // Extract the Product Properties this.extractManufacturerProperties(digitalNameplateData); // Extract the Manufacturer Properties diff --git a/aas-web-ui/src/components/Visualizations/Submodels/HandoverDocumentation.vue b/aas-web-ui/src/components/Visualizations/Submodels/HandoverDocumentation.vue index 150aa31..6c13fe8 100644 --- a/aas-web-ui/src/components/Visualizations/Submodels/HandoverDocumentation.vue +++ b/aas-web-ui/src/components/Visualizations/Submodels/HandoverDocumentation.vue @@ -317,7 +317,7 @@ methods: { async initHandoverDocumentation() { this.loading = true; - // Check if a Node is selected + if (Object.keys(this.submodelElementData).length == 0) { this.handoverDocuData = {}; // Reset the DigitalNameplate Data when no Node is selected this.loading = false; @@ -328,6 +328,7 @@ submodelElementData, this.SelectedNode.path ); + // create array of documents let documents = this.handoverDocuData.submodelElements.filter((element: any) => { return this.checkSemanticId(element, '0173-1#02-ABI500#001/0173-1#01-AHF579#001'); diff --git a/aas-web-ui/src/components/Visualizations/Submodels/TechnicalData.vue b/aas-web-ui/src/components/Visualizations/Submodels/TechnicalData.vue index 4d1191d..afaff93 100644 --- a/aas-web-ui/src/components/Visualizations/Submodels/TechnicalData.vue +++ b/aas-web-ui/src/components/Visualizations/Submodels/TechnicalData.vue @@ -303,12 +303,13 @@ methods: { async initTechnicalData() { this.loading = true; - // Check if a Node is selected + if (Object.keys(this.submodelElementData).length == 0) { this.technicalData = {}; // Reset the DigitalNameplate Data when no Node is selected this.loading = false; return; } + let technicalData = { ...this.submodelElementData }; // create local copy of the Nameplate Object this.technicalData = await this.calculateSubmodelElementPathes(technicalData, this.SelectedNode.path); // Set the DigitalNameplate Data this.extractGeneralProperties(technicalData); diff --git a/aas-web-ui/src/components/Visualizations/Submodels/TimeSeriesData.vue b/aas-web-ui/src/components/Visualizations/Submodels/TimeSeriesData.vue index cd02ca0..f80da45 100644 --- a/aas-web-ui/src/components/Visualizations/Submodels/TimeSeriesData.vue +++ b/aas-web-ui/src/components/Visualizations/Submodels/TimeSeriesData.vue @@ -325,11 +325,11 @@ methods: { // Function to initialize the TimeSeriesData Plugin initializeTimeSeriesData() { - // Check if a Node is selected if (Object.keys(this.submodelElementData).length == 0) { this.timeSeriesData = {}; // Reset the TimeSeriesData when no Node is selected return; } + let timeSeriesData = { ...this.submodelElementData }; // create local copy of the TimeSeriesData this.timeSeriesData = timeSeriesData; // set the local copy to the data object // get the collection for segments From 9225fa9bfc2ace4071d0923e41a21e12aea17fbe Mon Sep 17 00:00:00 2001 From: Sebastian Eicke Date: Sat, 7 Dec 2024 08:53:02 +0100 Subject: [PATCH 04/10] Back to Plugin wording --- README.md | 12 +++---- .../HelloWorldPlugin.vue} | 2 +- .../src/components/ComponentVisualization.vue | 22 ++++++------- .../Dashboard/DashboardEditElement.vue | 2 +- .../components/Dashboard/DashboardElement.vue | 2 +- .../CADPreview.vue | 0 .../ImagePreview.vue | 0 .../PDFPreview.vue | 0 .../HTWFuehrungskomponente.vue | 0 .../SubmodelElements/JSONArrayProperty.vue | 0 .../Submodels/BillsOfMaterial.vue | 0 .../Submodels/ContactInformation.vue | 0 .../Submodels/DigitalNameplate.vue | 0 .../Submodels/HandoverDocumentation.vue | 6 ++-- .../Submodels/TechnicalData.vue | 0 .../Submodels/TimeSeriesData.vue | 0 aas-web-ui/src/main.ts | 32 +++++++++---------- aas-web-ui/src/store/NavigationStore.ts | 10 +++--- 18 files changed, 44 insertions(+), 44 deletions(-) rename aas-web-ui/src/{UserVisualizations/HelloWorldVisualization.vue => UserPlugins/HelloWorldPlugin.vue} (99%) rename aas-web-ui/src/components/{Visualizations => Plugins}/CADPreview.vue (100%) rename aas-web-ui/src/components/{Visualizations => Plugins}/ImagePreview.vue (100%) rename aas-web-ui/src/components/{Visualizations => Plugins}/PDFPreview.vue (100%) rename aas-web-ui/src/components/{Visualizations => Plugins}/SubmodelElements/HTWFuehrungskomponente.vue (100%) rename aas-web-ui/src/components/{Visualizations => Plugins}/SubmodelElements/JSONArrayProperty.vue (100%) rename aas-web-ui/src/components/{Visualizations => Plugins}/Submodels/BillsOfMaterial.vue (100%) rename aas-web-ui/src/components/{Visualizations => Plugins}/Submodels/ContactInformation.vue (100%) rename aas-web-ui/src/components/{Visualizations => Plugins}/Submodels/DigitalNameplate.vue (100%) rename aas-web-ui/src/components/{Visualizations => Plugins}/Submodels/HandoverDocumentation.vue (99%) rename aas-web-ui/src/components/{Visualizations => Plugins}/Submodels/TechnicalData.vue (100%) rename aas-web-ui/src/components/{Visualizations => Plugins}/Submodels/TimeSeriesData.vue (100%) diff --git a/README.md b/README.md index 94827fa..4c06553 100644 --- a/README.md +++ b/README.md @@ -50,19 +50,19 @@ As of now, not all new SubmodelElements of the AAS V3 are supported. Additional See examples in the [basyx-java-server-sdk](https://github.com/eclipse-basyx/basyx-java-server-sdk/tree/main/examples ) Repository. -### Visualizations Development +### Plugin Development -The BaSyx-UI includes a Feature to develop your own Visualizations. They can be used to display and interact with a Submodel (and/or SubmodelElements). +The BaSyx-UI includes a Feature to develop your own Plugins. They can be used to display and interact with a Submodel (and/or SubmodelElements). -Visualizations will be displayed in the `Visualization`-Part of the UI. In order for Visualizations to be loaded, a Submodel(Element) has to have a SemanticID which matches with the configured `semanticId` of the desired Visualizations. The configuration of a Visualizations `semanticId`can be done via a string (e.g. `'http://hello.world.de/plugin_submodel'`) or via an array for multiple SemanticIds (e.g. `['http://hello.world.de/plugin_submodel', 'http://hello.world.de/plugin_property']`) +Plugin will be displayed in the `Visualization`-Part of the UI. In order for Plugin to be loaded, a Submodel(Element) has to have a SemanticID which matches with the configured `semanticId` of the desired Plugin. The configuration of a Plugin `semanticId`can be done via a string (e.g. `'http://hello.world.de/plugin_submodel'`) or via an array for multiple SemanticIds (e.g. `['http://hello.world.de/plugin_submodel', 'http://hello.world.de/plugin_property']`) -To include your own Visualizations, you have to create a Vue.js Component and add it to the `UserVisualizations`-Folder in the `aas-web-ui/src`-Directory. The Visualization will then be automatically loaded and displayed in the UI. +To include your own Plugins, you have to create a Vue.js Component and add it to the `UserPlugins`-Folder in the `aas-web-ui/src`-Directory. The Plugin will then be automatically loaded and displayed in the UI. > If you plan on including your own plugins, keep in mind that you have to build the Docker Image yourself! -A Demo-Visualizations can be found here: +A Demo-Plugin can be found here: -[HelloWorldVisualizations.vue](./aas-web-ui/src/UserVisualizations/HelloWorldVisualizations.vue) +[HelloWorldPlugin.vue](./aas-web-ui/src/UserPlugins/HelloWorldPlugin.vue) ### Prerequisites for developing on you own machine diff --git a/aas-web-ui/src/UserVisualizations/HelloWorldVisualization.vue b/aas-web-ui/src/UserPlugins/HelloWorldPlugin.vue similarity index 99% rename from aas-web-ui/src/UserVisualizations/HelloWorldVisualization.vue rename to aas-web-ui/src/UserPlugins/HelloWorldPlugin.vue index 0468dbc..261086f 100644 --- a/aas-web-ui/src/UserVisualizations/HelloWorldVisualization.vue +++ b/aas-web-ui/src/UserPlugins/HelloWorldPlugin.vue @@ -25,7 +25,7 @@ import { useAASStore } from '@/store/AASDataStore'; export default defineComponent({ - name: 'HelloWorldVisualization', + name: 'HelloWorldPlugin', // semanticId: 'http://hello.world.de/plugin_submodel', // semanticId of the HelloWorld-Plugin as string semanticId: ['http://hello.world.de/plugin_submodel', 'http://hello.world.de/plugin_property'], // semanticId of the HelloWorld-Plugin as array to use multiple semanticIds components: { diff --git a/aas-web-ui/src/components/ComponentVisualization.vue b/aas-web-ui/src/components/ComponentVisualization.vue index e93920c..f4d4b42 100644 --- a/aas-web-ui/src/components/ComponentVisualization.vue +++ b/aas-web-ui/src/components/ComponentVisualization.vue @@ -52,14 +52,14 @@ @@ -70,10 +70,10 @@