Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handling of multiple Concept Descriptions #138

Merged
merged 14 commits into from
Jun 3, 2024
Merged
35 changes: 19 additions & 16 deletions aas-gui/Frontend/aas-web-gui/src/components/SubmodelElementView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,13 @@
<AnnotatedRelationshipElement v-else-if="submodelElementData.modelType === 'AnnotatedRelationshipElement'" :annotatedRelationshipElementObject="submodelElementData"></AnnotatedRelationshipElement>
<InvalidElement v-else :invalidElementObject="submodelElementData"></InvalidElement>
</v-list>
<!-- ConceptDescription -->
<v-divider v-if="submodelElementData.conceptDescription" class="mt-5"></v-divider>
<v-list nav v-if="submodelElementData.conceptDescription">
<ConceptDescription :conceptDescriptionObject="submodelElementData.conceptDescription"></ConceptDescription>
<!-- ConceptDescriptions -->
<v-divider v-if="submodelElementData.conceptDescriptions" class="mt-5"></v-divider>
<v-list nav v-if="submodelElementData.conceptDescriptions">
seicke marked this conversation as resolved.
Show resolved Hide resolved
<v-list-item v-for="(conceptDescription, i) in submodelElementData.conceptDescriptions" :key="i">
seicke marked this conversation as resolved.
Show resolved Hide resolved
<ConceptDescription :conceptDescriptionObject="conceptDescription"></ConceptDescription>
<v-divider v-if="i != Object.keys(submodelElementData.conceptDescriptions).length - 1" class="mt-2"></v-divider>
</v-list-item>
</v-list>
<!-- Last Sync -->
<v-divider class="mt-5"></v-divider>
Expand Down Expand Up @@ -131,7 +134,7 @@ export default defineComponent({
data() {
return {
submodelElementData: {} as any, // SubmodelElement Data
conceptDescription: {} as any, // ConceptDescription Data
conceptDescriptions: {} as any, // Data of Concept Descriptions
seicke marked this conversation as resolved.
Show resolved Hide resolved
requestInterval: null as any, // interval to send requests to the AAS
}
},
Expand Down Expand Up @@ -242,7 +245,7 @@ export default defineComponent({

methods: {
// Initialize the Component
initializeView(withConceptDescription = false) {
initializeView(withConceptDescriptions = false) {
// console.log('Selected Node: ', this.SelectedNode);
// Check if a Node is selected
if (Object.keys(this.SelectedNode).length == 0) {
Expand All @@ -254,8 +257,8 @@ export default defineComponent({
let context = 'retrieving SubmodelElement';
let disableMessage = true;
this.getRequest(path, context, disableMessage).then((response: any) => {
// save embeddedDataSpecifications (ConceptDescription) before overwriting the SubmodelElement Data
let conceptDescription = this.submodelElementData.conceptDescription;
// save Concept Descriptions before overwriting the SubmodelElement Data
let conceptDescriptions = this.submodelElementData.conceptDescriptions;
if (response.success) { // execute if the Request was successful
response.data.timestamp = this.formatDate(new Date()); // add timestamp to the SubmodelElement Data
response.data.path = this.SelectedNode.path; // add the path to the SubmodelElement Data
Expand All @@ -273,31 +276,31 @@ export default defineComponent({
this.submodelElementData.timestamp = 'no sync';
this.submodelElementData.path = this.SelectedNode.path; // add the path to the SubmodelElement Data
}
if (withConceptDescription) {
this.getCD(); // fetch ConceptDescriptions for the SubmodelElement
if (withConceptDescriptions) {
this.getCD(); // fetch Concept Descriptions for the SubmodelElement
} else {
this.submodelElementData.conceptDescription = conceptDescription; // add the ConceptDescription to the SubmodelElement Data
this.submodelElementData.conceptDescriptions = conceptDescriptions; // add Concept Descriptions to the SubmodelElement Data
}
// console.log('SubmodelElement Data (SubmodelElementView): ', this.submodelElementData)
// add SubmodelElement Data to the store (as RealTimeDataObject)
this.aasStore.dispatchRealTimeObject(this.submodelElementData);
});
},

// Get the ConceptDescriptions for the SubmodelElement from the ConceptDescription Repository
// Get Concept Descriptions for the SubmodelElement from the ConceptDescription Repository
getCD() {
// Check if a Node is selected
if (Object.keys(this.SelectedNode).length == 0 || !this.SelectedNode.semanticId || !this.SelectedNode.semanticId.keys || this.SelectedNode.semanticId.keys.length == 0) {
this.conceptDescription = {}; // Reset the SubmodelElement Data when no Node is selected
this.conceptDescriptions = {}; // Reset the SubmodelElement Data when no Node is selected
return;
}
// call mixin to request concept description from the CD Repo
this.getConceptDescription(this.SelectedNode).then((response: any) => {
this.requestConceptDescriptions(this.SelectedNode).then((response: any) => {
// console.log('ConceptDescription: ', response)
this.conceptDescription = response;
this.conceptDescriptions = response;
// add ConceptDescription to the SubmodelElement Data
if (response ) {
this.submodelElementData.conceptDescription = response;
this.submodelElementData.conceptDescriptions = response;
}
});
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,9 +229,10 @@ export default defineComponent({
// request the concept descriptions for the records (if they have semanticIds)
// Create a list of promises
let promises = records.map((record: any) => {
return this.getConceptDescription(record).then((response: any) => {
return this.requestConceptDescriptions(record).then((response: any) => {
// console.log('Response: ', response, ' Record: ', record)
// check if the response is not an empty object and if it contains embeddedDataSpecifications
// TODO not tested, but it won't work that way
seicke marked this conversation as resolved.
Show resolved Hide resolved
if (response && Object.keys(response).length !== 0 && response.embeddedDataSpecifications) {
// create new property embeddedDataSpecifications in the record
record.embeddedDataSpecifications = response.embeddedDataSpecifications;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
</v-list>
<v-divider v-if="conceptDescriptionObject.embeddedDataSpecifications && conceptDescriptionObject.embeddedDataSpecifications.length > 0" class="mt-2"></v-divider>
<v-list nav v-if="conceptDescriptionObject.embeddedDataSpecifications && conceptDescriptionObject.embeddedDataSpecifications.length > 0">
<v-card v-for="(embeddedDataSpecification, i) in conceptDescriptionObject.embeddedDataSpecifications" :key="i"color="elevatedCard" class="mt-2">
<v-card v-for="(embeddedDataSpecification, i) in conceptDescriptionObject.embeddedDataSpecifications" :key="i" color="elevatedCard" class="mt-2">
<v-list nav class="bg-elevatedCard pt-0">
<!-- hasDataSpecification -->
<SemanticID v-if="embeddedDataSpecification.dataSpecification && embeddedDataSpecification.dataSpecification.keys && embeddedDataSpecification.dataSpecification.keys.length > 0" :semanticIdObject="embeddedDataSpecification.dataSpecification" :semanticTitle="'Data Specification'" class="mb-2"></SemanticID>
Expand Down
47 changes: 26 additions & 21 deletions aas-gui/Frontend/aas-web-gui/src/mixins/SubmodelElementHandling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -394,46 +394,51 @@ export default defineComponent({
}
},

// Get the ConceptDescriptions for the SubmodelElement from the ConceptDescription Repository
getConceptDescription(SelectedNode: any) {
// Get all ConceptDescriptions for the SubmodelElement from the ConceptDescription Repository
async requestConceptDescriptions(SelectedNode: any) {
seicke marked this conversation as resolved.
Show resolved Hide resolved
let conceptDescriptionRepoURL = '';
if (this.conceptDescriptionRepoURL && this.conceptDescriptionRepoURL != '') {
conceptDescriptionRepoURL = this.conceptDescriptionRepoURL;
} else {
return Promise.resolve({}); // Return an empty object wrapped in a resolved promise
}

// return if no SemanticID is available
if (!SelectedNode.semanticId || !SelectedNode.semanticId.keys || SelectedNode.semanticId.keys.length == 0) {
return Promise.resolve({});
}
let path = conceptDescriptionRepoURL + "/" + this.URLEncode(SelectedNode.semanticId.keys[0].value);
let context = 'retrieving ConceptDescription';
let disableMessage = true;

// Return the promise from getRequest
return this.getRequest(path, context, disableMessage).then((response: any) => {
if (response.success) {
// console.log('ConceptDescription Data: ', response.data);
let conceptDescription = response.data;
conceptDescription.path = path;
return conceptDescription;
} else {
return {};
}
let cdPromises = SelectedNode.semanticId.keys.map((key: any) => {

let path = conceptDescriptionRepoURL + "/" + this.URLEncode(key.value);
let context = 'retrieving ConceptDescriptions';
let disableMessage = true;

return this.getRequest(path, context, disableMessage).then((response: any) => {
if (response.success) {
// console.log('ConceptDescription Data: ', response.data);
let conceptDescription = response.data;
conceptDescription.path = path;
return conceptDescription;
} else {
return {};
}
});

});

let conceptDescriptions = await Promise.all(cdPromises);
return conceptDescriptions;

},

// calculate the pathes of the SubmodelElements in a provided Submodel/SubmodelElement
calculateSubmodelElementPathes(parent: any, startPath: string): any {
// console.log('Parent: ', parent, 'StartPath: ', startPath);
parent.path = startPath;
parent.id = this.UUID();
// get the conceptDescription for the SubmodelElement
this.getConceptDescription(parent).then((response: any) => {
if (response) {
parent.conceptDescription = response;
}
});
// get the Concept Descriptions for the SubmodelElement
parent.conceptDescriptions = this.requestConceptDescriptions(parent)
// check for children
if (parent.submodelElements && parent.submodelElements.length > 0) { // check for SubmodelElements
parent.submodelElements.forEach((element: any) => {
Expand Down
Loading