# ION Actions

### LOOK [HERE ](https://manual-v2.firstresonance.io/os/ion-actions)FOR AN UPDATED ION ACTIONS EXPERIENCE

It helps you accomplish everything laid out below but with a in line code editor and streamline UI.

### **1. Introduction**

Control workflows (e.g. when users can progress status), set conditions for data validation (e.g. require fields).

### 2. Turn rules on in your environment

First, rules must be enabled in your organization settings in order to use them.

Check that the rules are enabled with the below query:

```graphql
{
  me {
    organization {
      id
      _etag
      settings {
        rules {
          enabled
        }
      }
    }
  }
}
```

If they are not, enable them with this mutation:

```graphql
mutation UpdateOrganization($input: UpdateOrganizationInput!) {
  updateOrganization(input: $input) {
    organization {
      settings {
        rules {
          enabled
          errorState
          errorStateMessage
        }
      }
    }
  }
}
```

With the following input variables (retrieve the `etag` from the first query):

```json
{
  "input": {
    "id": <populate from first query>,
    "etag": "<populate from first query>",
    "settings": {
      "rules": {
        "enabled": true
      }
    }
  }
}
```

### 3. Definition of ION Action Attributes

Here are the definitions of key ION Action attributes:

* **Title:** The title is a visual identifier for the ION Action, shown in toast notifications, and used for internal tracking and logging. It should briefly describe the purpose of the ION Action.
* **Context:** The context is a placeholder that contains the data used in the ION Action's code. It can include model attributes, user roles, issue details, or any other relevant data. It is represented as a JSON string in GraphQL input. An example of a context structure could be:

```python
{
    'changes': {
        'entities': {},
        'issues': {}
    },
    'currentUser': {
        'email': 'alex@firstresonance.io',
        'roles': ['user', 'admin'],
        'teams': []
    },
    'issue': {
        'approvalRequests': {},
        'approvals': {},
        'attributes': [
            {'key': 'Cause Code', 'value': None },
            {'key': 'Component Part', 'value': None },
            {'key': 'Defect Type', 'value': None },
            {'key': 'Department', 'value': None },
            {'key': 'Major Subsystem', 'value': None }
        ],
        'causeCondition': ""
    }
}
```

* **Code:** The code attribute contains the Python-based script that is executed when the ION Action is triggered. It specifies the conditions and actions of the ION Action. If the conditions are not met, a ValidationError is raised.
* **ErrorState:** All active rules will BLOCK the action from occurring if the rule conditions are met. The errorState is a deprecated feature for now, so "ALLOW" or "BLOCK" as an error state are both going to BLOCK the action upon execution of the rule.

### 4. Creating an ION Action with GraphQL

#### **Create an ION Action**

```graphql
mutation CreateRule($create_rule: CreateRuleInput!) {
  createRule(input: $create_rule) {
    rule {
      id
      enabled
      status
      title
      target
      eventType
      context
      code
      errorState
      _etag
    }
  }
}
```

Variables:

```json
{
  "create_rule": {
    "enabled": true,
    "title": "This is the message that shows in the toast banner",
    "target": "ISSUE",
    "eventType": "UPDATE",
    "ruleType": "VALIDATION",
    "errorState": "ALLOW",
    "context": "specify the fields for the code to interpret",
    "code": "the python code which runs the logic - must be a single line! (chatGPT helps a lot here)"
  }
}
```

### 5. Updating an ION Action with GraphQL

**Find the rule you seek to update** You'll need the rule's `id` and `_etag` value for the next step

#### Query all rules

```
{
  rules{
    edges{
      node{
        id
        _etag
        title
        ruleType
        eventType
        target
        code
        context
        enabled
      }
    }
  }
}
```

#### **Write the UpdateRule Mutation:**

Write a mutation using the **`UpdateRule`** input type, specifying the rule's `id`, `_etag` and the updates you seek to make (generally the `context`, `code`, or `enabled` values).

```graphql
mutation UpdateRule($update_rule: UpdateRuleInput!) {
  updateRule(input: $update_rule) {
    rule {
      id
      _etag
      enabled
      title
      context
      code
    }
  }
}
```

Query variables:

```json
{
  "update_rule": {
    "id": from step 1,
    "etag": "copied from the step 1",
    "enabled": "true or false"
    "title": "You could modify the title here, or remove this line",
    "context": "overwrite the query, or remove this line",
    "code": "completely overwrite the code, or remove this line"
  }
}
```

**Execute the Mutation:** Run the mutation in the GraphQL Explorer to update the ION Action.

**NOTE:** Every time you update a rule, its `_etag` value will change, so you need to start from step 1 each time you update a rule.

### 6. Deleting an ION Action with GraphQL

This isn't necessary as you can set `enabled` to "false", but to delete an existing ION Action:

1. [**Query the rule** ](#query-all-rules)**to retrieve its `id` and `_etag` value**
2. **Write the DeleteRule Mutation:** Write a mutation using the **`DeleteRule`** mutation, specifying the ION Action `id` and **`_etag`** value.
3. **Execute the Mutation:** Run the mutation in the GraphQL Explorer to delete the ION Action.

#### **Example: Deleting an ION Action**

```graphql
mutation DeleteRule($id: ID!, $etag: String!) {
  deleteRule(id: $id, etag: $etag) {
    id
  }
}
```

Query variables:

```json
{
  "id": <ION_Action_id>,
  "etag": "<current_etag_value>"
}
```
