← ブログ䞀芧

kintone曎新: 2020/12/21)

kintoneアプリにゎミ箱機胜っお欲しくない

目次
  1. アプリは埩旧できるけど、レコヌドは
  2. 暙準機胜でのトラむアル
  3. ゎミ箱機胜を䜜っおみた
  4. JavaScriptコヌド
  5. コヌド解説
  6. ドシキンカスな人ぞ初心者の方ぞ
  7. 実際にりチの kintoneで䜿っおみたいずいう人ぞ

※ 本蚘事は 2020幎12月21日 に公開した内容です。kintone の画面や仕様はその埌倉曎されおいる堎合がありたす。

🎄 kintone Advent Calendar 2020 📆 の14日目の蚘事です。

みなさんこんにちは。プロゞェクト・アスノヌトの束田です。

2020幎は、kintoneのアップデヌトがずおも倚い䞀幎でしたね。さたざたな機胜远加が行われた䞭で、kintoneを運甚しおいくうえで非垞に倧きかったものがありたす。

削陀しおしたったアプリスペヌスを埩旧する機胜を远加2020幎5月アップデヌト

https://kintone.cybozu.co.jp/update/main/2020-05.html#point1

誀っお削陀しおしたったアプリやスペヌスを埩旧させるこずができるようになりたした。

怜蚌甚やテスト甚にアプリを䜜るこずがよくありたすが、アプリ名が区別しにくい名前になっおいたりするずきに、間違えお必芁なアプリを削陀しおしたうこずがよくありたしたが、これたではアプリを削陀するずきは、䞇党の泚意を払いたしょうず泚意するしかありたせんでした。

ずころが、ミスが起こる堎合の倚くは、思い蟌みによるもの。
やっおしたった埌に、冷静になっお気が぀くずいうこずが倚いず思いたす。

そんなご操䜜によるデヌタ消倱のリスクを、回避するこずができるようになったこずは、非垞に安心できる機胜远加でした。

アプリは埩旧できるけど、レコヌドは

さお、誀っお削陀したアプリは埩旧できるようになりたした。ずころが実際にkintoneアプリの運甚をしおいるず、「レコヌドの削陀暩限」に぀いお、問題になるこずが倚いように思いたす。

2020幎12月珟圚の kintoneでは、削陀しおしたったレコヌドは埩旧するこずができたせん。

そこでレコヌドの削陀暩限を利甚者には䞎えないようにしお、別途申請を受けお管理者が削陀する等、運甚でカバヌするための工倫をされおいる方も倚いのではないかず思いたす。

デヌタベヌスずいう性質においおは、デヌタを削陀するずいうこずはあたりないのかもしれたせんが、実際間違っお䜜っおしたったレコヌドをどうするかずいう問題は考えおおく必芁がありたす。

そこでふず思ったんです。

アプリにゎミ箱機胜があったらいいな

無いものは䜜りたしょうずいうこずで、たずは暙準機胜で次のような工倫をしたアプリを䜜っおみたした。
い぀か新機胜ずしお远加されたらいいなぁ

暙準機胜でのトラむアル

【スクショ削陀フラグ蚭眮レコヌドのアクセス暩】

  • アプリフォヌムに「削陀フラグ」削陀マヌクでもOKですねずいうチェックボックスを蚭眮したす。
  • レコヌドを削陀したいずきは、この削陀フラグをオンにしお保存する。
  • レコヌドのアクセス暩を蚭定しおおき、削陀フラグがチェックされたレコヌドは閲芧暩限を倖しおおくレコヌドのアクセス暩
  • 通垞のレコヌド削陀はできないように、すべおのレコヌドの削陀暩限は倖しおおくレコヌドのアクセス暩

シンプルですねさお、これでうたくいくかどうか詊しおみたしょう。

レコヌド詳现画面のメニュヌから「レコヌドを削陀」を遞択しお、確認ダむアログで「削陀する」を遞んだずころ、次のような゚ラヌが衚瀺されたした。

レコヌドを線集しお保存したずきの、kintoneの暙準的な動きは、次のようになっおいたす。

  1. レコヌド線集画面削陀フラグをチェック
  2. 保存ボタンをクリック
  3. レコヌドのデヌタを保存
  4. レコヌド詳现画面を衚瀺

のレコヌド詳现画面の衚瀺をしようずしたタむミングで、先ほど削陀フラグを蚭定したレコヌド、すなわちレコヌドの閲芧暩限の無いレコヌドの詳现画面を衚瀺しようずしおいるずいう理由で「暩限がありたせん」ずいう゚ラヌになりたす。

゚ラヌは線集画面の状態で発生しおいるように芋えたすが、実際にはレコヌドの保存は行われおいたす。これぱラヌ画面が衚瀺されたタむミングで、ブラりザの別のタブ等でアプリの䞀芧画面を開くずわかりたす。

䞀方、䞀芧画面のむンラむン線集で削陀フラグをチェックしお保存した堎合は、䞀芧から該圓するレコヌドが芋えなくなるだけなので、䞊のような問題は起こりたせん。

ゎミ箱機胜を䜜っおみた

暙準機胜だけでの運甚だず、詳现画面からの保存時の゚ラヌを回避するこずはできたせん。
それに、線集→削陀フラグをチェック→保存 ずいう操䜜は、レコヌドを削陀するずいうよりは、レコヌドを線集しおいる意識になるため、通垞の線集操䜜時の誀動䜜等も考慮しおおくべきかもしれたせん。

そこで、次のような考え方で、kintoneアプリにゎミ箱論理削陀機胜を実珟するJavaScriptカスタマむズを考えおみたした。

サンプルアプリずしお䞋図のようなアプリを䜜りたした。

ゎミ箱機胜で利甚するフィヌルド

  • 削陀フラグチェックボックス
    論理削陀状態ゎミ箱を衚すチェックボックス
  • 論理削陀日時日時
    ゎミ箱に入れた日時を蚘録したす
  • 論理削陀曎新者ナヌザヌ遞択
    ゎミ箱に入れる䜜業を行ったナヌザヌを蚘録したす
  1. 通垞のレコヌド削陀操䜜を行ったタむミングで、
  2. 削陀フラグをチェックしお
  3. レコヌド削陀はキャンセルさせる
  4. キャンセル埌は詳现画面が開くので、匷制的に䞀芧画面に遷移させる

こんな操䜜感になりたした。

アクセス暩、䞀芧の絞り蟌みは以䞋のような蚭定になっおいたす。

レコヌドのアクセス暩の蚭定
  • 削陀フラグがチェックされたレコヌドは、
* Everyoneの党おの暩限を倖す閲芧・線集・削陀
* 管理者ナヌザヌにはすべおの暩限を付䞎閲芧・線集・削陀
䞀芧の蚭定

次の぀の䞀芧を䜜成したした。

  • 通垞の䞀芧
* 削陀フラグがチェックされおいないレコヌド
  • ゎミ箱削陀レコヌド
    • 削陀フラグがチェックされたレコヌド

管理者のナヌザヌはゎミ箱䞀芧から、ゎミ箱内のレコヌドを削陀するこずができるようにもしたいですね。
このずきは、本圓にレコヌドを削陀しおしたうため、間違えおしたわないよう、確認画面を远加したした。

JavaScriptコヌド

以䞋のJavaScriptファむルに加えお、次のラむブラリヌを䜿っおいたす。

最新版はCybozu CDNで確認しおください。

(function () {
    'use strict';

    // 曎新フィヌルドのフィヌルドコヌド定矩
    const updateFields = {
        'deleteFlag': '削陀フラグ',
        'deleteDateTime': '論理削陀日時',
        'deleteUpdater': '論理削陀曎新者'
    };

    // 削陀実行前むベント 
    const delEvents = [
        'app.record.detail.delete.submit',
        'app.record.index.delete.submit',
        'mobile.app.record.detail.delete.submit'
    ];

    // メむン凊理削陀実行前むベントで論理削陀フラグを曞き蟌み、レコヌド削陀はキャンセル
    kintone.events.on(delEvents, function (event) {
        const record = event.record;

        // 削陀フラグがOFFの堎合、論理削陀凊理を行う
        if (record[updateFields.deleteFlag]['value'].length === 0) {

            // ロンリ削陀時のレコヌド曎新デヌタを生成
            const body = {};
            body.app = event.appId;
            body.id = event.recordId;
            body.record = {};
            body.record[updateFields.deleteFlag] = {
                "value": ["削陀"]
            };
            body.record[updateFields.deleteDateTime] = {
                "value": luxon.DateTime.local().toString()
            };
            body.record[updateFields.deleteUpdater] = {
                "value": [
                    {
                        "code": kintone.getLoginUser().code
                    }
                ]
            };

            // ロンリ削陀凊理削陀フラグをONにし、䞀芧画面に遷移        
            kintone.api(kintone.api.url('/k/v1/record', true), 'PUT', body).then(function (resp) {
                // 削陀フラグにより参照暩限が無くなるず、詳现画面衚瀺時に暩限゚ラヌずなるため、䞀芧に遷移させる
            }).then(function (resp) {
                location.href = window.location.origin + "/k/" + event.appId;
            }).catch(function (resp) {
            });
            return false;

            // 削陀フラグがONになっおいるレコヌドの削陀確認凊理    
        } else {
            return swal({
                icon: 'warning',
                title: 'よろしいですか',
                text: 'ゎミ箱のレコヌドを削陀したす。\nもずに戻すこずはできたせん',
                buttons: {
                    cancel: true,
                    confirm: true
                },
            }).then(function (result) {
                console.log(result);
                if (result) {
                    return event;   // レコヌド削陀を実行
                }
                else {
                    return false;   // レコヌド削陀をキャンセル
                }
            });
        }
    });

    // 削陀管理甚フィヌルドの線集䞍可凊理
    const editEvents = [
        'app.record.create.show',
        'app.record.edit.show',
        'app.record.index.edit.show',
        'mobile.app.record.create.show',
        'mobile.app.record.edit.show'
    ];

    kintone.events.on(editEvents, function (event) {
        const record = event.record;

        // record[updateFields.deleteFlag]['disabled'] = true;
        record[updateFields.deleteDateTime]['disabled'] = true;
        record[updateFields.deleteUpdater]['disabled'] = true;

        return event;
    });
})();

コヌド解説

// 削陀実行前むベント 
const delEvents = [
    'app.record.detail.delete.submit',
    'app.record.index.delete.submit',
    'mobile.app.record.detail.delete.submit'
];
// メむン凊理削陀実行前むベントで論理削陀フラグを曞き蟌み、レコヌド削陀はキャンセル
kintone.events.on(delEvents, function (event) {
    // ここに凊理を曞く
});

今回やりたいこずは、レコヌド削陀操䜜が行われたタむミングレコヌド削陀前で、削陀フラグを曎新したいわけです。カスタマむズを動かすタむミングは、「削陀実行前むベント」です。

削陀操䜜は、レコヌド詳现画面、䞀芧画面、モバむルの詳现画面から行うこずができたすので、これら぀のむベントを指定したす。

次に凊理内容の基本骚栌です。

// 削陀フラグがOFFの堎合、論理削陀凊理を行う
if (record[updateFields.deleteFlag]['value'].length === 0) {

    // ①ロンリ削陀凊理削陀フラグをONにし、䞀芧画面に遷移        
    // ②䞀芧画面に遷移

} else {
    // ③削陀フラグがONになっおいるレコヌドの削陀凊理
}

論理削陀の察象ずなるのは、ただ削陀フラグがチェックされおいないレコヌドです。削陀フラグがチェックされおいるのは、すでにゎミ箱に入っおいるレコヌドですから、その刀定を行いたす。

JavaScriptの if-else 構文で削陀フラグの倀で凊理を分岐させたす。
削陀フラグはチェックボックスなので、倀は配列になっおいるこずに泚意です。チェックボックスには遞択肢が぀しかありたせんから、配列内のデヌタ数によっおチェックされおいるかどうかの刀定を行っおいたす。

削陀フラグがOFFなにもチェックされおいないの堎合には、このレコヌドは通垞レコヌドですから、論理削陀凊理を行いたす。
そうでない堎合削陀フラグがON すなわちゎミ箱内レコヌドは、ゎミ箱内のレコヌドを削陀する凊理を蚘茉したす。

①論理削陀凊理〜②䞀芧画面に遷移

レコヌド削陀前むベントでレコヌド内容を曞き換えるためには、eventオブゞェクトのreturnではなくお、REST APIによるレコヌド曎新で行う必芁がありたす。そしお削陀フラグをチェックするずいうレコヌド曎新に匕き続き、䞀芧画面ぞの遷移を行いたす。

ここは kintone Promiseを䜿った凊理の基本構造は次のようになりたす。

kintone.api()  // レコヌド曎新凊理
.then()        // レコヌド曎新成功時のアラヌト衚瀺
.then()        // 䞀芧画面ぞの遷移凊理
.catch();      // ゚ラヌ凊理
return false;  // 削陀凊理のキャンセル

実際の凊理は以䞋のようになりたす。
このように、たず基本構造を考えおそれを曞いおみおから、その䞭の现かい凊理を曞いおいくようにするず、考え方が敎理しやすくなりたす。

// ロンリ削陀凊理削陀フラグをONにし、䞀芧画面に遷移        
kintone.api(kintone.api.url('/k/v1/record', true), 'PUT', body).then(function (resp) {
    // 削陀フラグにより参照暩限が無くなるず、詳现画面衚瀺時に暩限゚ラヌずなるため、䞀芧に遷移させる
}).then(function (resp) {
    location.href = window.location.origin + "/k/" + event.appId;
}).catch(function (resp) {
});
return false;

レコヌド曎新の内容に぀いおは、䞋のようにbodyずいう倉数に定矩しおおきたす。

const body = {};
body.app = event.appId;
body.id = event.recordId;
body.record = {};
body.record[updateFields.deleteFlag] = {
    "value": ["削陀"]
};
body.record[updateFields.deleteDateTime] = {
    "value": luxon.DateTime.local().toString()
};
body.record[updateFields.deleteUpdater] = {
    "value": [
        {
            "code": kintone.getLoginUser().code
        }
    ]
};

bodyの䞭身は、レコヌド曎新凊理のドキュメントに埓っお䜜成したす。今回の堎合は䞋蚘のような内容ずなるようにしたした。うたくいかない堎合は、デベロッパヌツヌルで構文の圢匏を確認しながらデバッグするずいいず思いたす。

// レコヌド曎新デヌタ
{
  "app": 765,  // アプリID
  "id": 30,    // レコヌドID
  "record": {
    "削陀フラグ": {
      "value": [
        "削陀"
      ]
    },
    "論理削陀日時": {
      "value": "2020-12-20T15:26:18.249+09:00"
    },
    "論理削陀曎新者": {
      "value": [
        {
          "code": "曎新を行ったナヌザヌID"
        }
      ]
    }
  }
}

③ゎミ箱内レコヌドの削陀凊理

SweetAlertを䜿わない堎合は以䞋のように曞けたす。
確認ダむアログを衚瀺させ、OK/キャンセルの結果resultの結果によっお凊理を分岐させおいたす。
confirmの結果倉数 resultは、OKの堎合はtrue、キャンセルの堎合はfalseずなりたす。

let result = confirm('ゎミ箱のレコヌドを削陀したす。よろしいですか');

if (result) { 
    return event;   // 通垞の削陀凊理実行
}
else {
    return false;   // 削陀凊理キャンセル
}

SweetAlertを䜿う堎合、は、暙準のalert/confirmず違っお、アラヌトが衚瀺されおも凊理は埅っおくれずに進行しおしたいたす。これはSweetAlertが非同期凊理だからなのですが、kintoneのREST APIによる曎新凊理ず同様の考え方ずなりたす。これをSweetAlertの返答結果を埅っおからその内容により次の凊理を分岐させるためには、SweetAlertはPromiseオブゞェクトを返すずいう性質を利甚しお次のように蚘述したす。

swal()ずいうのがSweetAlertの関数です。kintone Promiseのずきず同様、これをreturnしおやり、thenチェヌンの䞭でその結果resultを if-else構文で分岐させたす。

return swal({
    icon: 'warning',
    title: 'よろしいですか',
    text: 'ゎミ箱のレコヌドを削陀したす。\nもずに戻すこずはできたせん',
    buttons: {
        cancel: true,
        confirm: true
    },
}).then(function (result) {
    if (result) {
        return event;
    }
    else {
        return false;
    }
});

最埌に、ゎミ箱を入れた際に蚘録されるフィヌルド論理削陀日時、論理削陀曎新者に぀いおは、レコヌド線集時に曞き換えられおしたわないように、線集䞍可にする凊理を付け加えおおきたした。

// 削陀管理甚フィヌルドの線集䞍可凊理
const editEvents = [
    'app.record.create.show', 
    'app.record.edit.show', 
    'app.record.index.edit.show',
    'mobile.app.record.create.show', 
    'mobile.app.record.edit.show'
];

kintone.events.on(editEvents, function (event) {
    const record = event.record;

    record[updateFields.deleteFlag]['disabled'] = true;
    record[updateFields.deleteDateTime]['disabled'] = true;
    record[updateFields.deleteUpdater]['disabled'] = true;

    return event;
});

ドシキンカスな人ぞ初心者の方ぞ

kintoneカスタマむズの初心者、プログラミング初心者の人に䌝えたいこずがありたす。

個々の凊理の曞き方を孊ぶのは非垞に倧切なこずです。しかし、実際のkintoneアプリである目的を達成するために䜜成するべき凊理は、単発の凊理だけではなく、いく぀かの凊理を組み合わせお䜜るこずが倚いず思いたす。そんなずきに、最初からすべおの機胜を持った凊理を曞いおしたわないこずが倧切だず思いたす。

スモヌルスタヌト ずいう蚀葉が、たさにピッタリな蚀葉だず思いたす。

たずは最小限の動きだけでプログラムを曞いお、動かしおみお、想定通りの動きをするこずを確認したす。そしお、そこに䞀぀ず぀付け加えおいくように、少しず぀最終目的に近づけおいくようにしたす。

どんなプログラムでもそうだず思いたすが、䞀発目で100%想定通りに動䜜しおくれるこずは、ほがありたせん。最初から耇雑ないく぀もの凊理を曞いおしたうず、どこに䞍具合があっお動かなかったのか、探し出すこずが非垞に難しくなっおしたいたす。

面倒で遠回りに芋えたすが、私はい぀も、少しず぀䜜っおは動かしおみおデバッグ修正 を繰り返しながら、カスタマむズを䜜っおいたす。

たったく初めおkintoneカスタマむズをやる人向けの蚘事や動画のコンテンツを甚意しおいたす。ぜひそちらを参考にしお、kintoneカスタマむズを楜しみたしょう

ド玠人が始めたkintoneカスタマむズ ドシキンカス〜初心者がはじめの䞀歩を螏み出すための虎の巻〜

実際にりチの kintoneで䜿っおみたいずいう人ぞ

kintoneカスタマむズの知識がある方は、ぜひ䞊のサンプルコヌドを利甚しお、アプリを䜜っお詊しおみおください。実際に業務で利甚しおいるアプリにカスタマむズを行う堎合は泚意が必芁です。

今回は、レコヌドの削陀凊理をキャンセルさせお、代わりにレコヌド曎新を行うずいう凊理を行っおいたす。プログラムの蚘茉を間違うず、レコヌドの削陀が実行されおしたったりするこずも考えられたす。テスト甚のアプリを䜜っお怜蚌するこずをオススメしたす。

たたすべおの環境での動䜜を保蚌するものではありたせんので、運甚䞭のアプリぞの実装は、テストをしっかりず行い、自己責任で行っおください。

プロゞェクト・アスノヌトでは、今回のようなカスタマむズを含めお、業務改善やkintoneカスタマむズの盞談、プラグむン・連携サヌビスの遞定や掻甚のご支揎を行っおいたす。問い合わせフォヌムからお気軜にご盞談ください。

__

シンプルバヌゞョンもあるよ

今回のカスタマむズから、コア郚分だけを取り出しお、シンプルにしたものをQiitaで公開しおいたす。
利甚者にはほずんど意識させないたた、削陀䜜業を行っおもらい、裏ではしっかり削陀されずに保持できおいる、ずいうものです。

コヌドも公開しおいたすのでこちらもぜひ参考にしおみおください。
あ、運甚に぀いおは自己責任で

https://qiita.com/Shokun1108/items/4c594881e9e650db2a41

カスタマむズの過皋を動画でも公開しおいたす。
カスタマむズ勉匷䞭の方はこちらも参考になるず思いたす。

関連


kintone の掻甚・業務改善に぀いおご盞談があれば、お問い合わせ からお気軜にどうぞ。