Action Buttons Q&A

Hi everyone!

So, while pushing my way through coding Action Buttons (blindly, dissecting the examples, making up for lack of JS knowledge with pure denial to accept failure), I thought: it would be really cool to have a thread where one can ask a basic question about Action Buttons! Something one feels everyone else probably knows. Something presumably so small it feels awkward to start a separate thread for it.

Like these:

Q1: How can I check if an entity’s state === its final state? Checking state name somehow? Can I check the current state’s "Final" checkmark instead?

Q2: Can I use emojis in strings in code? How do I do that?

Q3: Is there a command to get the entity with all of its fields at once? It seems that fibery.getEntityById() returns an entity with only the fields asked for explicitly.

…and they keep coming as I keep going.

If the community and the devs support the idea, I’d gladly keep the thread organized, copying all the Qs and As to the top post for quick reference. Going like that for some time we might collect a neat little “Action Buttons Syntax 101”, which I imagine could be of great value for someone unequipped but very willing to take on this journey.

So, what do you think?
Would someone from the community be willing to share knowledge in bite-sized Q&A fashion? @Polina_Zenevich any chance we might also have the devs chime in from time to time? Should I go learn some JS instead? :grimacing:

Do let me know.

1 Like

I think it’s a nice idea - I too am an Action Button fan but with no JS experience or training, relying on trial&error, guesswork and determination. I have become better over time, but I also know that @Haslien and @Sergey_Truhtanov are pretty helpful if you get stuck.

To begin with, I’m pretty sure that I can answer Q1:
The entity’s state field is pretty much the same as any other single-select field, which means that behind the scenes, it is a type of its own, and you have to treat it accordingly.
For example, the following code will get you the state of an entity:

for (const entity of args.currentEntities) {
    const item = await fibery.getEntityById(entity.type, entity.id, ["State"]);
    const state = item["State"];
    return state["Name"];
}

Also, I will add that the (totally undocumented) fibery.executeSingleCommand is a brilliant way to achieve lots of stuff that would otherwise become a bit cumbersome using just the standard action button methods.
Have a look here: Command methods for button, and/or token availability in context
This method might actually help with Q3. I don’t think there is any way to get all fields without knowing what fields you’re asking for. But you could use the "command": "fibery.schema/query" to get the full structure of all your types, and from there, you could iterate through reading all the fields of a given entity’s type.

Using fibery.executeSingleCommand does require getting to grips with objects, but it’s actually not as hard as you might think, and I got a useful tip for a good JS learning resource: Extracting useful info from <del>JSON</del> JS object
Plus, the documentation for the general API commands is pretty easy to follow.

As for Q2, yes it is definitely possible:
await fibery.updateEntity(entity.type, entity.id, { "Name": "Hi 👍" });
:blush:

1 Like

Just a follow on to my answer to Q1. If you meant that you want to know if the state of the entity is (one of) the final state(s), without knowing the names of the states, then you can try:

for (const entity of args.currentEntities) {
    const item = await fibery.getEntityById(entity.type, entity.id, ["State"]);
    const state = await fibery.getEntityById("workflow/state_App_name/Type_name", item["State"]["id"], ["Final"])
    if (state["Final"]) {
        return "Final"
    }
    else {
        return "Not final"
    }
}

This is because ‘Final’ is just a boolean field of the state type, so once you’ve got the state entity, you can look up the value of this field.
Of course, it helps to know the name of the state type, which is where Get Schema comes in handy.

And my final tip, try a website like this to parse the output of "command": "fibery.schema/query"

2 Likes

Hi, @Chr1sG! Thanks for chiming in, your advice on checking the states helped me a lot. :slight_smile: Just wanted to add to it: it seems that the type for the state uses a bit other syntax – it goes "workflow/state_App Name/Type Name".

So, I needed to check for unfinished ‘Time Log’ entities for the user, and I used your code, eventually implementing it like this:

const myLogsCol = await fibery.getEntityById('User', args.currentUser.id, ['Time Log Collection']);

for (const log of myLogsCol['Time Log Collection']) {
    const logInfo = await fibery.getEntityById(logTypeName, log.id, ['id', 'Public Id', 'Task', 'State']);
    const logStateFinal = await fibery.getEntityById("workflow/state_Timers/Time Log", logInfo["State"]["id"], ["Final"]);
    const isLogComplete = logStateFinal['Final'];

    if (!isLogComplete) {
        // cutting this out for brevity...
    }
}

It works, which I enjoy a lot, but the search for the state finality seems to take a somewhat long time. What do you think, is that a given, or is there something I can change about the implementation to make it faster?

As for the emojis (Q2) – is there a way to assign them through some codename like the ones the editor on these forums uses? I don’t actually have the emojis on my PC’s keyboard, so I’m gonna need a more accessible way to enter them while scripting the buttons. :slight_smile:

P.S. A basic smiley here is codenamed :slight_smile: – that’s what I’m talking about.

I’m not a sw dev, but your code looks fine to me. Potentially a quicker way is to do a single query for all timelogs (using executeSingleCommand and “command”: “fibery.entity/query”) but I’d defer to one of the other experts in the forum for a definitive answer.
As for emojis, if you’re on Windows, you can use the Windows key and fullstop (.) to bring up a table that you can select from.

1 Like

Hello everyone.
Sorry for the late response.

Q1: The solution @Chr1sG suggested is correct. But as it looks too cubersome, I’ve modified
getEntityById method. So right now if you set ‘State’ in the list of retrieved fields, it will return Final flag as well. This workds only for Workflow extension. So you may just remove special code, that retrieves Final field.

By the way, under the hood all methods in fibery service are just thin wrappers on fibery.executeSingleCommand. In implementation I just check if State field is a Workflow extension, and add Final field to the list of fields, selected by fibery.executeSingleCommand. This can be implemented in action script as well, but definitely it is much easier to have a useful shortcut.

Q3: The following code should do this:

const fibery = context.getService('fibery');

const schema = await fibery.getSchema();
const typeObject = schema.typeObjectsByName[entity.type];

const entityFields = typeObject.fieldObjects.map(x => x.title)

// affected entities are stored in args.currentEntities;
// to support batch actions they always come in an array
for (const entity of args.currentEntities) {
    // to get collection fields query the API and provide the list of fields
    const entityWithExtraFields = await fibery.getEntityById(entity.type, entity.id, entityFields);

    // to update an entity provide an object with the new values
    console.log(entityWithExtraFields);
}

Note, that I use fibery schema to retrieve all list of fields for a type. Fibery schema package can be found in npm (https://www.npmjs.com/package/fibery-schema). Unfortunately there is no intellisense in the editor for it at the moment. In reality it is just a thin wrapper (with useful utilities) on json, that is returned by fibery.schema/query command. See https://api.fibery.io/#schema for further details.

2 Likes

@aprotasenya – idea to publish some article with useful snippets is great. We will gather cases and do this in the nearest future I hope.

2 Likes

Oh WOW. This is trully an eye-opener, I never knew about that! Thanks, @Chr1sG!

1 Like

Huh, very cool! This really shows the plus of being a part of the community for software in active development! :blush: Thank you, @Sergey_Truhtanov!

And thanks for the code for Q3, and explanations for it, I will give it a try!

I initially thought I would collect the responses from the thread in the first post – only to learn later that I cannot edit a post forever, so there’s no option to add anything to the first thread post. So, an article is our only hope now, yep. Hope this thread grows and helps conduct it. :slight_smile: