ライブデモを試す
Admiral は、React でバックオフィスを作成するためのフロントエンド フレームワークです。管理インターフェイスを簡単かつ迅速に開発できるようにする、すぐに使えるコンポーネントとツールを提供します。
で作られた?開発者ファミリーによる
要件:
Admiral をインストールするには、いくつかのオプションがあります。
npx を使用するには、 Node.jsがあることを確認してください。
npx create-admiral-app@latestこのコマンドをコンソールに入力すると、2 つのインストール オプションが表示されます。
[ Express.js にバックエンド設定を使用してテンプレートをインストールする] を選択すると、バックエンドを使用して完全にカスタマイズされたテンプレートが Express.js にインストールされます。
インストールと起動の詳細な手順
すべての環境変数は自動的に設定されます。手動で設定する場合は、プロジェクト フォルダーに移動して.env ファイルを開きます。最初から 1 つの CRUD ( Users)があります。それらを見つけるには、道を通過します - admiral/src/crud/users/index.tsx
「バックエンド設定なしでテンプレートをインストールする」を選択すると、CRUD- Usersが含まれる admiral フォルダーに Admiral のフロントエンド シェルのみが取得されます。それを見つけるには、 admiral/src/crud/users/index.tsxという方法を参照してください。バックエンドを使用するには、ドキュメントをお読みください。
Admiral は http://localhost:3000 で入手できます。ポート 3000 が使用中の場合は、他の空いているポートが選択されます。
コンソールに次のようなものが表示されます
Port 3000 is in use, trying another one...
vite v2.9.15 dev server running at:
> Local: http://localhost:3001/
> Network: http://192.168.100.82:3001/
ready in 459ms.詳細なインストールと起動の手順は、各例に記載されています。
ブラウザを開いて http://localhost:3000 に移動します。
はい、そうです。このリポジトリのクローンを作成し、次のコマンドを入力するだけです。
yarn
yarn dev次に、http://localhost:3000 に移動します。模擬データを備えた提督が利用可能になりました。
App.tsx ファイルは、アプリケーションへのエントリ ポイントです。ここでライブラリが初期化され、コンポーネントがAdminレンダリングされます。
import React from 'react'
import { Admin , createRoutesFrom , OAuthProvidersEnum } from '../admiral'
import Menu from './config/menu'
import dataProvider from './dataProvider'
import authProvider from './authProvider'
const apiUrl = '/api'
// import all pages from pages folder and create routes
const Routes = createRoutesFrom ( import . meta . globEager ( '../pages/**/*' ) )
function App ( ) {
return (
< Admin
dataProvider = { dataProvider ( apiUrl ) }
authProvider = { authProvider ( apiUrl ) }
menu = { Menu }
oauthProviders = { [
OAuthProvidersEnum . Google ,
OAuthProvidersEnum . Github ,
OAuthProvidersEnum . Jira ,
] }
>
< Routes />
</ Admin >
)
}
export default Appシステム内の認可の主なコントラクトはAuthProviderインターフェイスです。
export interface AuthProvider {
login : ( params : any ) => Promise < any >
logout : ( params : any ) => Promise < void | false | string >
checkAuth : ( params : any ) => Promise < void >
getIdentity : ( ) => Promise < UserIdentity >
oauthLogin ?: ( provider : OAuthProvidersEnum ) => Promise < { redirect : string } >
oauthCallback ?: ( provider : OAuthProvidersEnum , data : string ) => Promise < any >
[ key : string ] : any
}実装例 インターフェイス自体は好みに合わせてカスタマイズできますが、インターフェイスが提供する規約を尊重することが重要です。契約の詳細な説明
基本的な実装方法を見てみましょう。
| 方法 | 名前 | 説明 | パラメータ | 戻り値 |
|---|---|---|---|---|
| ログイン | ユーザー認証 | /api/loginに対して POST リクエストを実行し、 tokenフィールドを localStorage に保存します。これはその後のリクエストで使用されます。 | params - usernameとpasswordのフィールドを持つオブジェクト | tokenフィールドを持つオブジェクトと、 emailとnameフィールドを持つuserオブジェクト |
| ログアウト | ユーザーのログアウト | /api/logoutに POST リクエストを送信し、localStorage からtokenフィールドを削除します。 | void | |
| 認証確認 | ユーザー権限チェック | /api/checkAuthへの GET リクエストを実行し、トークンの有効性をチェックします。ステータス コード - 200 が期待されます。API が使用されるたびに使用されます。 | 無記名token | ステータスコード 200 |
| getIdentity | ユーザーデータの受信 | /api/getIdentityに対して GET リクエストを実行し、ユーザー データを含むオブジェクトを返します。 | 無記名token | emailとnameフィールドを持つオブジェクトuser |
| oauthログイン | OAuthによる認証 | /api/auth/social-login/${provider}に対して GET リクエストを実行し、リダイレクトに使用されるredirectフィールドを含むオブジェクトを返します。 | provider - OAuth プロバイダー | フィールドredirectを持つオブジェクト |
| oauthコールバック | OAuth経由のコールバック認証 | /api/auth/social-login/${provider}/callbackに POST リクエストを作成し、 tokenフィールドを localStorage に保存します。これは以降のリクエストで使用されます。 | provider - OAuth プロバイダー、 data - tokenフィールドが存在する OAuth プロバイダーから受信したデータ | フィールドtokenを持つオブジェクト |
データを操作するためのメイン コントラクトは、 DataProviderインターフェイスを表します。
export interface DataProvider {
getList : (
resource : string ,
params : Partial < GetListParams > ,
) => Promise < GetListResult < RecordType > >
reorderList : ( resource : string , params : ReorderParams ) => Promise < void >
getOne : ( resource : string , params : GetOneParams ) => Promise < GetOneResult < RecordType > >
getCreateFormData : ( resource : string ) => Promise < GetFormDataResult < RecordType > >
getFiltersFormData : (
resource : string ,
urlState ?: Record < string , any > ,
) => Promise < GetFiltersFormDataResult >
create : ( resource : string , params : CreateParams ) => Promise < CreateResult < RecordType > >
getUpdateFormData : (
resource : string ,
params : GetOneParams ,
) => Promise < GetFormDataResult < RecordType > >
update : ( resource : string , params : UpdateParams ) => Promise < UpdateResult < RecordType > >
deleteOne : ( resource : string , params : DeleteParams ) => Promise < DeleteResult < RecordType > >
[ key : string ] : any
}導入例 契約内容詳細
基本的な実装方法を見てみましょう。
| 方法 | 名前 | 説明 | パラメータ |
|---|---|---|---|
| getList | エンティティのリストの取得 | /api/${resource}に対して GET リクエストを実行し、 Listコンポーネントで使用されるデータを含むオブジェクトを返します。 | resource - リソース名、 params - クエリパラメータを持つオブジェクト |
| リストの並べ替え | エンティティの順序の変更 | /api/${resource}/reorderに対して POST リクエストを実行し、 Listコンポーネントで使用されるデータを含むオブジェクトを返します。 | resource - リソース名、 params - クエリパラメータを持つオブジェクト |
| ゲットワン | エンティティの取得 | /api/${resource}/${id}に対して GET リクエストを実行し、 Showコンポーネントで使用されるデータを含むオブジェクトを返します。 | resource - リソース名、 id - エンティティ識別子 |
| getフォームデータの作成 | エンティティ作成フォームのデータの取得 (Select、AjaxSelect) | /api/${resource}/createに対して GET リクエストを実行し、 Createコンポーネントで使用されるデータを含むオブジェクトを返します。 | resource - リソース名 |
| getFiltersFormData | フィルター用データの受信 | /api/${resource}/filtersに対して GET リクエストを実行し、 Filtersコンポーネントで使用されるデータを含むオブジェクトを返します。 | resource - リソース名、 urlState - Filtersで使用される URL のパラメータを含むオブジェクト |
| 作成する | エンティティの作成 | /api/${resource}に対して POST リクエストを実行し、コンポーネントで使用されるデータを含むオブジェクトを返しますCreate | resource - リソース名、 params - エンティティ データ オブジェクト |
| getUpdateFormData | エンティティ編集フォームのデータの取得 (Select、AjaxSelect) | /api/${resource}/${id}/updateに対して GET リクエストを実行し、コンポーネントで使用されるデータを含むオブジェクトを返しますEdit | resource - リソース名、 id - エンティティ識別子 |
| アップデート | エンティティの更新 | /api/${resource}/${id}に対して POST リクエストを実行し、コンポーネントで使用されるデータを含むオブジェクトを返しますEdit | resource - リソース名、 id - エンティティ識別子、 params - エンティティ データ オブジェクト |
| 消去 | エンティティの削除 | /api/${resource}/${id}に対して DELETE リクエストを実行し、コンポーネントのDeleteで使用されるデータを含むオブジェクトを返します。 | resource - リソース名、 id - エンティティ識別子 |
クエリ:
http://localhost/admin/users?page=1&perPage=10&filter%5Bid%5D=1結果:
{
"items" : [
{
"id" : 1 ,
"name" : " Dev family " ,
"email" : " [email protected] " ,
"role" : " Administrator " ,
"created_at" : " 2023-05-05 14:17:51 "
}
],
"meta" : {
"current_page" : 1 ,
"from" : 1 ,
"last_page" : 1 ,
"per_page" : 10 ,
"to" : 1 ,
"total" : 1
}
}クエリ:
http://localhost/admin/users/1/update?id=1結果:
{
"data" : {
"id" : 1 ,
"name" : " Dev family " ,
"email" : " [email protected] " ,
"role_id" : 1
},
"values" : {
"role_id" : [
{
"label" : " Administrator " ,
"value" : 1
}
]
}
}❗注: 検証エラーを処理するために、HTTP ステータス コード 422 Unprocessable Entity を利用します。
{
"errors" : {
"name" : [ " Field 'name' is invalid. " ],
"email" : [ " Field 'email' is invalid. " ]
},
"message" : " Validation failed "
}ページネーションはgetListメソッドで動作します。 getListメソッドにpageとperPageパラメータを渡すと、 itemsとmetaフィールドを含むPaginationResultオブジェクトが返されます。
フィルターはgetListメソッドで機能します。 getListメソッドにfilter[$field]パラメータを渡すと、 itemsとmetaフィールドを含むPaginationResultオブジェクトが返されます。
並べ替えはgetListメソッドで行います。 sort[$field]パラメータをgetListメソッドに渡すと、 itemsとmetaフィールドを含むPaginationResultオブジェクトが返されます。
Admiral にはファイル システム ベースのルーターがあります。
ページは、ページのディレクトリ内の .js、.jsx、.ts、または .tsx ファイルからエクスポートされた React コンポーネントです。ファイルがページのディレクトリに追加されると、そのファイルはルートとして自動的に使用可能になります。内部ではreact-router-domが使用されています。
ルーターは、index という名前のファイルをディレクトリのルートに自動的にルーティングします。
pages/index.ts → / pages/users/index.ts → /users
ルーターはネストされたファイルをサポートします。ネストされたフォルダー構造を作成した場合でも、ファイルは同じ方法で自動的にルーティングされます。
pages/users/create.ts → /users/create
動的セグメントと一致させるには、括弧構文を使用できます。これにより、名前付きパラメータを照合できるようになります。
pages/users/[id].ts → /users/:id (/users/42)
このコンポーネントは管理パネルで最も重要です。これを使用すると、ナビゲーション、ロゴ、サーバーへのリクエスト用の API、API 認証、ローカリゼーション、テーマなど、アプリケーションの基本的な設定と構成を設定できます。
使用例:
< Admin
dataProvider = { dataProvider ( apiUrl ) }
authProvider = { authProvider ( apiUrl ) }
menu = { Menu }
oauthProviders = { [
OAuthProvidersEnum . Google ,
OAuthProvidersEnum . Github ,
OAuthProvidersEnum . Jira ,
] }
>
< Routes />
</ Admin >コンポーネントは次の props を受け入れます。
メニュー
ここでナビゲーションをカスタマイズできます。パッケージの特別なコンポーネント (Menu、MenuItemLink、SubMenu) を使用する必要があります。ここで例を見つけることができます。
ロゴ
サイドナビゲーションバーに表示されるロゴを変更できます。このプロパティは、svg、JSX コンポーネント、または svg 形式のファイルへのリンクを受け入れます。
ログインロゴ
承認フォームに表示されるロゴを変更できます。このプロパティは、svg、JSX コンポーネント、または svg 形式のファイルへのリンクを受け入れます。
余談コンテンツ
このツールを使用すると、リンクの下のサイド ナビゲーション バーに必要なコンテンツを追加できます。 ReactNode を渡す必要があります。
データプロバイダー
データを扱うための主要な契約。詳細については、ドキュメントをご覧ください。
認証プロバイダー
システム内の承認のための主要なコントラクト。詳細については、ドキュメントをご覧ください。
テーマプリセット
アプリケーションのカラーテーマをカスタマイズできます。詳細については、ドキュメントをご覧ください。
ロケール
管理パネルのローカリゼーション スキーム。useLocaleProvider フックを使用して取得できます。ここでスキームの例を見つけることができます。
oauthプロバイダー
このプロパティを使用して OAuth 認証を使用します。 Admiral からの OAuthProvidersEnum enum を使用して、配列内の必要なプロバイダーの名前を渡します。
ベースアプリURL
アプリのベースパスを変更するためのプロパティを追加します。
メニューは、次の構造を持つオブジェクトの配列です。
import { Menu , SubMenu , MenuItemLink } from '../../admiral'
const CustomMenu = ( ) => {
return (
< Menu >
< MenuItemLink icon = "FiCircle" name = "First Menu Item" to = "/first" />
< SubMenu icon = "FiCircle" name = "Second Menu Item" >
< MenuItemLink icon = "FiCircle" name = "Sub Menu Item" to = "/second" />
</ SubMenu >
</ Menu >
)
}
export default CustomMenu私たちのアプリケーションは React フックを使用します。これらは、React コンポーネント内のアプリケーションのどこからでも使用できます。使用できるフックは次のとおりです。
このフックを使用すると、ナビゲーション バーのステータスを受信して管理できます。
import { useNav } from '@devfamily/admiral'
const { collapsed , toggleCollapsed , visible , toggle , open , close } = useNav ( )このフックを使用すると、フォーム値を取得し、フォームの状態を管理できます。フックは、createCRUD 関数の構成内の「フォーム」で使用されるコンポーネントで使用できます。
import { useForm } from '@devfamily/admiral'
const {
values ,
options ,
errors ,
setErrors ,
setValues ,
setOptions ,
isSubmitting ,
isFetching ,
locale ,
} = useForm ( )このフックを使用すると、テーマの状態を受信して管理できます。
import { useTheme } from '@devfamily/admiral'
const { themeName , setTheme } = useTheme ( )AuthProvider.getIdentity() を呼び出して取得した状態を取得できるフック
import { useGetIdentty } from '@devfamily/admiral'
const { identity , loading , loaded , error } = useGetIdentty ( )Admiralで使用しているアイコンはReact Iconsからのものです。
ThemeProvider は内部で @consta/uikit テーマ コンポーネントを使用します。
themePresetsプロパティを使用してプリセットをAdminコンポーネントに渡すことができます。
import React from 'react'
import { Admin , createRoutesFrom } from '../admiral'
import Menu from './config/menu'
import dataProvider from './dataProvider'
import authProvider from './authProvider'
import themeLight from './theme/presets/themeLight'
import themeDark from './theme/presets/themeDark'
const apiUrl = '/api'
const Routes = createRoutesFrom ( import . meta . globEager ( '../pages/**/*' ) )
function App ( ) {
return (
< Admin
dataProvider = { dataProvider ( apiUrl ) }
authProvider = { authProvider ( apiUrl ) }
menu = { Menu }
themePresets = { { light : themeLight , dark : themeDark } }
>
< Routes />
</ Admin >
)
} プリセット用のディレクトリを作成します。内部では、各モディファイアーのフォルダーを作成します - テーマコンポーネントの場合と同じです。
CSSファイルを作成します。修飾子を含むフォルダーに、それらの修飾子を担当する CSS ファイルを置きます。
同様のものが得られます:
presets/
_color/
_Theme_color_themeDark.css
_Theme_color_themeLight.css
_control/
_Theme_control_themeLight.css
_font/
_Theme_font_themeLight.css
_size/
_Theme_size_themeLight.css
_space/
_Theme_space_themeLight.css
_shadow/
_Theme_shadow_themeLight.css
themeLight.ts
themeDark.ts
CSS ファイルで変数を設定します。
プリセットファイル(themeLight、themeDark)を作成します。
使用する CSS ファイルをインポートします。
プリセットオブジェクトを作成します。プリセットでどの修飾子にどの値 (つまり CSS ファイル) を使用するかを指定します。同様のものが得られます:
// in presets/themeLight.ts
import './_color/_Theme_color_themeLight.css'
import './_color/_Theme_color_themeDark.css'
import './_control/_Theme_control_themeLight.css'
import './_font/_Theme_font_themeLight.css'
import './_size/_Theme_size_themeLight.css'
import './_space/_Theme_space_themeLight.css'
import './_shadow/_Theme_shadow_themeLight.css'
export default {
color : {
primary : 'themeLight' ,
accent : 'themeDark' ,
invert : 'themeDark' ,
} ,
control : 'themeLight' ,
font : 'themeLight' ,
size : 'themeLight' ,
space : 'themeLight' ,
shadow : 'themeLight' ,
}上の例のように、プリセットをAdminコンポーネントに渡します。
❗注: admiral プリセットの例では、色変換に postcss プラグインが使用されています。再現したい場合は、postcssとpostcss-color-mod-functionプラグインを設定してください。
Admiral の開発に参加したい場合は、リポジトリをフォークし、必要な変更を加えてプル リクエストを送信します。皆様のご提案を喜んで検討させていただきます。
このライブラリは MIT ライセンスに基づいて配布されます。
ご質問がございましたら、[email protected] までご連絡ください。フィードバックはいつでもお待ちしております。