Attribute Metadata
Definition¶
The following documentation explains how to achieve the most basic
but also the most complex scenarios by extending an Attribute
definition using what SmartShape calls AttributeMetadata.
An AttributeMetadata can be used to customize and extend the definition of
one or more specific Attributes. AttributeMetadata can be used to define
the lifecycle and additional properties of an Attribute:
- how/when the
Attributecan be edited - the read/write permissions of the
Attribute - the localization of the
Attribute's key and value(s)
and more.
Matching Attributes by key¶
The simplest scenario to match an AttributeMetadata to a specific attribute
is to match the corresponding Attribute's "key" (aka the attribute's "name").
For example, a new AttributeMetadata targeting attributes with the
status key can be created using the following smartshape-cli command:
Note: the examples above are for demonstration purposes only. Creating an
AttributeMetadata without additional customization has no effect.
Restricting an Attribute read permissions¶
By default, all Attributes can be read by all users.
One might want to restrict the possibility to read one or more specific
Attributes. To do this, simply set the readPermissions field to an array
of permission names given as strings.
The following example creates an AttributeMetadata
making the status Attribute readable only by users with both the
read-status and role-is-reporter permissions:
The matched Attributes will be readable only if the user has all of the
permissions listed in the readPermissions field. In the example above, it
means only the users with both the read-status and role-is-reporter
permissions will be able to read the status Attribute.
Making an Attribute editable¶
By default:
- the SmartShape application will list all
Attributesas read-only; - the SmartShape API will allow any (writtable attribute) to be created/edited.
An Attribute is shown as editable in the application if:
- the user has the permission to read the
Attribute(see Restricting anAttributeread permissions) - the user has the permission to write the
Attribute - the
Attributehas a proper editor set via a matchingAttributeMetadata
Write permissions¶
By default any Attribute can be created or updated by using:
- the
attribute upsertcommand viasmartshape-cli - the
POST /scene/attributeREST API endpoint
The writePermissions field can be used to declare the name of all the
permissions the user must have to be allowed to edit the matched
Attribute.
The following example creates an AttributeMetadata
making the status Attribute writable only by users with both the
write-status and role-is-reporter permissions:
The matched Attributes will be writable only if the user has all of the
permissions listed in the writePermissions field. In the example above, it
means only the users with both the write-status and role-is-reporter
permissions will be able to write the status Attribute.
Configuring the Attribute editor¶
To make an Attribute editable, one must describe how it can be edited via an
"editor". This is done by setting the editor field.
Textarea editor¶
The textarea editor is used to enter free text on multiple lines. It is
especially useful to enter remarks, comments or any kind of user-defined multiline
string.
Select editor¶
The select editor is used to allow the user to choose one specific item
in a list of options.
Number editor¶
The number editor is used to present a number spinner configured with optional
min, max and step values.
Checklist editor¶
The checklist editor is used to show the user a list of on/off toggles
(one toggle per option).
Picture editor¶
The picture editor is used to allow the user to use the device camera to
take a photo.
Matching Attributes by target Node/Annotation using SmartShape QL¶
Sometimes, an attribute with a specific key can have different definitions
depending on its target Node/Annotation. It is especially true for
Attributes with very common/generic names such as status or progress
for example.
For example, a progress attribute might be (editable as) a list when held
by the Scene Node of a mechanical part and at the same time also be
(editable as) a percentage when held by an Annotation. Or a status
Attribute can have different read/write permissions based on another
Attribute held by the same target Node. In a way, in those scenarios,
one might consider those are actually two different Attribute definitions
that share the same key. Thus, attempting to create an AttributeMetadata
that matches such Attributes by key only will be ambiguous.
To solve this, an AttributeMetadata can match an Attribute not only by
its key but also by testing its target Node/Annotation with a
user-defined SmartShape QL function. If (the key matches and) the function
returns true, then the AttributeMetadata matches and its definition is
applied.
For example, the following smartshape-cli command will create an
AttributeMetadata matching Attributes:
- with the
statuskey - and held by a
Node/Annotationwith itstypeAttributeset topipe:
Complex scenarios and lifecycles can be implemented using this feature.
Let's consider a use case with the two following Attributes:
statuscan be set to one ofworkingorbrokendefectcan be set to any free text, but it can only be set ifstatusis set tobroken
The catch here is to make sure defect will be defined as editable only
if the value of status is equal to the broken string. This is achieved
by matching the defect Attribute with the right SmartShape QL function:
# define the `status` attribute editor
curl -X POST -H 'Authorization: Bearer ${AUTH_TOKEN}' \
-d '{
"key":"status",
"editor": {
"type": "select",
"parameters": [
"working",
"broken"
]
}
}' \
https://smartshape.io/scene/attribute/metadata/
# define the `defect` attribute editor
curl -X POST -H 'Authorization: Bearer ${AUTH_TOKEN}' \
-d '{
"key":"defect",
"editor": {
"type": "textarea"
},
"query": "@status=\"broken\""
}' \
https://smartshape.io/scene/attribute/metadata/
Creating new Attributes¶
One might want to give (some) users the capability to create new
Attributes that don't exist yet.
The first obvious option is to upsert such Attributes with a default
value using the POST /scene/attributes/ API endpoint
or the smartshape-cli attribute upsert command. But this is not very
practical:
- It's not very storage-savvy since it implies creating a lot of
Attributesthat won't necessarily be used. - Creating those
Attributeswill require to find the corresponding targetNodes/Annotationsand then upsert theAttributes. Which implies making at least 2 potentially very heavy API requests per file. - Sometimes it's not possible at all: in the case of
Annotations, the user might create newAnnotationsand we might like to have thoseAttributesavailable on those newly createdAnnotations.
Some of those issues can be worked around using a custom middleware that would
listen to some specific webhooks and upsert the desired Attributes on the
fly. But webhooks obviously do not work in an offline scenario.
3D models usually have their Attribute data coming from the original CAD
software used for modelling and include mainly design data.
To use such 3D model in - for example - a maintenance scenario, new
maintenance-specific Attributes would be created by the users as they
perform those very maintenance tasks. But to input such Attributes, the
user must first be able to list and edit them via the app despite the fact
they don't actually exist yet.
In this case, since such Attribute does not exist yet, matching it
by key or by target won't work. To implement this use case, we can declare an
AttributeMetadata that will define how/when such Attribute can be created
based on a user-defined SmartShape QL function.
This SmartShape QL function can be set in the
AttributeMetadata.editor.updateOnlyQuery field.
If this function returns false, the SmartShape App will show:
- The corresponding
Attributeas editable. - With an empty default value.
By actually editing the Attribute and setting a non empty value, the
corresponding Attribute is indeed created on the corresponding target.
The following example defines a new AttributeMetadata that allows the
creation of a status Attribute on every target Node/Annotation
with its type Attribute set to pipe:
The behavior will be as follows:
- On any
Node/Annotationwith thetypeAttributeset topipe: thestatusAttributewill be editable and, upon edition, will be created if necessary. - On all the other
Node/Annotation, thestatusAttributewill not be editable, and won't even be listed if it doesn't actually exist.
If we do expect this Attribute to be creatable only on Nodes/Annotations
with the type Attribute set to pipe, we can make this AttributeMetadata
even more specific by matching only the relevant targets using
AttributeMetadata.query:
By using and mixing:
AttributeMetadata.keyAttributeMetadata.queryAttributeMetadata.editor.updateOnlyQueryAttributeMetadata.read_permissions
to properly match Attributes and make them editable/creatable only in
specific situations, very complex Attribute workflows can be implemented.