Skip to content

Commit

Permalink
Add administrative information component (eclipse-basyx#111)
Browse files Browse the repository at this point in the history
* Add administrative information component

* adds missing check for keys

* Adds missing checks (optional chaining)

* Harmonize v-list-items

* Add expansion panel

* Fix margin

---------

Co-authored-by: Aaron Zielstorff <[email protected]>
  • Loading branch information
seicke and aaronzi authored Dec 9, 2024
1 parent 43d00d8 commit 118b694
Show file tree
Hide file tree
Showing 3 changed files with 282 additions and 4 deletions.
20 changes: 17 additions & 3 deletions aas-web-ui/src/components/AppNavigation/AASListDetails.vue
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
<AssetInformation
v-if="assetInformation && Object.keys(assetInformation).length > 0"
:asset-object="assetInformation"></AssetInformation>
<v-divider v-if="assetInformation"></v-divider>
<v-divider v-if="assetInformation" thickness="2"></v-divider>
<!-- AAS Details -->
<v-list v-if="detailsObject" lines="one" nav class="bg-detailsCard">
<!-- AAS Identification -->
Expand All @@ -50,10 +50,22 @@
:model-type="'AAS'"
:id-type="'Identification (ID)'"
:name-type="'idShort'"></IdentificationElement>
<!-- AAS Administrative Information-->
<v-divider
v-if="detailsObject.displayName && detailsObject.displayName.length > 0"
v-if="
detailsObject.administration &&
(detailsObject.administration.revision != '' ||
detailsObject.administration.version != '')
"
class="mt-2"></v-divider>
<!-- SubmodelELement DisplayName -->
<AdministrativeInformationElement
v-if="detailsObject.administration"
:administrative-information-object="detailsObject.administration"
:administrative-information-title="'Administrative Information'"
:small="false"
:background-color="'detailsCard'"></AdministrativeInformationElement>
<v-divider v-if="detailsObject.displayName && detailsObject.displayName.length > 0"></v-divider>
<!-- AAS DisplayName -->
<DisplayNameElement
v-if="detailsObject.displayName && detailsObject.displayName.length > 0"
:display-name-object="detailsObject.displayName"
Expand All @@ -77,6 +89,7 @@

<script lang="ts">
import { defineComponent } from 'vue';
import AdministrativeInformationElement from '@/components/UIComponents/AdministrativeInformationElement.vue';
import AssetInformation from '@/components/UIComponents/AssetInformation.vue';
import DescriptionElement from '@/components/UIComponents/DescriptionElement.vue';
import DisplayNameElement from '@/components/UIComponents/DisplayNameElement.vue';
Expand All @@ -89,6 +102,7 @@
name: 'AASListDetails',
components: {
IdentificationElement,
AdministrativeInformationElement,
DisplayNameElement,
DescriptionElement,
AssetInformation,
Expand Down
18 changes: 17 additions & 1 deletion aas-web-ui/src/components/SubmodelElementView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,23 @@
:model-type="submodelElementData.modelType"
:id-type="'Identification (ID)'"
:name-type="'idShort'"></IdentificationElement>
<!-- Submodel Administrative Information-->
<v-divider
v-if="submodelElementData.displayName && submodelElementData.displayName.length > 0"
v-if="
submodelElementData.administration &&
(submodelElementData.administration.revision != '' ||
submodelElementData.administration.version != '')
"
class="mt-2"></v-divider>
<AdministrativeInformationElement
v-if="submodelElementData.administration"
:administrative-information-object="submodelElementData.administration"
:administrative-information-title="'Administrative Information'"
:small="false"></AdministrativeInformationElement>
<v-divider
v-if="
submodelElementData.displayName && submodelElementData.displayName.length > 0
"></v-divider>
<!-- SubmodelELement DisplayName -->
<DisplayNameElement
v-if="submodelElementData.displayName && submodelElementData.displayName.length > 0"
Expand Down Expand Up @@ -154,6 +168,7 @@
import Submodel from '@/components/SubmodelElements/Submodel.vue';
import SubmodelElementCollection from '@/components/SubmodelElements/SubmodelElementCollection.vue';
import SubmodelElementList from '@/components/SubmodelElements/SubmodelElementList.vue';
import AdministrativeInformationElement from '@/components/UIComponents/AdministrativeInformationElement.vue';
import ConceptDescription from '@/components/UIComponents/ConceptDescription.vue';
import DescriptionElement from '@/components/UIComponents/DescriptionElement.vue';
import DisplayNameElement from '@/components/UIComponents/DisplayNameElement.vue';
Expand All @@ -169,6 +184,7 @@
name: 'SubmodelElementView',
components: {
IdentificationElement,
AdministrativeInformationElement,
DisplayNameElement,
DescriptionElement,
SemanticID,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
<template>
<v-container fluid class="pa-0">
<v-expansion-panels>
<v-expansion-panel elevation="0" tile static :color="backgroundColor">
<v-expansion-panel-title class="px-2">
<span :class="small ? 'text-caption' : 'text-subtitle-2 '">
{{ administrativeInformationTitle }}
</span>
</v-expansion-panel-title>
<v-expansion-panel-text :class="'bg-' + backgroundColor">
<v-divider
v-if="
Array.isArray(administrativeInformationObject?.creator?.keys) &&
administrativeInformationObject?.creator?.keys.length > 0
"
class="mb-1"
opacity="0.05"></v-divider>
<v-list nav class="pa-0">
<!-- Creator -->
<v-list-item
v-if="
Array.isArray(administrativeInformationObject?.creator?.keys) &&
administrativeInformationObject?.creator?.keys.length > 0
"
class="ma-0">
<v-tooltip activator="parent" open-delay="600" transition="slide-x-transition">
<div
v-for="(creator, i) in administrativeInformationObject.creator.keys"
:key="i"
class="text-caption">
<span v-if="creator?.type" class="font-weight-bold">{{
'(' + creator.type + ') '
}}</span
>{{ creator.value }}
</div>
</v-tooltip>
<template #title>
<span class="text-subtitle-2">
{{
administrativeInformationObject.creator.keys.length === 1
? 'Creator:'
: 'Creators:'
}}
</span>
</template>
<v-list-item-subtitle
v-for="(creator, i) in administrativeInformationObject.creator.keys"
:key="i">
<div v-if="creator?.type" class="pt-2">
<v-chip label size="x-small" border class="mr-2">{{ creator.type }}</v-chip>
<span>{{ creator.value }}</span>
</div>
</v-list-item-subtitle>
</v-list-item>
<v-divider
v-if="
Array.isArray(administrativeInformationObject?.creator?.keys) &&
administrativeInformationObject?.creator?.keys.length > 0 &&
(administrativeInformationObject?.version || administrativeInformationObject?.revision)
"
class="mt-2"
opacity="0.05"></v-divider>
<!-- Version and Revision -->
<v-list-item
v-if="administrativeInformationObject?.version || administrativeInformationObject?.revision"
class="ma-0">
<v-list-item-title>
<template v-if="administrativeInformationObject?.version">
<span class="text-subtitle-2 mt-2 mr-2">{{ 'Version:' }}</span
><v-chip label size="x-small" border class="mr-5">{{
administrativeInformationObject.version
}}</v-chip>
</template>
<template v-if="administrativeInformationObject?.revision">
<span class="text-subtitle-2 mt-2 mr-2">{{ 'Revision:' }}</span
><v-chip label size="x-small" border class="mr-5">{{
administrativeInformationObject.revision
}}</v-chip>
</template>
</v-list-item-title>
</v-list-item>
</v-list>
<v-divider
v-if="
((Array.isArray(administrativeInformationObject?.creator?.keys) &&
administrativeInformationObject?.creator?.keys.length > 0) ||
administrativeInformationObject?.version ||
administrativeInformationObject?.revision) &&
administrativeInformationObject?.templateId
"
opacity="0.05"></v-divider>
<v-list nav class="pa-0">
<v-hover v-slot="{ isHovering, props }">
<v-list-item v-if="administrativeInformationObject?.templateId" class="ma-0">
<template #title>
<span class="text-subtitle-2">
{{ 'Template ID:' }}
</span>
</template>
<template #subtitle>
<div
v-if="administrativeInformationObject.templateId"
v-bind="props"
:class="isHovering ? 'cursor-pointer' : ''"
@click="
copyToClipboard(administrativeInformationObject.templateId, 'Template ID')
">
<v-icon v-if="isHovering" color="subtitleText" size="x-small" class="mr-1">{{
copyIcon
}}</v-icon>
<span>{{ administrativeInformationObject.templateId }}</span>
</div>
</template>
</v-list-item>
</v-hover>
</v-list>
<v-divider
v-if="
((Array.isArray(administrativeInformationObject?.creator?.keys) &&
administrativeInformationObject?.creator?.keys.length > 0) ||
administrativeInformationObject?.version ||
administrativeInformationObject?.revision ||
administrativeInformationObject?.templateId) &&
Array.isArray(administrativeInformationObject?.embeddedDataSpecifications) &&
administrativeInformationObject?.embeddedDataSpecifications.length > 0
"
opacity="0.05"></v-divider>
<!-- Embedded Data Specifications -->
<v-list
v-if="
Array.isArray(administrativeInformationObject?.embeddedDataSpecifications) &&
administrativeInformationObject?.embeddedDataSpecifications.length > 0
"
nav
class="pa-0">
<v-card
v-for="(
embeddedDataSpecification, i
) in administrativeInformationObject.embeddedDataSpecifications"
:key="i"
color="elevatedCard"
class="mt-2">
<v-list nav class="bg-elevatedCard pt-0">
<!-- hasDataSpecification -->
<SemanticID
v-if="
Array.isArray(embeddedDataSpecification?.dataSpecification?.keys) &&
embeddedDataSpecification?.dataSpecification?.keys.length > 0
"
:semantic-id-object="embeddedDataSpecification.dataSpecification"
:semantic-title="'Data Specification'"
class="mb-2"></SemanticID>
<v-divider v-if="embeddedDataSpecification?.dataSpecificationContent"></v-divider>
<!-- dataSpecificationContent -->
<DataSpecificationContent
v-if="embeddedDataSpecification?.dataSpecificationContent"
:data-specification-object="
embeddedDataSpecification?.dataSpecificationContent
"></DataSpecificationContent>
</v-list>
</v-card>
</v-list>
</v-expansion-panel-text>
</v-expansion-panel>
</v-expansion-panels>
</v-container>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import { useNavigationStore } from '@/store/NavigationStore';
import DataSpecificationContent from './DataSpecificationContent.vue';
import SemanticID from './SemanticID.vue';
export default defineComponent({
name: 'AdministrativeInformationElement',
components: {
SemanticID,
DataSpecificationContent,
},
// props: ['administrativeInformationObject', 'administrativeInformationTitle', 'small', 'backgroundColor'],
props: {
administrativeInformationObject: {
type: Object,
default: () => ({}),
},
administrativeInformationTitle: {
type: String,
default: '',
},
small: {
type: Boolean,
default: true,
},
backgroundColor: {
type: String,
default: '',
},
},
setup() {
const navigationStore = useNavigationStore();
return {
navigationStore, // NavigationStore Object
};
},
data() {
return {
copyIcon: 'mdi-clipboard-file-outline',
};
},
methods: {
// Function to copy the id to the clipboard
copyToClipboard(value: string, valueName: string) {
if (!value || !value) return;
// console.log('Copy ID to Clipboard: ', this.identificationObject.id);
// set the icon to checkmark
this.copyIcon = 'mdi-check';
// copy the path to the clipboard
navigator.clipboard.writeText(value);
// set the clipboard tooltip to false after 1.5 seconds
setTimeout(() => {
this.copyIcon = 'mdi-clipboard-file-outline';
}, 2000);
// open Snackbar to inform the user that the path was copied to the clipboard
this.navigationStore.dispatchSnackbar({
status: true,
timeout: 2000,
color: 'success',
btnColor: 'buttonText',
text: valueName + ' copied to Clipboard.',
});
},
},
});
</script>

<style lang="css" scoped>
.v-expansion-panel-text :deep(.v-expansion-panel-text__wrapper) {
padding-left: 8px !important;
padding-right: 8px !important;
padding-top: 0px !important;
padding-bottom: 12px !important;
}
</style>

0 comments on commit 118b694

Please sign in to comment.