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

Visualization component loading #106

Merged
merged 11 commits into from
Dec 7, 2024
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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']`)
seicke marked this conversation as resolved.
Show resolved Hide resolved

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
22 changes: 11 additions & 11 deletions aas-web-ui/src/components/ComponentVisualization.vue
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,14 @@
</template>
<template v-else>
<component
:is="visualization.name"
v-for="(visualization, index) in filteredVisualizations"
:is="plugin.name"
v-for="(plugin, index) in filteredPlugins"
:key="index"
:submodel-element-data="submodelElementData"
>{{ visualization.name }}</component
>{{ plugin.name }}</component
>
<GenericDataVisu
v-if="viewerMode && filteredVisualizations.length === 0"
v-if="viewerMode && filteredPlugins.length === 0"
:submodel-element-data="submodelElementData.submodelElements"></GenericDataVisu>
</template>
</v-card-text>
Expand All @@ -70,10 +70,10 @@
<script lang="ts">
import { defineComponent } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import CADPreview from '@/components/Plugins/CADPreview.vue';
import ImagePreview from '@/components/Plugins/ImagePreview.vue';
import PDFPreview from '@/components/Plugins/PDFPreview.vue';
import GenericDataVisu from '@/components/UIComponents/GenericDataVisu.vue';
import CADPreview from '@/components/Visualizations/CADPreview.vue';
import ImagePreview from '@/components/Visualizations/ImagePreview.vue';
import PDFPreview from '@/components/Visualizations/PDFPreview.vue';
import RequestHandling from '@/mixins/RequestHandling';
import SubmodelElementHandling from '@/mixins/SubmodelElementHandling';
import { useAASStore } from '@/store/AASDataStore';
Expand Down Expand Up @@ -153,13 +153,13 @@
return this.navigationStore.getIsMobile;
},

importedVisualizations() {
return this.navigationStore.getVisualizations;
importedPlugins() {
return this.navigationStore.getPlugins;
},

// Filtered Plugins
filteredVisualizations() {
return this.importedVisualizations.filter((plugin: any) => {
filteredPlugins() {
return this.importedPlugins.filter((plugin: any) => {
if (!plugin.semanticId) return false;

if (typeof plugin.semanticId === 'string') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import TimeSeriesData from '@/components/Visualizations/Submodels/TimeSeriesData.vue';
import TimeSeriesData from '@/components/Plugins/Submodels/TimeSeriesData.vue';
import DashboardHandling from '@/mixins/DashboardHandling';
import SubmodelElementHandling from '@/mixins/SubmodelElementHandling';
import { useEnvStore } from '@/store/EnvironmentStore';
Expand Down
2 changes: 1 addition & 1 deletion aas-web-ui/src/components/Dashboard/DashboardElement.vue
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@

<script lang="ts">
import { defineComponent } from 'vue';
import TimeSeriesData from '@/components/Visualizations/Submodels/TimeSeriesData.vue';
import TimeSeriesData from '@/components/Plugins/Submodels/TimeSeriesData.vue';
import DashboardHandling from '@/mixins/DashboardHandling';
import SubmodelElementHandling from '@/mixins/SubmodelElementHandling';
import { useEnvStore } from '@/store/EnvironmentStore';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,9 +266,9 @@
<script lang="ts">
import { defineComponent } from 'vue';
import { useTheme } from 'vuetify';
import CADPreview from '@/components/Visualizations/CADPreview.vue';
import ImagePreview from '@/components/Visualizations/ImagePreview.vue';
import PDFPreview from '@/components/Visualizations/PDFPreview.vue';
import CADPreview from '@/components/Plugins/CADPreview.vue';
import ImagePreview from '@/components/Plugins/ImagePreview.vue';
import PDFPreview from '@/components/Plugins/PDFPreview.vue';
import RequestHandling from '@/mixins/RequestHandling';
import SubmodelElementHandling from '@/mixins/SubmodelElementHandling';
import { useAASStore } from '@/store/AASDataStore';
Expand Down
32 changes: 16 additions & 16 deletions aas-web-ui/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ import App from './App.vue';
import { createAppRouter } from './router';
import { useAuthStore } from './store/AuthStore';
import { useEnvStore } from './store/EnvironmentStore';
import { useNavigationStore, VisualizationType } from './store/NavigationStore';
import { PluginType, useNavigationStore } from './store/NavigationStore';

const app = createApp(App);

const pinia = createPinia();

async function loadVisualizations() {
async function loadPlugins() {
const router = await createAppRouter();

app.use(router);
Expand All @@ -46,33 +46,33 @@ async function loadVisualizations() {

await registerPlugins(app);

const visualizationFileRecords = {
...import.meta.glob('./components/Visualizations/Submodels/*.vue'),
...import.meta.glob('./components/Visualizations/SubmodelElements/*.vue'),
...import.meta.glob('./UserVisualizations/*.vue'),
const pluginFileRecords = {
...import.meta.glob('./components/Plugins/Submodels/*.vue'),
...import.meta.glob('./components/Plugins/SubmodelElements/*.vue'),
...import.meta.glob('./UserPlugins/*.vue'),
};

const visualizationFiles = Object.keys(visualizationFileRecords);
const pluginFiles = Object.keys(pluginFileRecords);

const visualizations = [] as Array<VisualizationType>;
const plugins = [] as Array<PluginType>;

await Promise.all(
visualizationFiles.map(async (path) => {
pluginFiles.map(async (path) => {
const componentName = path
.replace('./components/Visualizations/Submodels/', '')
.replace('./components/Visualizations/SubmodelElements/', '')
.replace('./UserVisualizations/', '')
.replace('./components/Plugins/Submodels/', '')
.replace('./components/Plugins/SubmodelElements/', '')
.replace('./UserPlugins/', '')
.replace('.vue', '');
const component: any = await visualizationFileRecords[path]();
const component: any = await pluginFileRecords[path]();
if (component.default.semanticId) {
app.component(componentName, (component.default || component) as ReturnType<typeof defineComponent>);
visualizations.push({ name: componentName, semanticId: component.default.semanticId });
plugins.push({ name: componentName, semanticId: component.default.semanticId });
}
})
);

const navigationStore = useNavigationStore();
navigationStore.dispatchVisualizations(visualizations);
navigationStore.dispatchPlugins(plugins);
app.mount('#app');
}

Expand Down Expand Up @@ -139,4 +139,4 @@ async function initKeycloak(keycloakUrl: string, keycloakRealm: string, keycloak
});
}

loadVisualizations();
loadPlugins();
10 changes: 5 additions & 5 deletions aas-web-ui/src/store/NavigationStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export interface PlatformType {
win: boolean;
}

export interface VisualizationType {
export interface PluginType {
name: string;
semanticId: string;
}
Expand All @@ -53,7 +53,7 @@ export const useNavigationStore = defineStore({
StatusCheck: false as boolean,
isMobile: false as boolean,
platform: {} as PlatformType,
visualizations: [] as VisualizationType[],
plugins: [] as PluginType[],
triggerAASListReload: false as boolean,
triggerAASListScroll: false as boolean,
triggerAASSelected: false as boolean,
Expand All @@ -72,7 +72,7 @@ export const useNavigationStore = defineStore({
getStatusCheck: (state) => state.StatusCheck,
getIsMobile: (state) => state.isMobile,
getPlatform: (state) => state.platform,
getVisualizations: (state) => state.visualizations,
getPlugins: (state) => state.plugins,
getTriggerAASListReload: (state) => state.triggerAASListReload,
getTriggerAASListScroll: (state) => state.triggerAASListScroll,
getTriggerAASSelected: (state) => state.triggerAASSelected,
Expand Down Expand Up @@ -121,8 +121,8 @@ export const useNavigationStore = defineStore({
dispatchPlatform(platform: PlatformType) {
this.platform = platform;
},
dispatchVisualizations(visualizations: Array<VisualizationType>) {
this.visualizations = visualizations;
dispatchPlugins(plugins: Array<PluginType>) {
this.plugins = plugins;
},
dispatchTriggerAASListReload(triggerAASListReload: boolean) {
this.triggerAASListReload = triggerAASListReload;
Expand Down