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

Work on AASList / AASListDetails / AASTreeview / SubmodelList #135

Merged
merged 34 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
7bafde0
Not closeable DetailsCard anymore
seicke Dec 8, 2024
06909d3
Add ENV variable singleAasRedirect
seicke Dec 8, 2024
364261c
Add redirect if no existing aas path in URL
seicke Dec 8, 2024
0988f3a
Adapt AASList/AASListDetails for ENV singleAasRedirect
seicke Dec 8, 2024
f2ee96d
Harmonize AASUpload button with AASListRefresh button
seicke Dec 8, 2024
8c3ff6b
Avoid nested v-card for AASListDetails
seicke Dec 8, 2024
690c134
Add check for valid URL
seicke Dec 8, 2024
3e20f55
Fix background color of v-main
seicke Dec 8, 2024
9b43d80
Fix initial config.json
seicke Dec 8, 2024
86555b9
delete console.logs
seicke Dec 8, 2024
5296f26
Simplify dispatching AAS
seicke Dec 8, 2024
3969cc9
Add missing this.aasStore.dispatchLoadingState(false);
seicke Dec 8, 2024
0de1212
Merge branch 'main' into single-aas
seicke Dec 11, 2024
69f2965
Fixes height calculations in AASLIst
aaronzi Dec 13, 2024
a37b813
Introduce ENV variable singleAas + integrate PR #147
seicke Dec 15, 2024
6f56472
Fix response data error in App.vue
seicke Dec 15, 2024
50caf5d
Add ReferenceType to ReferenceElement.vue
seicke Dec 15, 2024
b932c7a
Adaption AASListDetails for missing assetKind of assetInformation
seicke Dec 16, 2024
6375420
Work on Reference checks and jumps
seicke Dec 16, 2024
e173c44
Harmonize globalAssetId design of Entity with design of AssetInformation
seicke Dec 16, 2024
2c71717
Add TODO regarding checkReference
seicke Dec 16, 2024
84dd838
Comment console.log
seicke Dec 16, 2024
45ec52f
Merge branch 'main' into single-aas
seicke Dec 16, 2024
0f7be21
Precises variable names
seicke Dec 16, 2024
0064c8c
Comment console.logs
seicke Dec 16, 2024
0b2349d
Harmonize/Update ReferenceElement & RelationshipElement
seicke Dec 16, 2024
2bb0fd9
Adapt .length checks
seicke Dec 17, 2024
9379f07
Functions for AAS and SM handling
seicke Dec 17, 2024
db5ecd3
Adds mobile support to 404 page
aaronzi Dec 17, 2024
a82adb5
Fix jumping to SME in SML
seicke Dec 17, 2024
edfeb0a
Add check for available SME in SMC für jumping to SME in SMC
seicke Dec 17, 2024
a31109f
Merge branch 'main' into single-aas
aaronzi Dec 17, 2024
b5653b5
Fixes error in SMEHandling were CDRepoURL wasn't accessible
aaronzi Dec 17, 2024
83b91d7
Fix checkReference, fix jumps
seicke Dec 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions aas-web-ui/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@ if [ -n "$ENDPOINT_CONFIG_AVAILABLE" ]; then
jq '.endpointConfigAvailable = env.ENDPOINT_CONFIG_AVAILABLE' /usr/src/app/dist/config.json > /tmp/config.json && mv /tmp/config.json /usr/src/app/dist/config.json
fi

if [ -n "$SINGLE_AAS" ]; then
jq '.singleAas = env.SINGLE_AAS' /usr/src/app/dist/config.json > /tmp/config.json && mv /tmp/config.json /usr/src/app/dist/config.json
fi

if [ -n "$SINGLE_AAS_REDIRECT" ]; then
jq '.singleAasRedirect = env.SINGLE_AAS_REDIRECT' /usr/src/app/dist/config.json > /tmp/config.json && mv /tmp/config.json /usr/src/app/dist/config.json
fi

if [ -n "$BASE_PATH" ]; then
echo "====================="
echo "BASE_PATH: $BASE_PATH"
Expand Down
4 changes: 3 additions & 1 deletion aas-web-ui/public/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,7 @@
"keycloakUrl": "",
"keycloakRealm": "",
"keycloakClientId": "",
"endpointConfigAvailable": true
"endpointConfigAvailable": true,
"singleAas": false,
"singleAasRedirect": ""
}
37 changes: 20 additions & 17 deletions aas-web-ui/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,9 @@
import RequestHandling from '@/mixins/RequestHandling';
import SubmodelElementHandling from '@/mixins/SubmodelElementHandling';
import { useAASStore } from '@/store/AASDataStore';
import { useEnvStore } from '@/store/EnvironmentStore';
import { useNavigationStore } from '@/store/NavigationStore';

interface AASType {
endpoints: Array<{
protocolInformation: {
href: string;
};
interface: string;
}>;
}

export default defineComponent({
name: 'App',
components: {
Expand All @@ -46,16 +38,18 @@
const aasStore = useAASStore();
const route = useRoute();
const router = useRouter();
const envStore = useEnvStore();

return {
navigationStore, // NavigationStore Object
aasStore, // AASStore Object
route, // Route Object
router, // Router Object
envStore, // EnvironmentStore Object
};
},

mounted() {
async mounted() {
let mobile = this.$vuetify.display.mobile;
// include IPad as mobile device
if (this.$vuetify.display.platform.mac && this.$vuetify.display.platform.touch) {
Expand All @@ -76,6 +70,20 @@
const aasEndpoint = searchParams.get('aas');
const submodelElementPath = searchParams.get('path');

// Ensure available aasEndpoint query parameter
if (
this.envStore.singleAas &&
(aasEndpoint === null || aasEndpoint === undefined || aasEndpoint.trim() === '')
) {
if (this.envStore.getSingleAasRedirect) {
window.location.replace(this.envStore.getSingleAasRedirect);
return;
} else if (this.route.name !== '404NotFound404') {
this.router.push({ name: 'NotFound404' });
return;
}
}

// check which platform is used and change the fitting view
if (mobile) {
if (this.route.name === 'MainWindow') {
Expand Down Expand Up @@ -117,12 +125,7 @@

if (aasEndpoint) {
// console.log('AAS Query is set: ', aasEndpoint);
let aas = {} as AASType;
let endpoints = [];
endpoints.push({ protocolInformation: { href: aasEndpoint }, interface: 'AAS-3.0' });
aas.endpoints = endpoints;
// dispatch the AAS set by the URL to the store
this.aasStore.dispatchSelectedAAS(aas);
await this.fetchAndDispatchAas(aasEndpoint);
}

if (aasEndpoint && submodelElementPath) {
Expand All @@ -142,7 +145,7 @@
this.aasStore.dispatchNode(response.data); // set the updatedNode in the AASStore
} else {
// execute if the Request failed
if (Object.keys(response.data).length == 0) {
if (response?.data && Object.keys(response?.data).length === 0) {
// don't copy the static SubmodelElement Data if no Node is selected or Node is invalid
this.navigationStore.dispatchSnackbar({
status: true,
Expand Down
2 changes: 1 addition & 1 deletion aas-web-ui/src/UserPlugins/HelloWorldPlugin.vue
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
methods: {
// Function to initialize the HelloWorld-Plugin
initializePlugin() {
if (Object.keys(this.submodelElementData).length == 0) {
if (Object.keys(this.submodelElementData).length === 0) {
this.pluginData = {}; // Reset the Plugin Data when no Node is selected
return;
}
Expand Down
127 changes: 43 additions & 84 deletions aas-web-ui/src/components/AASTreeview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
<v-col cols="auto">
<span>AAS Treeview</span>
</v-col>
<v-col v-if="nameToDisplay(SelectedAAS)" cols="auto" class="pl-1 pt-2">
<v-col v-if="nameToDisplay(selectedAAS)" cols="auto" class="pl-1 pt-2">
<v-chip size="x-small" color="primary" label border>{{
'AAS: ' + nameToDisplay(SelectedAAS)
'AAS: ' + nameToDisplay(selectedAAS)
}}</v-chip>
</v-col>
</v-row>
Expand All @@ -29,14 +29,20 @@
</template>
</v-list-item>
</div>
<!-- TODO: Replace with Vuetify Treeview Component when it get's released in Q1 2023 -->
<VTreeview
v-for="item in submodelData"
v-else
:key="item.id"
class="root"
:item="item"
:depth="0"></VTreeview>
<template v-else>
<v-empty-state
v-if="selectedAAS && Object.keys(selectedAAS).length > 0 && submodelData.length === 0"
title="No existing Submodels"
text="The selected AAS does not contain any Submodels"
class="text-divider"></v-empty-state>
<!-- TODO: Replace with Vuetify Treeview Component when it get's released in Q1 2023 -->
<VTreeview
v-for="item in submodelData"
:key="item.id"
class="root"
:item="item"
:depth="0"></VTreeview>
</template>
</v-card-text>
</v-card>
</v-container>
Expand Down Expand Up @@ -81,15 +87,10 @@

computed: {
// get selected AAS from Store
SelectedAAS() {
selectedAAS() {
return this.aasStore.getSelectedAAS;
},

// get the trigger for AAS selection from Store
triggerAAS() {
return this.navigationStore.getTriggerAASSelected;
},

// gets loading State from Store
loading() {
return this.aasStore.getLoadingState;
Expand All @@ -116,8 +117,7 @@
},

watch: {
// initialize Treeview when AAS gets selected
triggerAAS() {
selectedAAS() {
this.initializeTree();
},

Expand Down Expand Up @@ -154,74 +154,32 @@
},

methods: {
// Function to get the Submodels from the selected AAS (retrieved from the AAS with the provided endpoint)
initializeTree() {
// console.log('Initialize Treeview', this.initialUpdate, this.initialNode);
async initializeTree() {
// console.log('Initialize Treeview', this.SelectedAAS, this.initialUpdate, this.initialNode);
// return if no endpoints are available
if (!this.SelectedAAS || !this.SelectedAAS.endpoints || this.SelectedAAS.endpoints.length === 0) {
// TODO: this seems to get executed on reload with a selected AAS
if (!this.selectedAAS || !this.selectedAAS.endpoints || this.selectedAAS.endpoints.length === 0) {
// this.navigationStore.dispatchSnackbar({ status: true, timeout: 4000, color: 'error', btnColor: 'buttonText', text: 'AAS with no (valid) Endpoint selected!' });
this.submodelData = [];
return;
}
if (this.loading && !this.initialUpdate) return; // return if loading state is true -> prevents multiple requests
this.aasStore.dispatchLoadingState(true); // set loading state to true
this.submodelData = []; // reset Treeview Data
// retrieve AAS from endpoint
const shellHref = this.extractEndpointHref(this.selectedAAS, 'AAS-3.0');
let path = shellHref;
let context = 'retrieving AAS Data';
let disableMessage = false;
this.getRequest(path, context, disableMessage)
.then(async (response: any) => {
if (response.success) {
// execute if the Request was successful
try {
let AAS = response.data;
AAS.endpoints = this.SelectedAAS.endpoints;
this.aasStore.dispatchSelectedAAS(AAS); // dispatch the selected AAS to the Store
if (!AAS.submodels) {
throw new Error('No Submodels found in AAS!');
}
// request submodels from the retrieved AAS (top layer of the Treeview)
let submodelData = await this.requestSubmodels(AAS.submodels);
// set the isActive prop of the initialNode if it exists and the initialUpdate flag is set
if (this.initialUpdate && this.initialNode) {
let expandedSubmodelData = this.expandTree(submodelData, this.initialNode); // Update the Treeview to expand until the initially set node is reached
// this.updateNode(this.initialNode); // set the isActive prop of the initialNode to true
this.initialUpdate = false;
this.initialNode = {};
// console.log('Expanded Treeview Data: ', expandedSubmodelData)
this.submodelData = expandedSubmodelData; // set the Treeview Data
} else {
this.submodelData = submodelData; // set the Treeview Data
// console.log('Treeview Data: ', this.submodelData)
}
} catch (error: any) {
// console.error('Error while parsing the Submodel References: ', error);
const errorMessage = error.message;
const errorStack = error.stack;
const errorLocation = errorStack ? errorStack.split('\n')[1] : '';
this.navigationStore.dispatchSnackbar({
status: true,
timeout: 60000,
color: 'error',
btnColor: 'buttonText',
baseError: 'Error while parsing the Submodel References!',
extendedError: `Error: ${errorMessage}\nLocation: ${errorLocation.trim()}`,
});
} finally {
this.aasStore.dispatchLoadingState(false);
}
} else {
// execute if the Request failed
this.submodelData = [];
this.aasStore.dispatchLoadingState(false);
}
})
.catch(() => {
this.aasStore.dispatchLoadingState(false);
});
if (this.selectedAAS.submodels) {
let submodelData = await this.requestSubmodels(this.selectedAAS.submodels);
// set the isActive prop of the initialNode if it exists and the initialUpdate flag is set
if (this.initialUpdate && this.initialNode) {
let expandedSubmodelData = this.expandTree(submodelData, this.initialNode); // Update the Treeview to expand until the initially set node is reached
// this.updateNode(this.initialNode); // set the isActive prop of the initialNode to true
this.initialUpdate = false;
this.initialNode = {};
this.submodelData = expandedSubmodelData;
} else {
this.submodelData = submodelData;
}
} else {
this.submodelData = [];
}
this.aasStore.dispatchLoadingState(false);
},

// Function to request all Submodels for the selected AAS
Expand All @@ -231,8 +189,9 @@
// retrieve endpoint for submodel from submodel registry
// console.log('SubmodelRef: ', submodelRef, ' Submodel Registry: ', this.submodelRegistryServerURL);
// check if submodelRegistryURL includes "/submodel-descriptors" and add id if not (backward compatibility)
if (!this.submodelRegistryURL.includes('/submodel-descriptors')) {
this.submodelRegistryURL += '/submodel-descriptors';
let submodelRegistryURL = this.submodelRegistryURL;
if (!submodelRegistryURL.includes('/submodel-descriptors')) {
submodelRegistryURL += '/submodel-descriptors';
}
const submodelId = submodelRef.keys[0].value;
let path = this.submodelRegistryURL + '/' + this.URLEncode(submodelId);
Expand Down Expand Up @@ -439,9 +398,9 @@

// Function to initialize the treeview with route params
initTreeWithRouteParams() {
// check if the SelectedAAS is already set in the Store and initialize the Treeview if so
if (this.SelectedAAS && this.SelectedAAS.endpoints && this.SelectedAAS.endpoints.length > 0) {
// console.log('init Tree from Route Params: ', this.SelectedAAS);
// check if the selectedAAS is already set in the Store and initialize the Treeview if so
if (this.selectedAAS && this.selectedAAS.endpoints && this.selectedAAS.endpoints.length > 0) {
// console.log('init Tree from Route Params: ', this.selectedAAS);
this.initializeTree();
}

Expand Down
Loading
Loading