logo
Published on

ACE Card View vs Quick View — Design Patterns

The biggest mistake developers make with their first ACE is treating the card view as a miniature web part — stuffing it with too much information, too many buttons, and too much text.
The card view is a glanceable status indicator, not a compact page. The quick view is where detail and action live. Getting this boundary right is the difference between an ACE users check every morning and one they immediately hide from their dashboard.
This article covers the design patterns for each view, with Adaptive Card JSON templates for the most common scenarios.


🗺️ The Design Principle: One Glance, One Action

The Viva Connections Dashboard is designed for mobile-first, ambient consumption. Users see it while walking to a meeting, between tasks, or on their phone during commute. The card view must answer one question in under two seconds:

"Do I need to act on this?"

If the answer is yes, the card shows a count or status and a single button to open the quick view. If the answer is no, the card confirms that with a green indicator or a "nothing new" message. The quick view provides the list, form, or detail needed to act.


🧩 Card View Patterns

Pattern 1 — Count Badge (Approval / Task / Notification)

Best for: approvals, tasks, tickets, unread messages — anything with a count of pending items.

public get data(): IPrimaryTextCardParameters {
  const count = this.state.pendingApprovals.length;

  return {
    primaryText: count === 0
      ? 'All caught up'
      : `${count} Pending Approval${count !== 1 ? 's' : ''}`,
    description: count === 0
      ? 'No items waiting for your review'
      : `Oldest: ${this.state.pendingApprovals[0]?.title ?? ''}`,
    title: 'Approvals'
  };
}

Rule: Show the count prominently. Show the most urgent item's title as the description. If count is 0, show a positive confirmation — not a blank card.


Pattern 2 — Status Indicator (Health / System / Availability)

Best for: system health, room availability, shift status, connection status.

public get data(): IPrimaryTextCardParameters {
  const status = this.state.systemStatus; // 'Operational' | 'Degraded' | 'Down'

  const statusMap = {
    'Operational': { text: '✓ All Systems Operational', desc: 'Last checked 5 min ago' },
    'Degraded':    { text: '⚠ Partial Outage', desc: 'Some services affected' },
    'Down':        { text: '✗ Service Disruption', desc: 'IT team notified' }
  };

  return {
    primaryText: statusMap[status]?.text ?? 'Status Unknown',
    description: statusMap[status]?.desc ?? ''
  };
}

Rule: Use plain language. Users should not need to interpret a status code — "All Systems Operational" beats "STATUS_OK".


Pattern 3 — Next Item (Calendar / Schedule / Due Date)

Best for: next meeting, next shift, next deadline, next event.

public get data(): IPrimaryTextCardParameters {
  const next = this.state.nextMeeting;

  if (!next) {
    return {
      primaryText: 'No upcoming meetings',
      description: 'Your calendar is clear for today'
    };
  }

  return {
    primaryText: next.subject,
    description: `${next.startTime}${next.location ?? 'No location'}`
  };
}

Rule: Show the next item only — not a list. The quick view shows the list. One item in the card creates focus; a list creates overwhelm.


🧩 Quick View Patterns

Pattern 1 — Numbered List with Actions

The most common quick view: a list of items, each with a primary action button.

QuickViewTemplate.json

{
  "type": "AdaptiveCard",
  "version": "1.5",
  "body": [
    {
      "type": "TextBlock",
      "text": "Pending Approvals",
      "weight": "Bolder",
      "size": "Medium"
    },
    {
      "type": "Container",
      "$data": "${items}",
      "items": [
        {
          "type": "ColumnSet",
          "columns": [
            {
              "type": "Column",
              "width": "stretch",
              "items": [
                {
                  "type": "TextBlock",
                  "text": "${title}",
                  "weight": "Bolder",
                  "wrap": true
                },
                {
                  "type": "TextBlock",
                  "text": "Requested by ${requestedBy} · ${daysAgo} days ago",
                  "isSubtle": true,
                  "size": "Small",
                  "spacing": "None"
                }
              ]
            },
            {
              "type": "Column",
              "width": "auto",
              "items": [
                {
                  "type": "ActionSet",
                  "actions": [
                    {
                      "type": "Action.OpenUrl",
                      "title": "Review",
                      "url": "${url}",
                      "style": "positive"
                    }
                  ]
                }
              ]
            }
          ]
        }
      ],
      "separator": true
    }
  ]
}

Pattern 2 — Summary + Detail Toggle

For items where the user needs a summary first, then can expand to details:

{
  "type": "AdaptiveCard",
  "version": "1.5",
  "body": [
    {
      "type": "TextBlock",
      "text": "IT Service Tickets",
      "weight": "Bolder",
      "size": "Medium"
    },
    {
      "type": "Container",
      "$data": "${tickets}",
      "items": [
        {
          "type": "TextBlock",
          "text": "#${id} — ${title}",
          "weight": "Semibold",
          "wrap": true
        },
        {
          "type": "FactSet",
          "facts": [
            { "title": "Status", "value": "${status}" },
            { "title": "Priority", "value": "${priority}" },
            { "title": "Opened", "value": "${openedDate}" }
          ]
        }
      ],
      "separator": true,
      "selectAction": {
        "type": "Action.OpenUrl",
        "url": "${url}"
      }
    }
  ],
  "actions": [
    {
      "type": "Action.OpenUrl",
      "title": "Open Service Portal",
      "url": "${portalUrl}"
    }
  ]
}

Pattern 3 — Confirmation Form

For quick actions that need one confirmation field — approving a request, updating a status, submitting a brief response:

{
  "type": "AdaptiveCard",
  "version": "1.5",
  "body": [
    {
      "type": "TextBlock",
      "text": "Approve Leave Request",
      "weight": "Bolder",
      "size": "Medium"
    },
    {
      "type": "FactSet",
      "facts": [
        { "title": "Employee", "value": "${employeeName}" },
        { "title": "Dates", "value": "${leaveDates}" },
        { "title": "Type", "value": "${leaveType}" }
      ]
    },
    {
      "type": "Input.Text",
      "id": "comments",
      "placeholder": "Add a comment (optional)",
      "isMultiline": true
    }
  ],
  "actions": [
    {
      "type": "Action.Submit",
      "title": "Approve",
      "data": { "action": "approve", "itemId": "${itemId}" },
      "style": "positive"
    },
    {
      "type": "Action.Submit",
      "title": "Reject",
      "data": { "action": "reject", "itemId": "${itemId}" },
      "style": "destructive"
    }
  ]
}

Handling the submit action in the quick view class:

public async onAction(action: IActionArguments): Promise<void> {
  if (action.type === 'Submit') {
    const { actionId, itemId, comments } = action.data;

    if (actionId === 'approve') {
      await this._approvalService.approve(itemId, comments);
      // Navigate back and refresh state
      this.quickViewNavigator.close();
      await this.adaptiveCardExtensionContext.setState(
        await this._approvalService.getPendingApprovals()
      );
    }
  }
}

📐 Card View Sizing Guidelines

The Viva Connections Dashboard supports three card sizes:

SizeUse case
Medium (default)Most ACEs — sufficient for a count + description + one button
LargeWhen the quick view equivalent is too heavy — show a list of 3 items directly in the card
SmallStatus-only cards — single indicator, no description, no button

Declare supported sizes in the manifest:

{
  "preconfiguredEntries": [
    {
      "groupId": "...",
      "group": { "default": "Cards" },
      "title": { "default": "Approvals" },
      "description": { "default": "Pending approvals card" },
      "officeFabricIconFontName": "Checkmark",
      "cardSize": "Medium",
      "supportedCardSizes": ["Medium", "Large"]
    }
  ]
}

✅ Summary

  • The card view answers one question: "Do I need to act?" — count, status, or next item only.
  • The quick view is where lists, detail, and forms live — users come here to act, not just to read.
  • Show a positive "all clear" state when there are no pending items — a blank or empty card confuses users.
  • Use ColumnSet in quick view templates to align action buttons to the right of each list item.
  • Action.Submit handles in-card form submissions; Action.OpenUrl opens links in a new browser tab.
  • Support at least Medium and Large card sizes for flexibility — admins configure the size per dashboard layout.

Happy coding!

Ad image