Airtableのようなツールについて聞いたことがありますが、どこから始めればよいのかわかりませんでしたか?次に、データベースを構築するビジュアルプログラミングの世界にあなたを招待します!
この投稿から、Quarklyツールを使用した実際の例を示す一連のチュートリアルを開始します。このチュートリアルでは、会社の従業員を表示する簡単なWebアプリケーションを作成します。アプリケーションを作成したとき、ロシア鉄道の従業員は1人もけがをしていませんでした。
フロントはQuarklyを使用して行われ、データはデータベースからAirtableにプルされます。出力では、データベースと同期された反応アプリケーションを取得します。
前文。なぜAirtableなのか
Airtableは、データベースを大きくすることができる人気のあるノーコードツールです。それらはテーブルのように見えますが、はるかに強力な機能を備えています。特に、私たちのレッスンでは、APIを介してデータを転送する簡単な方法のためにAirtableが選択されました。
Airtableについて初めて聞いた場合は、作業を開始する前に、会社のWebサイトにある公式マニュアルを読む必要はありません。また、Airtable Chat&Communityテレグラムで躊躇せずに質問することをお勧めします。
作業のフロントエンド部分はQuarklyで行われ、このために2つのコンポーネントのみを使用します。
- 従業員カード。写真、テキストデータ、2つのボタン(メールの送信と電話)が含まれます。カードは、親コンポーネントであるラッパーからこのデータを受け取ります。
- ラッパー。Airtableからデータを受信し、カードを生成してデータを転送します。
印刷形式で投稿を詳しく調べる時間がない人のために、字幕とタイムコードを含むビデオを用意しました。
パート1。Quarklyでビジュアルを作成する
カードの作成:
- Quarkly, Airtable Example;
- ;
- . + Team;

- (StackItem) ;
«» Convert to Component. EmployeeCard.

- react-, -.
:
- . , ;

- EmployeeCard Stack. Stack , EmployeeCard: , «» Convert to Component. EmployeeTable.
, . Airtable.
2. Airtable
Airtable /.
- Add a base, . Start with a template;

- HR & Recruiting Employee directory. Use template;

- ;

, .
3. API
Airtable API. , , Airtable .
- API : https://airtable.com/api

- Employee directory. AUTHENTICATION.

- , EXAMPLE USING BEARER TOKEN (RECOMMENDED).
:
$ curl https://api.airtable.com/v0/app2MdLITmRTBsrkg/Employee%20directory \
-H "Authorization: Bearer YOUR_API_KEY"
- YOUR_API_KEY. , . .

- API Generate API key;

- . 3. .
4. Airtable Quarkly
EmployeeTable , API.
- . Components <> EmployeeTable ( );

- :

- :
import React from "react";
:
import React, { useEffect, useState } from "react";
useEffect useState, ; - , EmployeeCard:
import EmployeeCard from "./EmployeeCard";
- children ( ) override (, ):
const EmployeeTable = props => { const { children, rest } = useOverrides(props, overrides, defaultProps);
:
const EmployeeTable = props => { const { override, rest } = useOverrides(props, overrides, defaultProps);
- useState, :
const [employees, setEmployees] = useState([]);
- useEffect, API Airtable setEmployees.
, . fetch URL , ?view=All%20employees. headers API , 3 , 4.
useEffect(() => { fetch("https://api.airtable.com/v0/appWw7KBKSc9bPjZE/Employee%20directory?view=All%20employees", { headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }) .then(response => response.json()) .then(data => setEmployees(data.records.map(({ fields }) => fields))); }, []);
- , props override. , .
:
return <Stack {...rest}> {children} </Stack>; };
:
return <Stack {...rest}> { employees.map(employee => <EmployeeCard {...override("employeeCard")} employee={employee} />) } </Stack>; };
- Ctrl + S ( Cmd + S Mac). :
import React, { useEffect, useState } from "react"; import { useOverrides, Stack } from "@quarkly/components"; import EmployeeCard from "./EmployeeCard"; const defaultProps = { "margin-top": "40px" }; const overrides = {}; const EmployeeTable = props => { const { override, rest } = useOverrides(props, overrides, defaultProps); const [employees, setEmployees] = useState([]); useEffect(() => { fetch("https://api.airtable.com/v0/appWw7KBKSc9bPjZE/Employee%20directory?view=All%20employees", { headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }) .then(response => response.json()) .then(data => setEmployees(data.records.map(({ fields }) => fields))); }, []); return <Stack {...rest}> { employees.map(employee => <EmployeeCard {...override("employeeCard")} employee={employee} />) } </Stack>; }; Object.assign(EmployeeTable, { ...Stack, defaultProps, overrides }); export default EmployeeTable;
: API YOUR_API_KEY.
! Airtable, employees map. employees <EmployeeCard/>, .
EmpolyeeCard .
5. EmpolyeeCard
.
- . Components, EmployeeCard, <>.
- :
import React from "react"; import { useOverrides, Override, StackItem } from "@quarkly/components"; import { Box, Text } from "@quarkly/widgets"; const defaultProps = { "width": "25%", "lg-width": "50%", "sm-width": "100%" }; const overrides = { "box": { "kind": "Box", "props": { "height": "0", "margin": "0 0 20px 0", "padding-bottom": "100%", "background": "url(https://images.unsplash.com/photo-1503443207922-dff7d543fd0e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=582&q=80) 50% 0/cover no-repeat" } }, "text": { "kind": "Text", "props": { "color": "--grey", "margin": "0", "children": "CEO" } }, "text1": { "kind": "Text", "props": { "as": "h3", "font": "--headline3", "margin": "5px 0 20px 0", "children": "Nathan K. Joe" } }, "text2": { "kind": "Text", "props": { "as": "p", "margin": "20px 0 5px 0", "children": "This space is 100% editable. Use it to introduce a team member, describe their work experience and role within the company. This is also a great place to highlight a team member's strong sides." } } }; const EmployeeCard = props => { const { override, children, rest } = useOverrides(props, overrides, defaultProps); return <StackItem {...rest}> <Override slot="StackItemContent" flex-direction="column" /> <Box {...override("box")} /> <Text {...override("text")} /> <Text {...override("text1")} /> <Text {...override("text2")} /> {children} </StackItem>; }; Object.assign(EmployeeCard, { ...StackItem, defaultProps, overrides }); export default EmployeeCard;
- :
} = useOverrides(props, overrides, defaultProps);
:
const { employee = {} } = rest;
employee . - , , . :
<Box {...override("box")} />
:
<Box {...override("box")} background-image={`url(${employee.Photo && employee.Photo[0] && employee.Photo[0].url})`}/>
:
"background": "url(https://images.unsplash.com/photo-1503443207922-dff7d543fd0e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=582&q=80) 50% 0/cover no-repeat"
:
"background-size": "cover", "background-position": "center", "background-image": "url(https://images.unsplash.com/photo-1503443207922-dff7d543fd0e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=582&q=80) 50% 0/cover no-repeat"
:

- , . API Airtable . https://airtable.com/api, .
EMPLOYEE DIRECTORY TABLE.
, :
Name
Department
Home address
Email address
DOB
Start date
Phone
Reports to
Title
Status
Photo
Location - Title. :
<Text {...override("text")} />
:
<Text {...override("title")} children={employee.Title} />
overrides , .
:
"text": { "kind": "Text", "props": { "color": "--grey", "margin": "0", "children": "CEO" } },
:
"title": { "kind": "Text", "props": { "color": "--grey", "margin": "0", "children": "Title" } },
:
: . - Name Home address.
:
<Text {...override("text1")} /> <Text {...override("text2")} />
:
<Text {...override("name")} children={employee.Name} /> <Text {...override("address")} children={employee['Home address']} />
overrides. :
"text1": { "kind": "Text", "props": { "as": "h3", "font": "--headline3", "margin": "5px 0 20px 0", "children": "Nathan K. Joe" } }, "text2": { "kind": "Text", "props": { "as": "p", "margin": "20px 0 5px 0", "children": "This space is 100% editable. Use it to introduce a team member, describe their work experience and role within the company. This is also a great place to highlight a team member's strong sides." } }
:
"name": { "kind": "Text", "props": { "as": "h3", "font": "--headline3", "margin": "5px 0 5px 0", "children": "Name" } }, "address": { "kind": "Text", "props": { "as": "p", "margin": "10px 0 5px 0", "children": "Home address" } },
:

- Text . Department Reports to, DEPARTMENTS TABLE.
:
<Text {...override("address")} children={employee['Home address']} /> <Text {...override("Start date")} children={`Start date: ${employee['Start date']}`} /> <Text {...override("Status")} children={employee['Status']} /> <Text {...override("DOB")} children={`Birth date: ${employee['DOB']}`} />
"address": { "kind": "Text", "props": { "as": "p", "margin": "10px 0 5px 0", "children": "Home address" } }, "Start date": { "kind": "Text", "props": { "as": "p", "margin": "10px 0 5px 0", "children": "Start date" } }, "Status": { "kind": "Text", "props": { "as": "p", "margin": "10px 0 5px 0", "children": "Status" } }, "DOB": { "kind": "Text", "props": { "as": "p", "margin": "10px 0 5px 0", "children": "Birth date" } },
:

- 次に、2つのリンクコンポーネントを追加しましょう。ここには、電話と電子メールがあります。
import { Box, Text } from "@quarkly/widgets";
への変更:
import { Box, Text, Link } from "@quarkly/widgets";
そして、次の行を追加します。
<Link {...override("Email address")} children={employee['Email address']} href={`mailto:${employee['Email address']}`} /> <Link {...override("Phone")} children={employee['Phone']} href={`tel:${employee['Phone']}`}/>
それらのオーバーライドを忘れないでください:
"Email address": { "kind": "Link", "props": { "margin": "10px 0 5px 0", "color": "--primary", "text-decoration": "none", "children": "Email" } }, "Phone": { "kind": "Link", "props": { "margin": "10px 0 5px 0", "color": "--primary", "text-decoration": "none", "children": "Phone" } },
結果の確認:

最終的なコードは次のようになります。
import React from "react";
import { useOverrides, Override, StackItem } from "@quarkly/components";
import { Box, Text, Link } from "@quarkly/widgets";
const defaultProps = {
"width": "25%",
"lg-width": "50%",
"sm-width": "100%"
};
const overrides = {
"box": {
"kind": "Box",
"props": {
"height": "0",
"margin": "0 0 20px 0",
"padding-bottom": "100%",
"background-size": "cover",
"background-position": "center",
"background-image": "url(https://images.unsplash.com/photo-1503443207922-dff7d543fd0e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=582&q=80) 50% 0/cover no-repeat"
}
},
"title": {
"kind": "Text",
"props": {
"color": "--grey",
"margin": "0",
"children": "title"
}
},
"name": {
"kind": "Text",
"props": {
"as": "h3",
"font": "--headline3",
"margin": "5px 0 5px 0",
"children": "Name"
}
},
"address": {
"kind": "Text",
"props": {
"as": "p",
"margin": "10px 0 5px 0",
"children": "Home address"
}
},
"Start date": {
"kind": "Text",
"props": {
"as": "p",
"margin": "10px 0 5px 0",
"children": "Start date"
}
},
"Status": {
"kind": "Text",
"props": {
"as": "p",
"margin": "10px 0 5px 0",
"children": "Status"
}
},
"DOB": {
"kind": "Text",
"props": {
"as": "p",
"margin": "10px 0 5px 0",
"children": "Birth date"
}
},
"Email address": {
"kind": "Link",
"props": {
"margin": "10px 0 5px 0",
"color": "--primary",
"text-decoration": "none",
"children": "Email"
}
},
"Phone": {
"kind": "Link",
"props": {
"margin": "10px 0 5px 0",
"color": "--primary",
"text-decoration": "none",
"children": "Phone"
}
},
};
const EmployeeCard = props => {
const {
override,
children,
rest
} = useOverrides(props, overrides, defaultProps);
const { employee = {} } = rest;
return <StackItem {...rest}>
<Override slot="StackItemContent" flex-direction="column" />
<Box {...override("box")} background-image={`url(${employee.Photo[0].url})`}/>
<Text {...override("title")} children={employee.Title} />
<Text {...override("name")} children={employee.Name} />
<Text {...override("address")} children={employee['Home address']} />
<Text {...override("Start date")} children={`Start date: ${employee['Start date']}`} />
<Text {...override("Status")} children={employee['Status']} />
<Text {...override("DOB")} children={`Birth date: ${employee['DOB']}`} />
<Link {...override("Email address")} children={employee['Email address']} href={`mailto:${employee['Email address']}`} />
<Link {...override("Phone")} children={employee['Phone']} href={`tel:${employee['Phone']}`}/>
{children}
</StackItem>;
};
Object.assign(EmployeeCard, { ...StackItem,
defaultProps,
overrides
});
export default EmployeeCard;
GitHubにコミットし、Netlifyに公開します。
数分待って確認します:https://keen-varahamihira-c54ae1.netlify.app/

同期を確認するには、データベースのデータを変更します。

これらはアプリケーションに表示されます。

将来的には、Airtableからの構成済みのインポートを中断することなく、好きなようにカードで要素のスタイルを設定できます。例はここで見ることができます。
GitHubリポジトリ:https://github.com/quarkly-dev/Getting-data-from-Airtable-tutorial
清聴ありがとうございました!
— . , , .