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
Attribute
can 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
Attributes
as 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 anAttribute
read permissions) - the user has the permission to write the
Attribute
- the
Attribute
has a proper editor set via a matchingAttributeMetadata
Write permissions¶
By default any Attribute
can be created or updated by using:
- the
attribute upsert
command viasmartshape-cli
- the
POST /scene/attribute
REST 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
status
key - and held by a
Node
/Annotation
with itstype
Attribute
set topipe
:
Complex scenarios and lifecycles can be implemented using this feature.
Let's consider a use case with the two following Attributes
:
status
can be set to one ofworking
orbroken
defect
can be set to any free text, but it can only be set ifstatus
is 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
Attributes
that won't necessarily be used. - Creating those
Attributes
will require to find the corresponding targetNodes
/Annotations
and 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 newAnnotations
and we might like to have thoseAttributes
available 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
Attribute
as 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
/Annotation
with thetype
Attribute
set topipe
: thestatus
Attribute
will be editable and, upon edition, will be created if necessary. - On all the other
Node
/Annotation
, thestatus
Attribute
will 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.key
AttributeMetadata.query
AttributeMetadata.editor.updateOnlyQuery
AttributeMetadata.read_permissions
to properly match Attributes
and make them editable/creatable only in
specific situations, very complex Attribute
workflows can be implemented.