ケースフィードのレイアウトと外観のカスタマイズ
カスタマイズされたケースフィードページを Visualforce で作成すると、表示するアクションとツールや、ページ上の表示場所など、全体的なレイアウトと外観を制御できます。また、ページの機能を向上するために、他の標準およびカスタムのコンソールコンポーネントを含めることもできます。
このガイドに記載されているケース固有の 4 つの Visualforce コンポーネントに加え、chatter:feed コンポーネントも使用してケースフィードをカスタマイズできます。次の表に、コンポーネントの属性を示します。
chatter:feed 属性
| 属性名 | 属性型 | 説明 | 必須項目 | API バージョン | アクセス |
|---|---|---|---|---|---|
| entityId | id | フィードを表示するレコードのエンティティ ID。例: Contact.Id。 | はい | 25.0 | |
| feedItemType | String | Chatter EntityFeed または UserProfileFeed を絞り込むフィード項目種別。許容値についての詳細は、『API オブジェクトリファレンスガイド』にある FeedItem オブジェクトリストの [型] 項目を参照してください。 | 25.0 | ||
| id | String | ページの他のコンポーネントがコンポーネントを参照できるようにする識別子。 | 20.0 | グローバル | |
| onComplete | String | 投稿またはコメントをフィードに追加した後にコールする JavaScript 関数。 | 25.0 | ||
| rendered | Boolean | アクションのレイアウトに定義された追加項目を表示するかどうかを示す boolean 値。 | 20.0 | グローバル | |
| reRender | Object | action メソッドの結果がクライアントに返されるときに再作成される 1 つ以上のコンポーネントの ID。この値には、単一の ID、ID のカンマ区切りのリスト、または ID のリストまたはコレクションの差し込み項目の式を使用できます。 | 25.0 | ||
| showPublisher | Boolean | Chatter パブリッシャーを表示します。 | 25.0 |
使用事例
Acme Entertainment は、複数のプラットフォームで 100 万人を超えるユーザが使用するオンラインゲームを作成しています。Acme の 1500 人のサポートエージェントは、デスクトップコンピュータ、ラップトップ、タブレットを使用していますが、会社では異なるデバイスをまたいでデザインを標準化するためにケースフィードページをカスタマイズしたいと考えています。また、エージェントがケース活動を追跡しやすくするために、条件も使用したいと考えています。
Acme では、次の手順を使用して、カスタマイズされたケースフィードページを作成しました。
- パブリッシャーおよび他のケースフィードツールが常にページ中央に表示されるようにするため、chatter:feed コンポーネントを使用してフィードをサイドバーに配置しました。
-
ケースの発生源に応じて、フィード条件および自動選択されたデフォルトの条件を再配置しました。
- 発生源がメールの場合、デフォルト条件は [メール]。
- 発生源が電話の場合、デフォルト条件は [通話ログ]。
- 発生源が Web の場合、デフォルト条件は [ポータルアンサー]。
- ページサイズの変化に合わせてパブリッシャーを拡張/収縮することで、異なる画面サイズで一貫した外観にするため、apex:emailPublisher、apex:logCallPublisher、および support:portalPublisher をパーセントベースの幅にしました。
- パブリッシャーアクションのタブ方向を、標準の左側での垂直方向から、ページ上部での水平方向に変更しました。
コードサンプル
次のコードサンプルは、カスタムの [メール]、[ポータル]、[活動の記録]、[ケースの詳細] タブがある Visualforce ページを示します。
1swfobject.registerObject("clippy.codeblock-0", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<apex:page standardController="Case">
18
19 <!-- Repositions publisher tabs to a horizontal arrangement on top of the page -->
20 <ul class="demoNav" style="list-style: none; overflow: hidden">
21 <li style="float:left">
22 <a id="custom_email_tab" class="selected" href="javascript:void(0);"
23 onclick="getDemoSidebarMenu().selectMenuItem('custom_email_tab');">
24 <span class="menuItem">Email Customer</span>
25 </a>
26 </li>
27 <li style="float:left">
28 <a id="custom_log_call_tab" href="javascript:void(0);"
29 onclick="getDemoSidebarMenu().selectMenuItem('custom_log_call_tab');">
30 <span class="menuItem">Log Call</span>
31 </a>
32 </li>
33 <li style="float:left">
34 <a id="custom_portal_tab" href="javascript:void(0);"
35 onclick="getDemoSidebarMenu().selectMenuItem('custom_portal_tab');">
36 <span class="menuItem">Portal Answer</span>
37 </a>
38 </li>
39 <li style="float:left">
40 <a id="custom_detail_tab" href="javascript:void(0);"
41 onclick="getDemoSidebarMenu().selectMenuItem('custom_detail_tab');">
42 <span class="menuItem">Case Details</span>
43 </a>
44 </li>
45 </ul>
46
47 <!-- Email action -->
48 <div id="custom_email_pub_vf">
49 <apex:emailPublisher entityId="{!case.id}"
50 width="80%"
51 emailBodyHeight="10em"
52 showAdditionalFields="false"
53 enableQuickText="true"
54 toAddresses="{!case.contact.email}"
55 toVisibility="readOnly"
56 fromAddresses="support@cirrus.com"
57 onSubmitSuccess="refreshFeed();" />
58 </div>
59
60 <!-- Log call action -->
61 <div id="custom_log_call_vf" style="display:none">
62 <apex:logCallPublisher entityId="{!case.id}"
63 width="80%"
64 logCallBodyHeight="10em"
65 reRender="demoFeed"
66 onSubmitSuccess="refreshFeed();" />
67 </div>
68
69 <!-- Portal action -->
70 <div id="custom_portal_vf" style="display:none">
71 <support:portalPublisher entityId="{!case.id}"
72 width="80%"
73 answerBodyHeight="10em"
74 reRender="demoFeed"
75 answerBody="Dear {!Case.Contact.FirstName},
76 \n\nHere is the solution to your case.\n\nBest regards,\n\nSupport"
77 onSubmitSuccess="refreshFeed();" />
78 </div>
79
80 <!-- Case detail page -->
81 <div id="custom_detail_vf" style="display:none">
82 <apex:detail inlineEdit="true" relatedList="true" rerender="demoFeed" />
83 </div>
84
85 <!-- Include library for using service desk console API -->
86 <apex:includeScript value="/support/console/25.0/integration.js"/>
87
88 <!-- Javascript for switching publishers -->
89 <script type="text/javascript">
90 function DemoSidebarMenu() {
91 var menus = {"custom_email_tab" : "custom_email_pub_vf",
92 "custom_log_call_tab" : "custom_log_call_vf",
93 "custom_portal_tab" : "custom_portal_vf",
94 "custom_detail_tab" : "custom_detail_vf"};
95
96 this.selectMenuItem = function(tabId) {
97 for (var index in menus) {
98 var tabEl = document.getElementById(index);
99 var vfEl = document.getElementById(menus[index]);
100
101 if (index == tabId) {
102 tabEl.className = "selected";
103 vfEl.style.display = "block";
104 } else {
105 tabEl.className = "";
106 vfEl.style.display = "none";
107 }
108 }
109 };
110 }
111 var demoSidebarMenu;
112 var getDemoSidebarMenu = function() {
113 if (!demoSidebarMenu) {
114 demoSidebarMenu = new DemoSidebarMenu();
115 }
116 return demoSidebarMenu;
117 };
118 </script>
119
120 <!-- Javascript for firing event to refresh feed in the sidebar -->
121 <script type="text/javascript">
122 function refreshFeed() {
123 sforce.console.fireEvent
124 ('Cirrus.samplePublisherVFPage.RefreshFeedEvent', null, null);
125 }
126 </script>
127</apex:page>次のサンプルに、上記の Visualforce ページで使用されるコントローラ拡張を含む Apex クラスを示します。
1swfobject.registerObject("clippy.codeblock-1", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public class MyCaseExtension {
18 private final Case mycase;
19 private String curFilter;
20
21 public MyCaseExtension(ApexPages.StandardController stdController) {
22 this.mycase = (Case)stdController.getRecord();
23
24 // initialize feed filter based on case origin
25 if (this.mycase.origin.equals('Email')) {
26 curFilter = 'EmailMessageEvent';
27 } else if (this.mycase.origin.equals('Phone')) {
28 curFilter = 'CallLogPost';
29 } else if (this.mycase.origin.equals('Web')) {
30 curFilter = 'CaseCommentPost';
31 }
32 }
33
34 public String getCurFilter() {
35 return curFilter;
36 }
37
38 public void setCurFilter(String c) {
39 if (c.equals('All')) {
40 curFilter = null;
41 } else {
42 curFilter = c;
43 }
44 }
45
46 public PageReference refreshFeed() {
47 return null;
48 }
49}次のサンプルは、ケースにカスタムフィード条件と Chatter フィードがある Visualforce ページを示します。このページは、Salesforce コンソールのサイドバーで使用できます。
1swfobject.registerObject("clippy.codeblock-2", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<apex:page standardController="Case" extensions="MyCaseExtension">
18
19 <!-- Feed filter -->
20 <div>
21 <span>Feed Filters:</span>
22 <select onchange="changeFilter(this.options[selectedIndex].value);"
23 id="custom_filterSelect">
24 <option value="All" id="custom_all_option">All</option>
25 <option value="EmailMessageEvent"
26 id="custom_email_option">Emails</option>
27 <option value="CaseCommentPost"
28 id="custom_web_option">Portal Answers</option>
29 <option value="CallLogPost"
30 id="custom_phone_option">Call Logs</option>
31 </select>
32 </div>
33
34 <apex:form >
35 <!-- actionFunction for refreshing feed when the feed filter is updated -->
36 <apex:actionFunction action="{!refreshFeed}" name="changeFilter"
37 reRender="custom_demoFeed" immediate="true" >
38 <apex:param name="firstParam" assignTo="{!curFilter}" value="" />
39 </apex:actionFunction>
40
41 <!-- actionFunction for refreshing feed when there is an event fired for
42 updating the feed -->
43 <apex:actionFunction action="{!refreshFeed}" name="updateFeed"
44 reRender="custom_demoFeed" immediate="true" />
45 </apex:form>
46
47 <!-- Chatter feed -->
48 <chatter:feed entityId="{!case.id}" showPublisher="false"
49 feedItemType="{!curFilter}" id="custom_demoFeed" />
50
51 <!-- Include library for using service desk console API -->
52 <apex:includeScript value="/support/console/25.0/integration.js"/>
53
54 <!-- Javascript for adding event listener for refreshing feed -->
55 <script type="text/javascript">
56
57 var listener = function (result) {
58 updateFeed();
59 };
60
61 // add a listener for the 'Cirrus.samplePublisherVFPage.RefreshFeedEvent'
62 event type
63 sforce.console.addEventListener('Cirrus.samplePublisherVFPage.RefreshFeedEvent',
64 listener);
65 </script>
66
67 <!-- Javascript for initializing select option based on case origin -->
68 <script type="text/javascript">
69 window.onload = function() {
70 var caseOrigin = "{!case.origin}";
71 if (!caseOrigin) {
72 caseOrigin = "all";
73 } else {
74 caseOrigin = caseOrigin.toLowerCase();
75 }
76 var selectElem = document.getElementById('custom_' + caseOrigin + '_option');
77 if (selectElem) {
78 selectElem.selected = true;
79 }
80 }
81 </script>
82
83</apex:page>