2
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?

More than 3 years have passed since last update.

バックエンドをノーコードで「タスク管理ツール」を作った話

Last updated at Posted at 2021-07-23

はじめに

皆さん、仕事ををやる上でタスク管理ツールを使われると思います。
RedmineとかBacklogとか使ってますか?

そんな感じのものを
下記を使えばノーコードで作れるんじゃないのかなと思って作ってみた次第です。
CRUDのWebApi開発は不要!Json登録でWebApiを作れるシステムを作った話

また不完全ですが、作れました!!

作ったもの

みなさんが凄いもの作ってくれることを期待して、あえて90年代のデザインにしました😁

公開WebApi

これと同じような感じで使えます。
エンジニア・プログラマにしか使えないSNSを作ってみた話

エンドポイント

https://versatileapi.herokuapp.com/api/task_management

ユーザー

登録
POST /user

更新
PUT /user/:user_id

取得
GET /user/:user_id

全件取得
GET /user/all
ODataクエリが使用できます。(全て対応はしていません)

スキーマ

user.json
{
    "additionalProperties": false,
    "type": "object",
    "properties": {
        "name": {
            "description": "名前",
            "type": "string",
            "minLength": 1,
            "maxLength": 50
        }
    },
    "required": [
        "name"
    ]
}

カテゴリ

登録
POST /category

更新
PUT /category/:category_id

取得
GET /category/:category_id

全件取得
GET /category/all
ODataクエリが使用できます。(全て対応はしていません)

スキーマ

user.json
{
    "additionalProperties":false,
    "type": "object",
    "properties": {
        "category_name": {
            "description": "カテゴリ名",
            "type": "string",
            "minLength": 1,
            "maxLength": 50
        }
    },
    "required": [
        "category_name"
    ]
}

タスク

登録
POST /task

更新
PUT /task/:task_id

取得
GET /task/:task_id

全件取得
GET /task/all
ODataクエリが使用できます。(全て対応はしていません)

スキーマ

user.json
{
    "additionalProperties": false,
    "type": "object",
    "properties": {
        "title": {
            "description": "タスク名",
            "type": "string",
            "minLength": 1,
            "maxLength": 140
        },
        "description": {
            "description": "タスクの内容",
            "type": "string",
            "minLength": 1,
            "maxLength": 1000
        },
        "in_charge_user_id": {
            "description": "担当者Id",
            "type": "string",
            "minLength": 36,
            "maxLength": 36
        },
        "start_datetime": {
            "description": "開始日",
            "type": "string",
            "format":"date"
        },
        "end_datetime": {
            "description": "期限日",
            "type": "string",
            "format":"date"
        },
        "scheduled": {
            "description": "予定",
            "type": "number"
        },
        "achievements": {
            "description": "実績",
            "type": "number"
        },
        "status": {
            "description": "状態",
            "type": "string",
            "enum": [
              "waiting",
              "working",
              "pending",
              "completed",
              "discontinued"
            ]
        },
        "category_id": {
            "description": "カテゴリId",
            "type": "string",
            "minLength": 36,
            "maxLength": 36
        }
    },
    "required": [
        "title",
        "status"
    ]
}

暫定で作ったフロントエンドのHTML

一応公開しておきます。vue.jsで作りました

task-list.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>タスク管理ツール</title>
</head>

<body>
    <h2>タスク一覧</h2>
    <div id="app">
        <ul id="example-1">
            <li v-for="item in taskList" :key="taskList.id">
                <a :href="'./task-detail.html?taskid='+ item.id"> {{ item.title }}</a>
            </li>
        </ul>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
    <script>
        const api = "https://versatileapi.herokuapp.com/api/task_management/";
        const app = new Vue({
            el: "#app",
            data: {
                taskList: []
            },
            async mounted() {
                //可読性は良いけど、待たないほうが早い
                let taksInfo = await (await fetch(api + "task/all")).json();

                taksInfo.forEach(res => {
                    this.taskList.push(res);
                });
            },
            methods: {
            }
        });
    </script>
</body>

</html>
task-detail.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>タスク管理ツール</title>
</head>

<body>
    <div id="app">
        <h2>タスク詳細</h2>
        <p>タイトル:{{title}}</p>
        <p>チケット内容:{{description}}</p>
        <p>担当者:{{in_charge_user}}</p>
        <div style="display: flex;">
            <p>開始日:{{start_datetime}}</p>
            <p>期限日:{{end_datetime}}</p>
        </div>
        <div style="display: flex;">
            <p>予定:{{scheduled}}</p>
            <p>実績:{{achievements}}</p>
        </div>
        <p>状態:{{status}}</p>
        <p>カテゴリ:{{categoryName}}</p>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
    <script>
        const api = "https://versatileapi.herokuapp.com/api/task_management/";
        const app = new Vue({
            el: "#app",
            data: {
                title: "",
                description: "",
                in_charge_user: "",
                start_datetime: "",
                end_datetime: "",
                scheduled: "",
                achievements: "",
                status: "",
                categoryName: "",
            },
            async mounted() {
                let taskId = this.getUrlQueries()["taskid"];

                //可読性は良いけど、待たないほうが早い
                let taksInfo = await (await fetch(api + "task/" + taskId)).json();

                let userName = "";
                if (taksInfo["in_charge_user_id"] != null)
                    userName = (await (await fetch(api + "user/" + taksInfo["in_charge_user_id"])).json())["name"];
                let categoryName = "";
                if (taksInfo["category_id"] != null)
                    categoryName = (await (await fetch(api + "category/" + taksInfo["category_id"])).json())["category_name"];

                this.title = taksInfo["title"];
                this.description = taksInfo["description"];
                this.in_charge_user = userName;
                this.start_datetime = taksInfo["start_datetime"];
                this.end_datetime = taksInfo["end_datetime"];
                this.scheduled = taksInfo["scheduled"];
                this.achievements = taksInfo["achievements"];
                this.status = taksInfo["status"];
                this.categoryName = categoryName;
            },
            methods: {
                getUrlQueries: function () {
                    var queryStr = window.location.search.slice(1);
                    queries = {};
                    if (!queryStr) {
                        return queries;
                    }
                    queryStr.split("&").forEach(function (queryStr) {
                        var queryArr = queryStr.split("=");
                        queries[queryArr[0]] = queryArr[1];
                    });

                    return queries;
                }
            }
        });
    </script>
</body>

</html>

参考文献

2
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
2
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?