TrailheadにUX Prototyping Basicsのモジュールが用意されています。このモジュールでは開発前にプロトタイプの実装を行うことのメリットが紹介されていました。またSalesforce社ではどのようにこういった作業をおこなっているかも触れられていました。
Lightning PageとLightning Componentを作りながらプロトタイプ作成→本実装までの流れを確認することができます。次のような画面を開発することができました。
VerticalNavigation.cmp
<aura:component implements="force:appHostable, flexipage:availableForAllPageTypes,flexipage:availableForRecordHome, force:hasRecordId,forceCommunity:availableForAllPageTypes, force:lightningQuickAction" access="global" > <div class="slds-grid slds-grid--vertical slds-navigation-list--vertical"> <h2 class="slds-text-title--caps slds-p-around--medium" id="entity-header">Results for 'CO'</h2> <ul> <li class="slds-is-active"> <a href="javascript:void(0);" class="slds-navigation-list--vertical__action slds-text-link--reset" aria-describedby="entity-header"> All </a> </li> <li> <a href="javascript:void(0);" class="slds-navigation-list--vertical__action slds-text-link--reset" aria-describedby="entity-header"> Accounts </a> </li> <li> <a href="javascript:void(0);" class="slds-navigation-list--vertical__action slds-text-link--reset" aria-describedby="entity-header"> Contacts </a> </li> <li> <a href="javascript:void(0);" class="slds-navigation-list--vertical__action slds-text-link--reset" aria-describedby="entity-header"> Leads </a> </li> </ul> </div> </aura:component>
ResultSection.cmp
<aura:component controller="SearchResultsController" implements="force:appHostable, flexipage:availableForAllPageTypes, flexipage:availableForRecordHome,force:hasRecordId, forceCommunity:availableForAllPageTypes, force:lightningQuickAction" access="global" > <aura:attribute name="accounts" type="Account[]"/> <aura:attribute name="contacts" type="Contact[]"/> <aura:attribute name="leads" type="Lead[]"/> <aura:handler name="init" value="{!this}" action="{!c.doInit}"/> <div> <h2 class="slds-text-heading--medium slds-p-vertical--medium">Accounts</h2> <div class="slds-grid"> <ul class="slds-col slds-size--1-of-1"> <aura:iteration items="{!v.accounts}" var="account"> <li class="slds-size--1-of-3 slds-show--inline-block"> <lightning:card variant="narrow" iconName="standard:account" class="slds-m-around--small"> <aura:set attribute="title"> {!account.Name} </aura:set> <div class="slds-tile slds-p-horizontal--large"> <div class="slds-tile__detail slds-text-body--small"> <dl class="slds-list--horizontal slds-wrap"> <dt class="slds-item--label slds-text-color--weak slds-truncate" title="First Label">Phone:</dt> <dd class="slds-item--detail slds-truncate">{!account.Phone}</dd> <dt class="slds-item--label slds-text-color--weak slds-truncate" title="Second Label">Website:</dt> <dd class="slds-item--detail slds-truncate">{!account.Website}</dd> <dt class="slds-item--label slds-text-color--weak slds-truncate" title="Third Label">Account Owner:</dt> <dd class="slds-item--detail slds-truncate">{!account.OwnerId}</dd> </dl> </div> </div> </lightning:card> </li> </aura:iteration> </ul> </div> <h2 class="slds-text-heading--medium slds-p-vertical--medium">Contacts</h2> <div class="slds-grid"> <ul class="slds-col slds-size--1-of-1"> <aura:iteration items="{!v.contacts}" var="contact" indexVar="index"> <li class="slds-size--1-of-3 slds-show--inline-block"> <lightning:card variant="narrow" iconName="standard:contact" class="slds-m-around--small"> <aura:set attribute="title"> {!contact.Name} </aura:set> <div class="slds-tile slds-p-horizontal--large"> <div class="slds-tile__detail slds-text-body--small"> <dl class="slds-list--horizontal slds-wrap"> <dt class="slds-item--label slds-text-color--weak slds-truncate" title="First Label">Email Address:</dt> <dd class="slds-item--detail slds-truncate">{!contact.Email}</dd> <dt class="slds-item--label slds-text-color--weak slds-truncate" title="Second Label">Title:</dt> <dd class="slds-item--detail slds-truncate">{!contact.Title}</dd> <dt class="slds-item--label slds-text-color--weak slds-truncate" title="Third Label">Phone:</dt> <dd class="slds-item--detail slds-truncate">{!contact.Phone}</dd> </dl> </div> </div> </lightning:card> </li> </aura:iteration> </ul> </div> <h2 class="slds-text-heading--medium slds-p-vertical--medium">Leads</h2> <div class="slds-grid"> <ul class="slds-col slds-size--1-of-1"> <aura:iteration items="{!v.leads}" var="lead" indexVar="index"> <li class="slds-size--1-of-3 slds-show--inline-block"> <lightning:card variant="narrow" iconName="standard:lead" class="slds-m-around--small"> <aura:set attribute="title"> {!lead.Name} </aura:set> <div class="slds-tile slds-p-horizontal--large"> <div class="slds-tile__detail slds-text-body--small"> <dl class="slds-list--horizontal slds-wrap"> <dt class="slds-item--label slds-text-color--weak slds-truncate" title="Second Label">Company:</dt> <dd class="slds-item--detail slds-truncate">{!lead.Company}</dd> <dt class="slds-item--label slds-text-color--weak slds-truncate" title="Second Label">Email Address:</dt> <dd class="slds-item--detail slds-truncate">{!lead.Email}</dd> <dt class="slds-item--label slds-text-color--weak slds-truncate" title="Third Label">Status:</dt> <dd class="slds-item--detail slds-truncate">{!lead.Status}</dd> <dt class="slds-item--label slds-text-color--weak slds-truncate" title="First Label">Phone:</dt> <dd class="slds-item--detail slds-truncate">{!lead.Phone}</dd> </dl> </div> </div> </lightning:card> </li> </aura:iteration> </ul> </div> </div> </aura:component>
ResultSectionController.js
({ doInit : function(component, event, helper) { helper.getAccounts(component); helper.getContacts(component); helper.getLeads(component); } })
ResultSectionHelper.js
({ getAccounts : function(cmp) { var action = cmp.get("c.getAccounts"); action.setCallback(this, function(response){ var state = response.getState(); if (state === "SUCCESS") { cmp.set("v.accounts", response.getReturnValue()); } }); $A.enqueueAction(action); }, getContacts : function(cmp) { var action = cmp.get("c.getContacts"); action.setCallback(this, function(response){ var state = response.getState(); if (state === "SUCCESS") { cmp.set("v.contacts", response.getReturnValue()); } }); $A.enqueueAction(action); }, getLeads : function(cmp) { var action = cmp.get("c.getLeads"); action.setCallback(this, function(response){ var state = response.getState(); if (state === "SUCCESS") { cmp.set("v.leads", response.getReturnValue()); } }); $A.enqueueAction(action); }, })
SearchResultsController
public with sharing class SearchResultsController { @AuraEnabled public static List<Account> getAccounts() { List<Account> accounts = [SELECT Id, Name, Phone, Website, OwnerId FROM Account LIMIT 5]; return accounts; } @AuraEnabled public static List<Contact> getContacts() { List<Contact> contacts = [SELECT Id, Name, Phone, Email, Title FROM Contact LIMIT 5]; return contacts; } @AuraEnabled public static List<Lead> getLeads() { List<Lead> leads = [SELECT Id, Name, Company, Email, Status, Phone FROM Lead LIMIT 5]; return leads; } }
ひさしぶりにLightingコンポーネントとLightning Pageをさわりましたが、lightning:cardタグなど開発がやりやすくなっているようでした。