Linked Whiteboards not exposed by API?

In a DB, I can have a Collection of Whiteboards, but I cannot retrieve the collection’s contents via API or graphQL:

[Error: getEntityById: There is no relation for “Sandbox/Task” database “whiteboards/whiteboards” field.]

So it’s impossible for a script to accurately clone/copy such an entity.

EDIT: It appears the same is true for “Documents” collections.

@helloitse

You have to use the views API to get whiteboards or documents:

1 Like

@Chr1sG Can the Views API be accessed directly from scripts, or does it need to use context.getService('http') ?

Only via API call I’m afraid.

@Chr1sG I’m confused.

The Views API does not seem to have anything to do with entities.

What I need to do is retrieve an entity Collection, in this case a collection of Whiteboards (views).

The regular fibery API does not allow retrieving the Collection field at all - Error: getEntityById: There is no relation for "Sandbox/Task" database "whiteboards/whiteboards" field.

So - how to retrieve the list of Whiteboard view IDs that are in the entity Collection?
Then I will also need to write those View IDs to a different entity’s Whiteboards Collection.

You need to make a query to the view API where you include a filter, limiting the views to be returned to those which belong to the entity you are interested in (and of the type you are interested in).
See the example in the user guide:


Then you need to update the views to change their parent entity.

As an example, this script will get all the docs and whiteboards from an entity and move them to an entity of the same type, with a public Id of ‘2’:

const fibery = context.getService("fibery");
const http = context.getService("http");
const TOKEN = <api token>;
const WORKSPACE = 'https://<workspace>.fibery.io';

const schema = await fibery.getSchema();

for (const entity of args.currentEntities) {
    const typeId = schema['typeObjects'].find((t) => t.name === entity.type).id;
    const entityId = entity['Public Id'];

    const queryResponse = await http.postAsync(
        `${WORKSPACE}/api/views/json-rpc`,
        {
            body: {
                jsonrpc: "2.0",
                method: "query-views",
                params: {
                    filter: {
                        container: {
                            type: "entity",
                            typeId: `${typeId}`,
                            publicIds: [`${entityId}`]
                        }
                    }
                }
            },
            headers: {
                "Content-Type": "application/json",
                "Authorization": `Bearer ${TOKEN}`
            }
        }
    );

    const queryResponseJson = JSON.parse(queryResponse);
    const viewIds = queryResponseJson.result.filter((v) => v['fibery/type'] === 'document' || v['fibery/type'] === 'canvas').map((v) => v['fibery/id']);

    const newId = '2'
    const batchUpdate = { updates: viewIds.map((v) => ({ id: v, values: { 'fibery/container-entity-id': `${newId}` } })) };

    const updateResponse = await http.postAsync(
        `${WORKSPACE}/api/views/json-rpc`,
        {
            body: {
                jsonrpc: "2.0",
                method: "update-views",
                params: batchUpdate
            },
            headers: {
                "Content-Type": "application/json",
                "Authorization": `Bearer ${TOKEN}`
            }
        }
    );
}

E&OE :wink:

Hope this is useful.

1 Like

Thanks @Chr1sG
It’s not clear whether a View can be referenced by more than one entity?

This seems to imply there can only be a single entity referencing the view:

batchUpdate = { updates: viewIds.map((v) => ({ id: v, values: { 'fibery/container-entity-id': `${newId}` } })) };

A view belongs to a single ‘container’ (which can be many possible things, including entities)

1 Like