LoginSignup
2
1

[React] Refine + Hasura で作る簡単タスク管理アプリ

Last updated at Posted at 2023-08-19

初めに

工場の現場の見える化などを普段行っているものです。
本業はITエンジニアではないので色々と甘い部分がありますが悪しからず。

自分でDBを触ってマスター管理するのが面倒なのでWebで管理画面を作った時に使いました。

面倒なイベント処理やバックエンドとの通信処理をほぼ書くことなく作ることができます。

私の工場では外部にネットワークが繋がらないのでオンプレミスで動く構成となっております。

なお説明のためHasuraはCloud使ってますが、Dockerで立てて簡単に使うことができます。

大体30分ぐらいで作ることが出来ます。

出来上がるもの

  • テーブルView
  • タスク追加機能
  • タスク編集機能
  • タスク削除機能
    データはHasuraを通してDBに保存されます。
    image.png

中途半端な完成コード

前提知識

  • React 必須
  • postgres ほぼ知らなくてよい
  • GraphQL ほぼ知らなくてよい

導入

Refineセットアップ

https://github.com/refinedev/refine
RefineというReactフレームワークを使います。
日本語の文献がほぼないですが、コードをあまり書くことなく簡単なアプリを作ることができます。
認証やら多言語化やらいいようにしてくれます。

まずはインストール

npm create refine-app@latest
or
yarn create refine-app

コマンドを打つとテンプレート選ぶ画面が出ます。
ここではViteで開発します。
プロジェクト名は必須だった気がします。
バックエンドはHasuraを選択
UI Frameworkも好きなのを選べます。
Ant Designがおすすめ(できることが多いので)
Example pageは最初はあったほうがいいと思います。
authはお好みで。
i18nもお好みで
packerge managerもお好みで
メールは書かなくてオッケー

>refine(Vite)
What would you like to name your project? 好きな名前
Choose your backend service to connect Hasura
Do you want to use a UI Framework? Ant Design
Do you want to add example pages?: Yes
Do you want to add example pages?: inferencer
Do you need any Authentication logic?: auth-provider-custom
Do you need i18n (Internationalization) support?: i18n-antd
Choose a package manager: yarn

すべて選択するとインストールが始まります。

とりあえず動かしてみます。

yarn dev 

Example Pageを追加してるのであればここで既にそれっぽいページができてます。

Hasuraセットアップ

詳細割愛
データソースはpostgresを使ってます。

立ち上がったらこんな感じのページを開けると思います。
image.png

Create Tableでテーブルを作ります。

image.png

フレームワークの関係上idをPrimary Keyにする必要があります。

テーブルができたらInsert Rowで適当にデータを入れときます。

image.png

コーディング

ページ部分

pages直下にtasksフォルダを作成し
crate, edit, index, listファイルを以下のように作成します。

src\pages\tasks
create.tsx
edit.tsx
index.ts
list.tsx

コードはblog-postsをそのままコピーして関数名だけ変更します。

// list.tsx
import { IResourceComponentsProps } from "@refinedev/core";
import { AntdListInferencer } from "@refinedev/inferencer/antd";

import { inferencerPredefinedMeta } from "../../inferencerPredefinedMeta";

export const TasksList: React.FC<IResourceComponentsProps> = () => {
    return <AntdListInferencer
        meta={inferencerPredefinedMeta}
    />
};
// index.ts
export { TasksList } from "./list";
export { TasksCreate } from "./create";
export { TasksEdit } from "./edit"

データ連携

App.tsx部分を記述していきます。

API_URLを先ほど作成したhasuraのGraphQL EndpointのURLに変更します。

この画像のページのGraphQL EndpointにあるURL
image.png

headers部分をHasuraのRequestHeaders部分のkey valueにします。

const client = new GraphQLClient(API_URL, {
    headers: {
        "Hasuraに書いてあるKEY":"Hasuraに書いてあるValue" 
    },
});

HasuraのdataProviderはデフォルトだとuuidを使おうとするのでidTypeをIntに変更します。

return (
    <BrowserRouter>
        <GitHubBanner />
        <RefineKbarProvider>
            <ColorModeContextProvider>
                <Refine dataProvider={dataProvider(client, {
                    idType: "Int"
                })}

resources部分を修正してtasksを追加します。

resources={[
{
    name: "tasks",
    list: "/tasks",
    create: "/tasks/create",
    edit: "/tasks/edit/:id",
    meta: {
        canDelete: true,
    }
}
]}

Routeも修正します。

<Route index element={
    <NavigateToResource resource="tasks" />
} />
<Route path="/tasks">
    <Route index element={<TasksList />} />
    <Route path="create" element={<TasksCreate />} />
    <Route path="edit/:id" element={<TasksEdit />} />
</Route>

次にinferencerPredefinedMeta.tsに追記します。

    tasks: {
        getList: {
            fields: ["id", "task", "status"]
        },
        getOne: {
            fields: ["id", "task", "status"]
        },
    }

ここまで出来たら再度アプリを開きます。
すると勝手に生成したコードを表示してくれます。

image.png

Show the auto-generated code を押しコード表示します。

image.png

こちらをコピーして実際のコードに反映させます。
table部分はlist.tsxです。

// list.tsx
import React from "react";
import {
    IResourceComponentsProps,
    BaseRecord,
    useTranslate,
} from "@refinedev/core";
import { useTable, List, EditButton, DeleteButton } from "@refinedev/antd";
import { Table, Space } from "antd";

export const TasksList: React.FC<IResourceComponentsProps> = () => {
    const translate = useTranslate();
    const { tableProps } = useTable({
        syncWithLocation: true,

        meta: { fields: ["id", "task", "status"] },
    });

    return (
        <List>
            <Table {...tableProps} rowKey="id">
                <Table.Column
                    dataIndex="id"
                    title={translate("tasks.fields.id")}
                />
                <Table.Column
                    dataIndex={["task"]}
                    title={translate("tasks.fields.task")}
                />
                <Table.Column
                    dataIndex="status"
                    title={translate("tasks.fields.status")}
                />
                <Table.Column
                    title={translate("table.actions")}
                    dataIndex="actions"
                    render={(_, record: BaseRecord) => (
                        <Space>
                            <EditButton
                                hideText
                                size="small"
                                recordItemId={record.id}
                            />

                            <DeleteButton
                                hideText
                                size="small"
                                recordItemId={record.id}
                            />
                        </Space>
                    )}
                />
            </Table>
        </List>
    );
};

これだけでページが完成します。
createやedit部分も同様の作業をします。
全て貼り付けて不要部分を修正したら大枠は完成です。

これだけでタスク管理アプリができます。(細かい部分はいい感じに修正が必要)
詳しくはドキュメントを読んでください。
https://refine.dev/docs/#what-is-refine

社内で運用するのであればdockerでnginxを立ち上げてbuildしたデータを配信するだけです。

慣れたら10分程度で作れそうです。

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