スケジュールページ
スケジュールページは、カレンダーまたはタイムライン表示のカスタム生成を可能にする、スクリプトのコレクションを含むレコードです。
タイムラインスケジュールページを作成するには、ページ/イベントフローを理解し、クライアントおよびサーバーサイドの JavaScript を作成できる必要があります。
スケジュールページフォーム
スケジュールページにアクセスするには、次の場所に移動します。 .
| フィールド | フィールドタイプ | 説明 |
|---|---|---|
| 名前 | 文字列 | 現在のスケジュールページの識別に使用する一般名。 |
| スケジュールタイプ | 文字列 | スケジュールタイプは、「sysparm_page_schedule_type」URI パラメーターを介してスケジュールページを一意に識別するために使用する文字列です。たとえば、次のようにスケジュールページにアクセスできます。
または、「sysparm_page_sys_id」URI パラメーターをスケジュールページの 32 文字からなる 16 進数で構成される一意のシステム識別子に設定すると、スケジュールページにもアクセスできます。 |
| ビュータイプ | 選択肢 | 各ビュータイプには、異なるフィールドの組み合わせが表示されます。利用可能なオプションは 2 つあります。
|
| 説明 | 文字列 | 現在のスケジュールページに関する詳細情報を表示する一般的な説明。このフィールドは必須ではありません。 |
| Init 関数名 | 文字列 | 注: init 関数名は、[カレンダー] タイプのスケジュールページの [クライアントスクリプト] 関数内で呼び出す JavaScript 関数の名前を指定します。この機能は、[カレンダー] タイプのスケジュールページでのみ使用されます。 |
| HTML | 文字列 | 注: HTML フィールドは、Jelly によって解析され、カレンダーの残りの部分より前に表示ページに挿入される、スクリプト可能セクションです。これはサーバーから変数を渡すために使用し、必要かつ余分なフィールドを定義できます。この機能は、[カレンダー] タイプのスケジュールページでのみ使用されます。 |
| クライアントスクリプト | 文字列 | クライアントスクリプトは、スケジュールページの表示オプションを設定できるスクリプト作成可能なセクションです。API はスケジュールページのビュータイプによって異なり、説明は次のとおりです。 |
| サーバー AJAX プロセッサー | 文字列 | 注: サーバー AJAX プロセッサーは、カレンダータイプのスケジュールページに特有のもので、表示するスケジュールアイテムとスパンのセットを返すために使用されます。この機能は、[カレンダー] タイプのスケジュールページでのみ使用されます。 |
タイムラインスケジュールページ
タイムラインスケジュールページは、時間ベースのポイントとスパンを「タイムライン」のような形式で表示するための構成情報を含む特定のレコードです。
タイムラインスケジュールページは、AbstractTimelineSchedulePage から拡張されたスクリプトインクルードを参照して、さまざまなイベントや条件に基づいてタイムラインを動的に変更します。スケジュールページとタイムライン生成用のスクリプトインクルードはどちらも、高度なカスタマイズが可能です。対応するアプリケーションプログラミングインターフェイス (API) を以下に示します。
スケジュールページを使用してタイムラインを生成するアプリケーション
- プロジェクト管理
- メンテナンススケジュール
- グループオンコールローテーション
- Field Service Management
タイムラインスケジュールページの例
次の例は、上記の API の大部分を利用して、対応するスクリプトインクルードでタイムラインスケジュールページを作成する方法を示しています。
この例では、プロジェクトサポートマネージャーのインシデントサマリータイムラインを作成して、すべての新しいインシデントをビジュアル化します。すべての新しいインシデントは、ポイントアイコンの違いでインシデントの優先度が区別される、単一のポイントとして表示されます。さらに、すべてのクローズ済みインシデントは、クローズされる前のインシデントの期間を示す別のグループとしてタイムラインに表示する必要があります。プロジェクトマネージャーは、解決済みの新しいアイテムをフォームリストを使用せずに簡単にクローズできる必要があるため、垂直移動イベントを処理して、新しいインシデントをクローズ済みインシデントグループまたはその中のアイテムにドラッグできるようにします。
スケジュールページ
- 名前:ハードウェアインシデント
- スケジュールタイプ:incident_timeline
- ビュータイプ:タイムライン
- クライアントスクリプト:
// Set our page configuration
glideTimeline.setReadOnly(false);
glideTimeline.showLeftPane(true);
glideTimeline.showLeftPaneAsTree(true);
glideTimeline.showTimelineText(true);
glideTimeline.showDependencyLines(false);
glideTimeline.groupByParent(true);
glideTimeline.setDefaultPointIconClass('milestone');
// We will define what items to display and provide a custom event handler for moving new items to the closed state
glideTimeline.registerEvent('getItems', 'IncidentTimelineScriptInclude');
glideTimeline.registerEvent('elementMoveY', 'IncidentTimelineScriptInclude');スクリプトインクルード
- 名前: IncidentTimelineScriptInclude
- アクティブ:オン
- クライアントコール可能:オン
- Script :
// Class Imports
var IncidentTimelineScriptInclude = Class.create();
IncidentTimelineScriptInclude.prototype = Object.extendsObject(AbstractTimelineSchedulePage, {
/////////////////////// // GET_ITEMS ///////////////////////////////////////
getItems:function() {
// Specify the page title
this.setPageTitle('My Custom Incident Summary Timeline');
var groupNew = new GlideTimelineItem('new');
groupNew.setLeftLabelText('New Incidents');
groupNew.setImage('../images/icons/all.gifx');
groupNew.setTextBold(true);
this.add(groupNew);
var groupClosed = new GlideTimelineItem('closed');
groupClosed.setLeftLabelText('Closed Incidents');
groupClosed.setImage('../images/icons/all.gifx');
groupClosed.setTextBold(true);
groupClosed.setIsDroppable(true);
// This allows us to drag an open incident onto the closed group row.
this.add(groupClosed);
// Get all the incidents and let's add only the new/closed ones appropriately
var now_GR = new GlideRecord('incident');
gr.query();
while(gr.next()) {
// Only loop through new/closed incidents
if(gr.incident_state != '1' && gr.incident_state != '7') continue;
// Ok, we have a new/closed incident. Create the item and the span first.
var item = new GlideTimelineItem(gr.getTableName(), gr.sys_id);
var span = item.createTimelineSpan(gr.getTableName(), gr.sys_id);
// Specific properties for a new incident
if(gr.incident_state == '1') { // New
item.setParent(groupNew.getSysId());
item.setImage('../images/icons/open.gifx');
span.setTimeSpan(gr.getElement('opened_at').getGlideObject().getNumericValue(),
gr.getElement('opened_at').getGlideObject().getNumericValue());
// We'll show different colors based upon the priorities only for new incidents
switch(gr.getElement('priority').toString()) {
case '1': span.setPointIconClass('red_circle'); break;
case '2': span.setPointIconClass('red_square'); break;
case '3': span.setPointIconClass('blue_circle'); break;
case '4': span.setPointIconClass('blue_square'); break;
case '5': span.setPointIconClass('sepia_circle'); break;
default: // Otherwise, the default point icon class will be used (Milestone)
}
}
// Specific properties for a closed incident
else if(gr.incident_state == '7') {
item.setParent(groupClosed.getSysId());
item.setImage('../images/icons/closed.gifx');
span.setTimeSpan(gr.getElement('opened_at').getGlideObject().getNumericValue(),
gr.getElement('closed_at').getGlideObject().getNumericValue()); }
// Common item properties
item.setLeftLabelText(gr.short_description);
// Common span properties
span.setSpanText(gr.short_description);
span.setTooltip('<strong>' + GlideStringUtil.escapeHTML(gr.short_description) + '</strong><br>' + gr.number);
span.setAllowXMove(false);
span.setAllowYMove(gr.canWrite() ? true:false);
span.setAllowYMovePredecessor(false);
span.setAllowXDragLeft(false);
span.setAllowXDragRight(false);
// Now we add the actual item
this.add(item);
} } ,
//////////////////////// // ELEMENT_MOVE_Y /////////////////////////////////////////////////////////////
/**
* This is one of the AbstractTimelineSchedulePage event handler methods that corresponds to a vertical
* move. The arguments for this function are defined in the API section of the event handler methods.
*/
elementMoveY: function(spanId, itemId, newItemId) {
// Get information about the current incident
var now_GR = new GlideRecord('incident');
gr.addQuery('sys_id', spanId);
gr.query();
if(!gr.next())
return this.setStatusError('Error', 'Unable to lookup the current incident.');
// Only allow the new incidents to have their state adjusted.
if(gr.incident_state != '1')
return this.setStatusError('Error','Only new incidents can have their state adjusted.');
// Get information about the dropped GlideTimelineItem. If it was dropped in an item on the "New Incidents"
// group let's do nothing. If it was dropped in the "Closed Incidents" then let's adjust the state automatically.
var grDropped = new GlideRecord('incident');
grDropped.addQuery('sys_id', newItemId );
grDropped.query();
if(!grDropped.next() || grDropped.incident_state == '7') {
// This means the dropped item was either the 'Closed Incidents' group (which has no record or sys_id) or an
// existing incident that is closed. The 'New Incidents' also has no sys_id; however, the default behavior for
// items without a sysId is to be non-droppable. This is why we explicitly denoted the 'Closed Incidents' to
// be marked as "droppable".
// Return a dialog prompt
this.setStatusPrompt('Confirm', 'Are you sure you want to close: ' +
'<div style="margin:10px 0 10px 14px;padding:4px;background-color:#EBEBEB;"><strong>' +
GlideStringUtil.escapeHTML(gr.short_description) +
'</strong><br/><div class="font_smaller">' + now_GR. number + '</div></div>',
'this._elementMoveYHandler_DoClose', // This function is for when the OK button is clicked.
'this._elementMoveYHandler_DoNothing', // This function is for when the Cancel button is clicked.
'this._elementMoveYHandler_DoNothing'); // This function is for when the Close button is clicked.
} } ,
_elementMoveYHandler_DoClose: function(spanId, itemId, newItemId) {
// Notice that this function takes the same function arguments as the original function for which it
// is a custom event handler for.
// Update the database record from 'New' to 'Closed'.
var now_GR = new GlideRecord('incident');
gr.addQuery('sys_id', spanId);
gr.query();
gr.next();
gr.setValue('incident_state', '7');
gr.update();
// This will re-render the timeline showing the updated item in the closed group.
this.setDoReRenderTimeline(true);
// Let's show a success message
this.setStatusSuccess('Success', '<strong>' + gr.short_description + '</strong> was successfully closed.'); } ,
// Since the user clicked cancel or close we simply do nothing.
_elementMoveYHandler_DoNothing: function(spanId, itemId, newItemId) { }
});スクリーンショット/結果
- 移動先:
http://[YOURINSTANCE]:8080/show_schedule_page.do?sysparm_page_schedule_type=incident_timeline
太字のテキストは、スケジュールページの [スケジュールタイプ] フィールドの値です。
- ページには、スケジュールページで指定されたタイムラインと作成されたスクリプトインクルードが表示されます。このページへのリンクを作成し、必要に応じてモジュールまたは UI アクションとして配置できます。
図 : 2. タイムラインのインシデントのプレビューの例 - クローズ済みインシデントをいずれかの場所に移動しようとすると、予想されるエラーメッセージが表示されます。
図 : 3. タイムラインの移動エラーの例 - インシデントの移動:次の確認ボックスに「さらにメモリが必要 (I need more memory)」と表示されます 。
図 : 4. タイムラインのクローズ確認の例 - [キャンセル] ボタンをクリックすると、オーバーレイが閉じられます。[OK] ボタンをクリックすると、実際にはレコードの incident_state が更新され、次の成功ボックスが表示されます。
図 : 5. タイムラインのクローズ成功の例 - [OK] をクリックすると、インシデントは [クローズ済みインシデント] グループにリストされるようになります。
図 : 6. タイムラインのインシデント更新の例