【Garoon JavaScript API】ワークフローの印影カスタマイズ

目次

はじめに

クラウド版 Garoon、パッケージ版 Garoon(4.6.0 以上)にはワークフロー画面にイベントが用意されています。
今回はこのイベントを使って「ワークフローの承認欄に印影」を表示するカスタマイズを行います。

注意事項

サンプルでは一部の機能で Garoon がサポートしない DOM 操作をしています。Garoon のアップデートにより、機能を利用できなくなる可能性があります。

完成イメージ

ワークフローの詳細画面と承認後画面にて、印影が表示されます。

印影データの準備

ワークフローに表示させる印影データ(画像ファイル)を Garoon のファイル管理にアップロードしてください。

そして、印影データを保存したフォルダーの ID(URL 部分の hid 部分)をメモしておいてください。

例: https://(サブドメイン)cybozu.com/g/cabinet/index.csp?hid=3
→ この場合フォルダーの ID は「3」となります。

印影のファイル名は対応するユーザーの「ログイン名」と合わせてください。

JavaScript カスタマイズ設定方法

印影を表示させたいワークフローに以下の JavaScript ファイルを適用させます。

手順

  1. 次のサンプルコードを任意のファイル名で保存します。拡張子は「.js」にしてください。
    13 行目の hid をご自身のフォルダーID に変更してください。

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    
    /*
    * Sample program of Garoon JavaScript API
    * Copyright (c) 2018 Cybozu
    *
    * Licensed under the MIT License
    * https://opensource.org/license/mit/
    */
    
    (function($) {
      'use strict';
    
      const CYB = {
        hid: '7', // ファイル管理のフォルダ ID
        sealrotate: '0' // 印影の画像の回転角度
      };
    
      // xml のヘッダー部分を作成する
      const makeXMLHeader = function(action) {
        // ファイル管理の xmlns の url
        const xmlns = 'cabinet_services="http://wsdl.cybozu.co.jp/cabinet/2008"';
    
        return '<?xml version="1.0" encoding="UTF-8"?>' +
                  '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" ' +
                        'xmlns:xsd="http://www.w3.org/2001/XMLSchema" ' +
    
                        'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' +
                        'xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" ' +
                        'xmlns:' + xmlns + '>' +
                  '<SOAP-ENV:Header>' +
                        '<Action SOAP-ENV:mustUnderstand="1" ' +
                            'xmlns="http://schemas.xmlsoap.org/ws/2003/03/addressing">' + action + '</Action>' +
                        '<Timestamp SOAP-ENV:mustUnderstand="1" Id="id" ' +
                            'xmlns="http://schemas.xmlsoap.org/ws/2002/07/utility">' +
                            '<Created>2037-08-12T14:45:00Z</Created>' +
                            '<Expires>2037-08-12T14:45:00Z</Expires>' +
                        '</Timestamp>' +
                        '<Locale>jp</Locale>' +
                  '</SOAP-ENV:Header>';
      };
    
      // 印影を出力する
      const outputSeals = function(files) {
        const objsealurl = {};
    
        // ユーザーと印影ファイルの url の情報を配列に保持する
        for (let i = 0; i < files.length; i++) {
          // ファイルの id を取得する
          const id = $(files[i]).attr('id');
    
          // ファイル名を取得する
          const filename = $(files[i]).find('name').first().text();
    
          // ファイル名から最後のピリオド以後を削除し、usercode を取得する
          const arysplit = filename.split('.');
          arysplit.pop();
          const usercode = arysplit.join('.');
    
          // CYB.sealurl 配列に usercode と印影の url を格納する
          objsealurl[usercode] =
              '/g/cabinet/download.csp/-/' + filename + '?hid=' + CYB.hid + '&fid=' + id;
        }
    
        // 「進行状況」のテーブルの行数を取得する
        const tblrows = $('.list_column tr').length;
    
        // テーブルの行数文ループする。ただし先頭の行はスキップする。
        for (let j = 1; j < tblrows; j++) {
          // 「結果の欄」の「承認」の部分を探す
          const $result = $('.list_column tr:eq(' + j + ') td ' +
                    '.wfRouteHistoryResultMarkOkLast-grn,' +
                    '.list_column tr:eq(' + j + ') td ' +
                    '.wfRouteHistoryResultMark-grn');
    
          // 「承認」が存在する場合
          if ($result.length > 0 &&
                    ($result.text() === '承認' || $result.text() === '確認')) {
    
            // 承認者の usercode を名前のリンクから取得する
            const authcode = $('.list_column tr:eq(' + j + ') ' +
                        '.wfRouteHistoryUserComment-grn a').attr('href').split('users/')[1];
    
            // ユーザーの印影の情報があれば、印影の画像に書き換える
            if (objsealurl[authcode]) {
              $result.parent().html('<img src="' + objsealurl[authcode] + '" ' +
                            'width="56" height="56" class="imgseal"></img>');
            }
          }
    
          $('.imgseal').css('transform', 'rotate(' + CYB.sealrotate + 'deg)');
          $('.imgseal').css('margin', '10px 10px 10px 10px');
    
        }
    
      };
    
      const runCabinetGetFileInfo = function(callback) {
        const xmlhttp = new XMLHttpRequest(),
          url = '/g/cbpapi/cabinet/api.csp';
    
        const xml = makeXMLHeader('CabinetGetFileInfo') +
                      '<SOAP-ENV:Body>' +
                        '<CabinetGetFileInfo>' +
                          '<parameters hid="' + CYB.hid + '">' +
                          '</parameters>' +
                        '</CabinetGetFileInfo>' +
                      '</SOAP-ENV:Body>' +
                      '</SOAP-ENV:Envelope>';
    
        xmlhttp.open('post', url, true);
        xmlhttp.setRequestHeader('Content-Type', 'text/xml; charset=UTF-8');
        xmlhttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
    
        xmlhttp.onload = function(e) {
          if (xmlhttp.readyState === 4) {
            if (xmlhttp) {
              const respText = xmlhttp.responseText;
              const resp = $.parseXML(respText);
              callback(null, $(resp).find('file'));
            } else {
              callback(xmlhttp.statusText);
            }
          }
        };
    
        xmlhttp.onerror = function(e) {
          callback(xmlhttp.statusText);
        };
    
        xmlhttp.send(xml);
      };
    
      // Garoonワークフロー 詳細表示イベント/承認画面表示イベント
      garoon.events.on([
        'workflow.request.detail.show',
        'workflow.request.approve.show'
      ], (event) => {
        runCabinetGetFileInfo((err, filename) => {
          if (err) {
            alert(err);
            return;
          }
          outputSeals(filename);
        });
        return event;
      });
    })(jQuery.noConflict(true));
  2. [Garoon システム管理 > 各アプリケーションの管理 > ワークフロー > 申請フォームの一覧 > カスタマイズを適用したい申請フォーム]の画面を表示します。
    続いて「JavaScript / CSS によるカスタマイズ」をクリックします。

  3. 必要なライブラリ(jQuery)と保存した JavaScript ファイルを適用します。
    必ず「カスタマイズ」を「適用する」に変更してください。

    • jQuery:https://js.cybozu.com/jquery/3.4.1/jquery.min.js

プログラムの解説

イベント

JavaScripit が動くイベントは、ワークフローの「詳細画面を表示した時」と「承認後画面を表示した時」となります。

133
134
135
136
  garoon.events.on([
    'workflow.request.detail.show',
    'workflow.request.approve.show'
  ], function(event) {

印影データの取得

ファイル管理に保存している印影データを取得するために、Garoon SOAP API を利用しています。

取得した画像データからファイル名部分(=ログイン名)を取得します。

50
51
52
53
54
55
56
57
58
59
60
// ファイル名を取得する
filename = $(files[i]).find('name').first().text();

// ファイル名から最後のピリオド以後を削除し、usercode を取得する
arysplit = filename.split('.');
arysplit.pop();
usercode = arysplit.join('.');

// CYB.sealurl 配列に usercode と印影の url を格納する
objsealurl[usercode] =
        '/g/cabinet/download.csp/-/' + filename + '?hid=' + CYB.hid + '&fid=' + id;

「結果」部分の取得

進行状況の「結果」部分を取得します。こちらは DOM 操作となります。

69
70
71
72
$result = $('.list_column tr:eq(' + j + ') td ' +
              '.wfRouteHistoryResultMarkOkLast-grn,' +
              '.list_column tr:eq(' + j + ') td ' +
              '.wfRouteHistoryResultMark-grn');

印影データの表示

承認者のログイン名とファイル名を比較して、同じものがあればその印影データを「結果」部分に表示させます。こちらは DOM 操作となります。

78
79
80
81
82
83
84
85
86
// 承認者の usercode を名前のリンクから取得する
authcode = $('.list_column tr:eq(' + j + ') ' +
                  '.wfRouteHistoryUserComment-grn a').attr('href').split('users/')[1];

// ユーザーの印影の情報があれば、印影の画像に書き換える
if (objsealurl[authcode]) {
  $result.parent().html('<img src="' + objsealurl[authcode] + '" ' +
                      'width="56" height="56" class="imgseal"></img>');
}

画像に角度をつける機能

14 行目の数値を変更することで、角度を指定して画像を回転させることができます。

数値をプラスで設定して少し右向きに角度をつけたり、数値をマイナスで設定して左向きに角度をつけることも可能です。

数値を「10」(プラス 10)とした場合

数値を「-20」(マイナス 20)とした場合

おわりに

ワークフローに「印影」をつけたいという声はかなりあると思います。

Garoon でもカスタマイズをすることで対応が可能なので、ぜひ提案の 1 つに入れてみてください。

information

この Tips は、2018 年 12 月版 Garoon で動作を確認しています。