Skip to content

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:

smartshape-cli attribute metadata add 'status'
curl -X POST -H 'Authorization: Bearer ${AUTH_TOKEN}' \
    -d '{"key":"status"}' \
    https://smartshape.io/scene/attribute/metadata/

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:

smartshape-cli attribute metadata add 'status' \
    --read-permission 'read-status' 'role-is-reporter'
curl -X POST -H 'Authorization: Bearer ${AUTH_TOKEN}' \
    -d '{
        "key":"status",
        "readPermissions": [
            "read-status",
            "role-is-reporter"
        ]
    }' \
    https://smartshape.io/scene/attribute/metadata/

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 an Attribute read permissions)
  • the user has the permission to write the Attribute
  • the Attribute has a proper editor set via a matching AttributeMetadata

Write permissions

By default any Attribute can be created or updated by using:

  • the attribute upsert command via smartshape-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:

smartshape-cli attribute metadata add 'status' \
    --write-permission 'write-status' 'role-is-reporter'
curl -X POST -H 'Authorization: Bearer ${AUTH_TOKEN}' \
    -d '{
        "key":"status",
        "writePermissions": [
            "write-status",
            "role-is-reporter"
        ]
    }' \
    https://smartshape.io/scene/attribute/metadata/

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.

smartshape-cli attribute metadata add 'comment' \
    --textarea-editor
curl -X POST -H 'Authorization: Bearer ${AUTH_TOKEN}' \
    -d '{
        "key": "comment",
        "editor": {
            "type": "textarea"
        }
    }'

Select editor

The select editor is used to allow the user to choose one specific item in a list of options.

smartshape-cli attribute metadata add 'status' \
    --select-editor \
    --select-editor-options 'working' 'broken'
curl -X POST -H 'Authorization: Bearer ${AUTH_TOKEN}' \
    -d '{
        "key": "status",
        "editor": {
            "type": "select"
            "parameters": ["working", "broken"]
        }
    }'

Number editor

The number editor is used to present a number spinner configured with optional min, max and step values.

smartshape-cli attribute metadata add 'thickness' \
    --number-editor \
    --number-editor-min 0 \
    --number-editor-max 42
curl -X POST -H 'Authorization: Bearer ${AUTH_TOKEN}' \
    -d '{
        "key": "thickness",
        "editor": {
            "type": "number",
            "min": 0,
            "max": 42
        }
    }'

Checklist editor

The checklist editor is used to show the user a list of on/off toggles (one toggle per option).

smartshape-cli attribute metadata add 'status' \
    --checklist-editor \
    --checklist-editor-options 'working' 'broken'
curl -X POST -H 'Authorization: Bearer ${AUTH_TOKEN}' \
    -d '{
        "key": "status",
        "editor": {
            "type": "checklist"
            "parameters": ["working", "broken"]
        }
    }'

Picture editor

The picture editor is used to allow the user to use the device camera to take a photo.

smartshape-cli attribute metadata add 'defect picture' \
    --picture-editor
curl -X POST -H 'Authorization: Bearer ${AUTH_TOKEN}' \
    -d '{
        "key": "defect picture",
        "editor": {
            "type": "picture"
        }
    }'

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 its type Attribute set to pipe:
smartshape-cli attribute metadata add 'status' \
    --query '@type="pipe"'
curl -X POST -H 'Authorization: Bearer ${AUTH_TOKEN}' \
    -d '{
        "key": "status",
        "searchQuery": "@type=\"pipe\""
    }' \
    https://smartshape.io/scene/attribute/metadata/

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 of working or broken
  • defect can be set to any free text, but it can only be set if status is set to broken

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
smartshape-cli attribute metadata add 'status' \
    --select-editor \
    --select-editor-options 'working' 'broken'

# define the `defect` attribute editor
smartshape-cli attribute metadata add 'defect' \
    --textarea-editor \
    --query "@status=\"broken\""
# 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 target Nodes/Annotations and then upsert the Attributes. 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 new Annotations and we might like to have those Attributes available on those newly created Annotations.

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:

smartshape-cli attribute metadata add 'status' \
    --select-editor \
    --select-editor-options 'working' 'broken' \
    --editor-update-only-query '@type!="pipe"'
curl -X POST -H 'Authorization: Bearer ${AUTH_TOKEN}' \
    -d '{
        "key":"status",
        "editor": {
            "type": "select",
            "parameters": [
                "working",
                "broken"
            ],
            "updateOnlyQuery": "@type!=\"pipe\""
        }
    }' \
    https://smartshape.io/scene/attribute/metadata/

The behavior will be as follows:

  • On any Node/Annotation with the type Attribute set to pipe: the status Attribute will be editable and, upon edition, will be created if necessary.
  • On all the other Node/Annotation, the status 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:

smartshape-cli attribute metadata add 'status' \
    --select-editor \
    --select-editor-options 'working' 'broken' \
    --editor-update-only-query '@type!="pipe"' \
    --query '@type="pipe"'
curl -X POST -H 'Authorization: Bearer ${AUTH_TOKEN}' \
    -d '{
        "key":"status",
        "editor": {
            "type": "select",
            "parameters": [
                "working",
                "broken"
            ],
            "updateOnlyQuery": "@type!=\"pipe\""
        },
        "query": "@type=\"pipe\""
    }' \
    https://smartshape.io/scene/attribute/metadata/

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.


November 29, 2023 June 9, 2020