0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

UMD版Hexabase JavaScript SDKを使ってTodoアプリを作る(タスクのステータス変更)

Posted at

Hexabase(ヘキサベース)は企業においても安心して利用できるBaaS(Backend as a Service)を提供しています。多くのBaaSがそうであるように、主にフロントエンド開発者に利用してもらいたいと考えています。そこで現在、TypeScript SDKの開発が進められています。

元々TypeScriptで作られていることもあって、Next.jsやVue.jsなどでimportして利用することができます。しかし、もっと普通のWebアプリケーションなどで使う際には、CDN経由で利用したいと考える方もいるでしょう。そこで、UMD版Hexabase JavaScript SDKを作成しました。

今回は、そのUMD版Hexabase JavaScript SDKを使ったTodoアプリのデモを紹介します。今回はタスクの表示と、編集機能を解説します。一覧の表示、タスクの追加と削除および編集は以下を参照してください。

デモ

デモはこちらのURLで体験できます。

image.png

SDKの読み込み

SDKは下記URLで読み込めます。

<script src="https://cdn.jsdelivr.net/npm/@hexabase/hexabase-js@latest/dist/umd/hexabase.min.js"></script>

バージョン指定する場合は、以下のようになります。メジャーバージョンが上がらない限りはlatest指定をお勧めします。

<script src="https://cdn.jsdelivr.net/npm/@hexabase/hexabase-js@2.0.6/dist/umd/hexabase.min.js"></script>

モジュールとして使う場合には、以下のようになります。

<script type="module">
import hexabase from 'https://cdn.jsdelivr.net/npm/@hexabase/hexabase-js@latest/+esm'
</script>

SDKの初期化

SDKは以下のようコードで初期化します。これさえ終われば、後はTypeScriptと同じように使えます。

const { HexabaseClient } = hexabase;
const client = new HexabaseClient();

HTMLについて

HTMLはBootstrapを使って、以下のように作成しています。上半分が既存タスクの表示、下半分はタスクの追加・編集用フォームになっています。 #Status にステータス変更の表示を行います。

<div class="container" style="padding-top: 1em;">
  <div class="row justify-content-md-center">
    <div class="col-10">
      <div class="row justify-content-end">
        <div class="col-5">
          <button type="button" id="add" class="btn btn-primary">➕ 新しいタスク</button>
        </div>
      </div>
      <table class="table">
        <thead>
          <tr>
            <th scope="col">タスク</th>
            <th scope="col">担当者名</th>
            <th scope="col">カテゴリ</th>
            <th scope="col">ステータス</th>
            <th scope="col">アクション</th>
          </tr>
        </thead>
        <tbody>
          
        </tbody>
      </table>
      <form>
        <div class="row g-3">
          <input type="hidden" name="id" />
          <div class="col">
            <input type="text" class="form-control" name="Title" aria-describedby="emailHelp" placeholder="新しいタスク">
          </div>
          <div class="col">
            <input type="text" class="form-control" name="Assignee" placeholder="担当者名">
          </div>
          <div class="col">
            <select name="Category" class="form-control">
            
            </select>
          </div>
          <div class="col">
            <button type="submit" name="Button" id="button" class="btn btn-primary" disabled>追加</button>
          </div>
        </div>
      </form>
      <div class="row g-3" style="padding-top: 1em;">
        <div class="col">
          <div id="Status">
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

初期設定

まずコード内で使う変数、DOMを定義します。

// 認証用のメールアドレスとパスワード
const email = 'demo5@moongift.jp';
const password = 'K4c%j%vzR7sQKS$u&Uo%';

// Hexabaseのワークスペース、プロジェクト、ワークスペースのID
const workspaceId = '644f6e5ab30d853869ec919f';
const projectId = '650a30501222568b1ae7a2c2';
const datastoreId = '65895ba97b4300d37757d562';

// 複数の処理で使う変数用
const params = {
	datastore: null, // データストア
  items: [], // 既存タスク一覧
};

// DOM
const table = document.querySelector('.table tbody');
const form = document.querySelector('form');
const addButton = document.querySelector('#add');

初期表示処理

初期表示の処理は以下のようになります。初期設定、データの読み込み、そしてフォームへの値設定となります。

// 画面が読み込まれたときの処理
(async () => {
  await init();
  load();
  await makeForm();
})();

初期設定

初期設定用の init 関数ではログインやワークスペース・プロジェクト・データストアの取得を行っています。

// 初期設定
const init = async () => {
	// ログイン
	const res = await client.login({email, password});
  // ワークスペース・プロジェクト・データストアの取得
  await client.setWorkspace(workspaceId);
  const project = await client.currentWorkspace.project(projectId);
  params.datastore = await project.datastore(datastoreId);  
  // 追加ボタンを押せるようにする
  addButton.disabled = false;
};

データの読み込み

load 関数は既存のタスク一覧を読み込み、テーブルに表示します。

// 既存のアイテム一覧を取得する処理
const load = async () => {
	const query = client.query(projectId);
  const items = await query
      .from(datastoreId)
      .select('*');
  params.items = items;
  // 表示更新
  showTable();
};

showTable 関数は、取得したアイテム一覧をテーブルに表示します。また、削除ボタンのイベントリスナーも設定しています。編集ボタンは .edit で、クリックすると editItem 関数を呼び出します。

// タスク一覧の更新と、タスクへのアクション設定
const showTable = () => {
	// params.itemsに沿って、表示を更新
	table.innerHTML = params.items.map(item => `
  <tr data-id="${item.id}">
  	<td>${item.get('Title')}</td>
    <td>${item.get('Assignee')}</td>
    <td>${item.get('Category').ja}</td>
    <td>${item._status ? item._status.name : item.statusLabel}</td>
    <td>
    	<span class="edit">📝</span>
    	<span class="delete">🗑️</span>
    </td>
  </tr>`).join('');
  // 表示リセット
  form.reset();
  Status.innerHTML = '';
  
  // 削除のイベントリスナー
  table.querySelectorAll('.delete').forEach(dom => {
  	dom.addEventListener('click', deleteItem);
  });
  
  table.querySelectorAll('.edit').forEach(dom => {
  	dom.addEventListener('click', editItem);
  });
};

フォームの作成

makeForm 関数は、フォームの select タグに対して、Hexabaseで設定しているオプションを取得し、描画します。

ja は日本語で、 en に英語が設定されています。

// フォームの作成処理
const makeForm = async () => {
  // ドロップダウンの項目を取得
  const field = await params.datastore.field('Category');
  // オプション項目を取得
  const options = await field.options();
  // HTMLに反映
  const html = options.map(option => `
  	<option id="${option.id}">${option.value.ja}</option>
  `);
  document.querySelector('form [name="Category"]').innerHTML = html;
}

タスクの編集

既存タスクの編集アイコンをクリックすると editItem 関数が呼ばれます。これは、既存データをフォームに表示する処理です。ドロップダウンのoptionを選択状態にするところで多少工夫が必要です。

item.statusActions を実行すると、次のステータスに変更するためのアクションが取得できます。これをボタンにして表示しています。ボタンをクリックすると updateStatus 関数が呼ばれます。

// 編集フォームの作成・項目を表示する処理
const editItem = async (e) => {
  const id = e.target.closest('tr').getAttribute('data-id');
	// 該当するアイテムを探す
	const item = params.items.find(item => item.id === id);
  form.elements.id.value = id;
  form.elements.Title.value = item.get('Title');
  form.elements.Assignee.value = item.get('Assignee');
  const category = item.get('Category');
  const field = await params.datastore.field('Category');
  // オプション項目を取得
  const options = await field.options();
  const option = options.find(option => option.value.ja === category.ja);
  form.elements.Category.options[option.id].selected = true;
  form.elements.Button.innerText = '更新';
  form.elements.Button.disabled = false;
  
  // アイテムの詳細情報取得(ステータス用)
  await item.fetch(); 
  // 次のステータスをボタンで表示
  Status.innerHTML = item.statusActions.map(action => `
  	<button class="btn btn-success" data-id="${action.id}">${action.name}</button>
  `).join(' ');
  // 各ボタンにイベント設定
  Status.querySelectorAll('button').forEach(dom => {
  	dom.addEventListener('click', (e) => updateStatus(item, e));
  });
};

image.png

上記の画像の場合、 作業中に戻す完了する がステータス変更のアクションになります。

ステータスとは

Hexabaseのデータストア(RDBMSでいうテーブル相当)ではステータスという特別なフィールドが用意されています。

ステータスは、データの状態を表すためのフィールドです。例えば、案件のデータを管理する場合、ステータスには「新規」「進行中」「完了」などの値を設定します。そして、ステータスは直接変更はできず、ステータス変更のアクションを実行して変更します。

たとえば以下のようになります。

データの状態 ステータス
新規保存 起票
プロジェクト開始 開始
納品完了 検収中
プロジェクト終了 請求前
請求書発行 入金前
入金確認 完了

そして、このステータスの中には差し戻しが発生することもあるでしょう。検収中のステータスから開始に戻すこともあるでしょう。このような場合も、ステータスの変更はアクションを実行することで行います。

image.png

Hexabaseでは、特定のステータスから別なステータスに変更するアクションは、あらかじめ定義したものだけが指定できます。

ステータスの作成

ステータスは管理画面で作成します。ここで各ステータスが別なステータスに変更できるアクションを定義します。

image.png

ステータスの更新

ステータスの更新は updateStatus 関数で行います。ステータス変更を行うアクションIDを取得して、 item.execute メソッドで実行します。

// ステータスの更新処理
const updateStatus = async (item, e) => {
  e.preventDefault();
  // 次のステータスに移動するアクション
  const actionId = e.target.getAttribute('data-id');
	await item.execute(actionId);
  // 再描画
  showTable();
}

まとめ

今回はUMD版Hexabase JavaScript SDKを使って、Todoアプリを作成するデモを紹介しました。UMD版Hexabase JavaScript SDKは、CDN経由で利用できるため、jQueryなど普通のWebアプリケーションでも利用できます。また、TypeScript SDKと同じように使えるため、TypeScript SDKを使っている方でも移行が容易です。

ぜひHexabaseを使ってWebアプリケーション開発を行ってください。

Hexabase | 新規事業向け開発・競争領域でのDX実現をサポート

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?