【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で動作を確認しています。