Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 46 additions & 23 deletions samples/009-ForceStart/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,69 @@

## Description

This plugin is designed to Force the start of any activity in the technician route, no matter which was the previous order.
`009-ForceStart` lets a technician start the selected activity even when it is not the next ordered activity in the route.

Depending on the condition, it will trigger different actions.
Before any start/suspend action, the plugin checks route queue status from the `open` payload:

If the technicians wants to start an activity while I have another activity started, it will suspend the current started activity
If the pending activity I want to start is not the next one in the route, I will suspend such activity to make it non-ordered and it will start it.
- If `queue.status` is `notActivated`, it sends:
- `method: "update"`
- `actions: [{ entity: "queue", action: "activate_queue" }]`
- After activation, it continues with the force-start flow.
- It retries queue activation up to 3 times; if activation still fails, it redirects back without forcing updates.

## Behavior

When the queue is activated, the plugin decides actions in this order:

1. If selected activity is already `started`: close and redirect.
2. If selected activity is already non-ordered (`position_in_route = "-1"`): start it.
3. Otherwise:
- If another activity is `started`: suspend that activity, then re-check.
- If selected activity is next in route: start it.
- If selected activity is not next in route: set selected activity to non-ordered (`position_in_route = "-1"`), then start it.

After successful start, the plugin closes and redirects to the configured back screen.

## Parameters

**Secure Parameters**
### Secure Parameters

none
None.

**Open Parameters**
### Open Parameters

backScreen : screen where I want to redirect the technician after starting the activity ( default : plugin_by_label )
redirectPluginLabel : if the redirect option is a plugin, label of the plugin ( default : debriefing )
- `backScreen`: destination when plugin closes.
- Default: `activity_by_id`
- `redirectPluginLabel`: plugin label used when `backScreen = plugin_by_label`.

**Properties needed**
## Required Open Message Data

aid
astatus
position_in_route
- `queue.status`
- `activity.aid`
- `activity.astatus`
- `activity.position_in_route`
- `activityList` entries with `aid`, `astatus`, and `position_in_route`

## How to use
## How To Use

Add this plugin to the Activity Details Screen for any activity in Pending status
Add this plugin to Activity Details for activities that technicians may need to force start.

## For development
## Development

### How to build
### Build

1. Install the dependencies
1. Install dependencies: `npm install`
2. Build: `just pack`
3. Zip package: `just zip`

`npm install`
### Upload Credentials (`$HOME/.secure`)

2. Build and compress the plugin
`just upload` resolves credentials from:

`webpack --mode=production`
- `$HOME/.secure/<env>-plugin_mgr.secret` (preferred)
- `$HOME/.secure/<env>.secret` (fallback)

3. Create the zip file that can be uploaded to OFS
Examples:

`cd dist; zip plugin.zip index.html main.js`
- `just upload sunrise0511`
- `just upload env=etaq-dev4`
38 changes: 38 additions & 0 deletions samples/009-ForceStart/assets/js/custom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class OFSCustomOpenMessage extends OFSOpenMessage {
resource: any;
activityList: any;
openParams: any;
queue: any;
}

class OFSError {
Expand Down Expand Up @@ -44,6 +45,27 @@ enum Method {
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));

export class CustomPlugin extends OFSPlugin {
private static readonly MAX_QUEUE_ACTIVATION_ATTEMPTS = 3;
private queueActivationAttempts = 0;

private queue_not_activated(data: any): boolean {
return data?.queue?.status == "notActivated";
}

activate_queue() {
var dataToSend = {
actions: [
{
entity: "queue",
action: "activate_queue",
},
],
};
this.queueActivationAttempts += 1;
globalThis.actionAtReturn = "RECHECK";
this.update(dataToSend);
}

start_activity() {
let activityToUpdate = {
aid: globalThis.aid,
Expand Down Expand Up @@ -125,6 +147,7 @@ export class CustomPlugin extends OFSPlugin {
var plugin = this;
globalThis.backScreen = "activity_by_id";
globalThis.aid = data.activity.aid;
this.queueActivationAttempts = 0;

for (var param in data.openParams) {
if (param == "redirectPluginLabel") {
Expand All @@ -136,6 +159,21 @@ export class CustomPlugin extends OFSPlugin {
this.decide_action(data);
}
decide_action(data?: any) {
if (this.queue_not_activated(data)) {
if (
this.queueActivationAttempts < CustomPlugin.MAX_QUEUE_ACTIVATION_ATTEMPTS
) {
this.activate_queue();
} else {
console.error(
`${this.tag} Queue activation failed after ${this.queueActivationAttempts} attempts`
);
this.redirect();
}
return;
}
this.queueActivationAttempts = 0;

if (data.activity.astatus == "started") {
this.redirect();
} else if (data.activity.position_in_route == "-1") {
Expand Down
43 changes: 33 additions & 10 deletions samples/009-ForceStart/justfile
Original file line number Diff line number Diff line change
@@ -1,22 +1,45 @@
set shell := ["zsh", "-cu"]

plugin_label := "ForceStart"
secure_dir := env_var_or_default("HOME", "") + "/.secure"

default:
just --list

build:
tsc
tsc

dist-clean:
-@rm -rf dist/
-@mkdir dist
@cp index.html dist/
-@rm -rf dist/
-@mkdir dist
@cp index.html dist/

pack: dist-clean
webpack --mode=production
webpack --mode=production

dev-pack: dist-clean
webpack --mode=development
webpack --mode=development

zip: pack
cd dist; zip plugin.zip index.html main.js
cd dist; zip plugin.zip index.html main.js

dev-zip: dev-pack
cd dist; zip plugin.zip index.html main.js
cd dist; zip plugin.zip index.html main.js

upload env="sunrise0511": zip
plugin_mgr_credentials="{{secure_dir}}/{{env}}-plugin_mgr.secret"; \
default_credentials="{{secure_dir}}/{{env}}.secret"; \
if [ -f "$plugin_mgr_credentials" ]; then \
credentials="$plugin_mgr_credentials"; \
elif [ -f "$default_credentials" ]; then \
credentials="$default_credentials"; \
else \
echo "No credentials file found for '{{env}}'. Tried:" >&2; \
echo " $plugin_mgr_credentials" >&2; \
echo " $default_credentials" >&2; \
exit 1; \
fi; \
npx pluginmgr upload {{plugin_label}} --credentials "$credentials" --filename dist/plugin.zip

upload:
pluginmgr --filename dist/plugin.zip upload ForceStart
upload-sunrise:
just upload sunrise0511
Loading