Skip to content

Preserve plan expansion state across chat.update #2701

Description

@amuresia

Package

@slack/web-api

Description

Summary

We are building a Slack integration that posts progress updates using the plan and task_card block types.

Our workflow is:

  1. Call chat.postMessage with a plan block.
  2. The user expands the plan in Slack.
  3. A few minutes later, call chat.update to update the progress of the tasks.

The issue is that every call to chat.update causes the plan block to collapse again, even if the user had already expanded it. This creates a poor user experience because users have to repeatedly expand the plan every time it is updated.

Feature request

It would be very helpful if the plan block supported the following properties, similar to other collapsible components:

  • is_collapsible: false
  • default_collapsed: false

This would allow applications to preserve the expanded state for plans that are intended to be live, continuously updated progress views.

Expected behavior

If a client explicitly sets:

"is_collapsible": false,
"default_collapsed": false

the plan should remain expanded after subsequent chat.update calls instead of collapsing each time the message is refreshed.

Reproduction

1. Create the message

chat.postMessage payload
{
  "channel": "C085HTP5X16",
  "text": "Investigating Jenkins failure",
  "blocks": [
    {
      "type": "plan",
      "title": "Investigating Jenkins failure",
      "tasks": [
        {
          "type": "task_card",
          "task_id": "collect_logs",
          "title": "Collect logs",
          "status": "complete",
          "output": {
            "type": "rich_text",
            "elements": [
              {
                "type": "rich_text_section",
                "elements": [
                  {
                    "type": "text",
                    "text": "Downloaded Jenkins console log and Surefire reports."
                  }
                ]
              }
            ]
          }
        },
        {
          "type": "task_card",
          "task_id": "analyze_logs",
          "title": "Analyze logs",
          "status": "in_progress",
          "details": {
            "type": "rich_text",
            "elements": [
              {
                "type": "rich_text_section",
                "elements": [
                  {
                    "type": "text",
                    "text": "Inspecting stack traces and comparing dependency versions."
                  }
                ]
              }
            ]
          }
        },
        {
          "type": "task_card",
          "task_id": "prepare_recommendation",
          "title": "Prepare recommendation",
          "status": "pending"
        }
      ]
    }
  ]
}

Expand the plan in Slack.

2. Update the message

Call chat.update using the ts returned by chat.postMessage.

chat.update payload
{
  "channel": "C085HTP5X16",
  "ts": "1786651363.258239",
  "text": "Investigating Jenkins failure",
  "blocks": [
    {
      "type": "plan",
      "title": "Investigating Jenkins failure",
      "tasks": [
        {
          "type": "task_card",
          "task_id": "collect_logs",
          "title": "Collect logs",
          "status": "complete",
          "output": {
            "type": "rich_text",
            "elements": [
              {
                "type": "rich_text_section",
                "elements": [
                  {
                    "type": "text",
                    "text": "Downloaded Jenkins console log and Surefire reports."
                  }
                ]
              }
            ]
          }
        },
        {
          "type": "task_card",
          "task_id": "analyze_logs",
          "title": "Analyze logs",
          "status": "complete",
          "output": {
            "type": "rich_text",
            "elements": [
              {
                "type": "rich_text_section",
                "elements": [
                  {
                    "type": "text",
                    "text": "Compared dependency versions and identified the root cause."
                  }
                ]
              }
            ]
          }
        },
        {
          "type": "task_card",
          "task_id": "prepare_recommendation",
          "title": "Prepare recommendation",
          "status": "in_progress",
          "default_collapsed": false,
          "is_collapsible": false,
          "details": {
            "type": "rich_text",
            "elements": [
              {
                "type": "rich_text_section",
                "elements": [
                  {
                    "type": "text",
                    "text": "Preparing the recommended fix and migration guidance."
                  }
                ]
              }
            ]
          }
        }
      ]
    }
  ]
}

Actual behavior

After the chat.update call, the plan is collapsed again, even though the user had already expanded it.

Expected behavior

The plan should either:

  1. Preserve its current expanded/collapsed state across chat.update, or
  2. Support is_collapsible and default_collapsed on the plan block so applications can control this behavior explicitly.

This would significantly improve the user experience for applications that update plans over time, as users would no longer need to repeatedly expand the same plan after every update.

Thank you for considering this enhancement!

Alternatives Considered

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions