Advanced 45 min read

Capstone Reference Implementation: Components and UI

By the end of this lesson, you'll be able to:

  • Implement the planned component tree with proper parent/child composition
  • Wire the datatable, account summary, and modal to the Apex layer built in Lesson 2
  • Apply responsive, mobile-ready layout from the start

Prerequisites: "Capstone Reference Implementation: Data Layer and Apex"

The Parent: commandCenter

import { LightningElement, wire } from 'lwc';
import getOpenCases from '@salesforce/apex/CommandCenterController.getOpenCases';
import NewCaseModal from 'c/newCaseModal';

export default class CommandCenter extends LightningElement {
    wiredCasesResult;
    selectedAccountId;

    @wire(getOpenCases)
    wiredCases(result) {
        this.wiredCasesResult = result;
    }

    get cases() {
        return this.wiredCasesResult?.data ?? [];
    }

    handleCaseSelected(event) {
        this.selectedAccountId = event.detail.accountId;
    }

    async handleNewCase() {
        const result = await NewCaseModal.open({ size: 'small' });
        if (result === 'created') {
            await refreshApex(this.wiredCasesResult);
        }
    }
}
<div class="slds-grid slds-wrap slds-gutters">
    <div class="slds-col slds-size_1-of-1 slds-large-size_2-of-3">
        <c-case-list cases={cases} oncaseselected={handleCaseSelected}></c-case-list>
    </div>
    <div class="slds-col slds-size_1-of-1 slds-large-size_1-of-3">
        <c-account-summary account-id={selectedAccountId}></c-account-summary>
    </div>
</div>
<lightning-button label="New Case" onclick={handleNewCase}></lightning-button>

The parent owns the shared getOpenCases wire and the selectedAccountId state, passing it down to c-account-summary (Module 5's @api pattern) — the SLDS grid (Module 9) stacks to one column on mobile, two-thirds/one-third on large screens.

The Child: caseList

import { LightningElement, api } from 'lwc';
import updateCaseStatus from '@salesforce/apex/CommandCenterController.updateCaseStatus';

const COLUMNS = [
    { label: 'Subject', fieldName: 'subject', type: 'text' },
    { label: 'Status', fieldName: 'status', type: 'text', editable: true },
];

export default class CaseList extends LightningElement {
    @api cases;
    columns = COLUMNS;
    draftValues = [];

    handleRowClick(event) {
        this.dispatchEvent(new CustomEvent('caseselected', {
            detail: { accountId: event.detail.row.accountId },
        }));
    }

    async handleSave(event) {
        const draftValues = event.detail.draftValues;
        await Promise.all(draftValues.map(draft =>
            updateCaseStatus({ caseId: draft.caseId, newStatus: draft.status })
        ));
        this.draftValues = [];
    }
}

caseselected (Module 5's CustomEvent pattern) tells the parent which Account to show a summary for; inline editing (Module 10) and Promise.all bulk-persist status changes exactly as in Module 19's Case Management project.

The Child: accountSummary

import { LightningElement, api, wire } from 'lwc';
import getAccountSummary from '@salesforce/apex/CommandCenterController.getAccountSummary';

export default class AccountSummary extends LightningElement {
    @api accountId;

    @wire(getAccountSummary, { accountId: '$accountId' })
    summary;
}

The reactive '$accountId' parameter (Module 6) means simply changing the parent's selectedAccountId automatically re-fetches the right Account's summary — no manual refresh call needed for this piece.

Exercise

Explain, as a comment, why caseselected is dispatched as a CustomEvent rather than accountSummary querying the selected Case directly.

Show hint

Recall Module 5's child-to-parent communication rationale.

JAVASCRIPT

Exercise

Challenge: explain, as a comment, why accountId is a reactive ($-prefixed) wire parameter in accountSummary.

Show hint

Recall Module 6's reactive parameter lesson.

JAVASCRIPT

Capstone Reference Implementation: Components and UI Quiz

1. What owns the shared getOpenCases wire and selectedAccountId state?

2. How does caseList communicate the selected Case's Account back to the parent?

3. What makes accountSummary automatically re-fetch when a different Case is selected?

4. What SLDS layout technique makes the workspace stack to one column on mobile?

5. What persists Case status changes made via inline editing?

Log in to submit the quiz and save your score.

My Notes

Log in to keep private notes on this lesson.

Questions about this lesson

No questions yet — be the first to ask.

Log in to ask a question about this lesson.

Summary

The component tree planned in Lesson 1 becomes real markup and JavaScript — a datatable-driven Case list, an LDS-style Account summary, and a modal for creating new Cases, laid out responsively from the start.