ลองสาธิตสด
Admiral เป็นเฟรมเวิร์กส่วนหน้าสำหรับสร้างแบ็คออฟฟิศใน React มีส่วนประกอบและเครื่องมือที่แกะกล่องซึ่งทำให้การพัฒนาอินเทอร์เฟซผู้ดูแลระบบง่ายและรวดเร็ว
ทำด้วย? โดย dev.family
ความต้องการ:
มีหลายตัวเลือกในการติดตั้ง Admiral:
หากต้องการใช้ npx ตรวจสอบให้แน่ใจว่าคุณมี Node.js
npx create-admiral-app@latest
เมื่อคุณป้อนคำสั่งนี้ลงในคอนโซล คุณจะเห็นตัวเลือกการติดตั้ง 2 แบบ:
หากคุณเลือก " ติดตั้งเทมเพลตด้วยการตั้งค่าแบ็กเอนด์บน Express.js " คุณจะติดตั้งเทมเพลตที่ปรับแต่งโดยสมบูรณ์ด้วยแบ็กเอนด์บน Express.js
คำแนะนำการติดตั้งและการเริ่มต้นโดยละเอียด
ตัวแปรสภาพแวดล้อมทั้งหมดจะถูกตั้งค่าโดยอัตโนมัติ หากคุณต้องการกำหนดค่าด้วยตนเอง ให้ไปที่โฟลเดอร์โปรเจ็กต์แล้วเปิดไฟล์ .env คุณจะมี 1 CRUD ตั้งแต่เริ่มต้น - ผู้ใช้ หากต้องการค้นหาพวกมันผ่านทาง - admiral/src/crud/users/index.tsx
หากคุณเลือก " ติดตั้งเทมเพลตโดยไม่มีการตั้งค่าแบ็กเอนด์ " คุณจะได้รับเพียงส่วนหน้าของ Admiral ในโฟลเดอร์ Admiral ที่มี CRUD - Users หากต้องการค้นหาว่ามันผ่านทาง - 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
}
ตัวอย่างการใช้งาน อินเทอร์เฟซสามารถปรับแต่งได้ตามที่คุณต้องการ แต่สิ่งสำคัญคือต้องเคารพสัญญาที่ให้ไว้ คำอธิบายสัญญาโดยละเอียด
ลองดูวิธีการพื้นฐานในการดำเนินการ:
วิธี | ชื่อ | คำอธิบาย | พารามิเตอร์ | ส่งคืนค่า |
---|---|---|---|---|
เข้าสู่ระบบ | การรับรองความถูกต้องของผู้ใช้ | ส่งคำขอ POST ไปที่ /api/login และจัดเก็บฟิลด์ token ใน localStorage ซึ่งใช้ในคำขอเพิ่มเติม | params - วัตถุที่ username และ password ของฟิลด์ | ออบเจ็กต์ที่มีช่อง token และออบเจ็กต์ user ที่มีช่อง email และ name |
ออกจากระบบ | ผู้ใช้ออกจากระบบ | ส่งคำขอ POST ไปที่ /api/logout และลบฟิลด์ token ออกจาก localStorage | void | |
ตรวจสอบการรับรองความถูกต้อง | การตรวจสอบสิทธิ์ผู้ใช้ | ส่งคำขอ GET ไปที่ /api/checkAuth และตรวจสอบความถูกต้องของโทเค็น คาดว่ารหัสสถานะ - 200 ใช้ทุกครั้งที่ใช้ API | token ผู้ถือ | รหัสสถานะ 200 |
รับข้อมูลประจำตัว | การรับข้อมูลผู้ใช้ | ส่งคำขอ GET ไปที่ /api/getIdentity และส่งคืนออบเจ็กต์พร้อมข้อมูลผู้ใช้ | token ผู้ถือ | user ออบเจ็กต์พร้อมฟิลด์ email และ name |
คำสาบานเข้าสู่ระบบ | การอนุญาตผ่าน OAuth | สร้างคำขอ GET ไปที่ /api/auth/social-login/${provider} และส่งคืนอ็อบเจ็กต์ด้วยฟิลด์ redirect ซึ่งใช้สำหรับการเปลี่ยนเส้นทาง | provider - ผู้ให้บริการ OAuth | วัตถุ redirect เส้นทางฟิลด์ |
คำสาบานโทรกลับ | การอนุญาตการโทรกลับผ่าน OAuth | ส่งคำขอ POST ไปที่ /api/auth/social-login/${provider}/callback และจัดเก็บฟิลด์ token ใน localStorage ซึ่งใช้ในคำขอเพิ่มเติม | provider - ผู้ให้บริการ OAuth data - ข้อมูลที่ได้รับจากผู้ให้บริการ OAuth ซึ่งมีฟิลด์ token อยู่ | วัตถุที่มี 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
}
ตัวอย่างการดำเนินการ คำอธิบายสัญญาโดยละเอียด
ลองดูวิธีการพื้นฐานในการดำเนินการ:
วิธี | ชื่อ | คำอธิบาย | พารามิเตอร์ |
---|---|---|---|
รับรายการ | รับรายการเอนทิตี | สร้างคำขอ GET ไปที่ /api/${resource} และส่งคืนออบเจ็กต์พร้อมข้อมูลที่จะใช้ในองค์ประกอบ List | resource - ชื่อทรัพยากร params - วัตถุที่มีพารามิเตอร์แบบสอบถาม |
เรียงลำดับรายการใหม่ | การเปลี่ยนลำดับของเอนทิตี | สร้างคำขอ POST เพื่อ /api/${resource}/reorder และส่งคืนออบเจ็กต์พร้อมข้อมูลที่จะใช้ในองค์ประกอบ List | resource - ชื่อทรัพยากร params - วัตถุที่มีพารามิเตอร์แบบสอบถาม |
รับหนึ่ง | การได้รับเอนทิตี | สร้างคำขอ GET ไปที่ /api/${resource}/${id} และส่งคืนออบเจ็กต์พร้อมข้อมูลที่จะใช้ในองค์ประกอบ Show | resource - ชื่อทรัพยากร id - ตัวระบุเอนทิตี |
getCreateFormData | การรับข้อมูลสำหรับแบบฟอร์มการสร้างเอนทิตี (Select, AjaxSelect) | สร้างคำขอ GET เพื่อ /api/${resource}/create และส่งคืนออบเจ็กต์พร้อมข้อมูลที่จะใช้ในองค์ประกอบ Create | resource - ชื่อทรัพยากร |
getFiltersFormData | การรับข้อมูลสำหรับตัวกรอง | สร้างคำขอ GET เพื่อ /api/${resource}/filters และส่งคืนออบเจ็กต์พร้อมข้อมูลที่จะใช้ในองค์ประกอบ Filters | resource - ชื่อทรัพยากร urlState - วัตถุที่มีพารามิเตอร์จาก url ที่จะใช้ใน Filters ส่วนประกอบ |
สร้าง | การสร้างเอนทิตี | สร้างคำขอ POST ไปที่ /api/${resource} และส่งคืนออบเจ็กต์พร้อมข้อมูลที่จะใช้ในคอมโพเนนต์ Create | resource - ชื่อทรัพยากร params - ออบเจ็กต์ข้อมูลเอนทิตี |
รับ UpdateFormData | การรับข้อมูลสำหรับแบบฟอร์มแก้ไขเอนทิตี (Select, AjaxSelect) | สร้างคำขอ GET เพื่อ /api/${resource}/${id}/update และส่งคืนออบเจ็กต์พร้อมข้อมูลที่จะใช้ใน Edit คอมโพเนนต์ | resource - ชื่อทรัพยากร id - ตัวระบุเอนทิตี |
อัปเดต | กำลังอัปเดตเอนทิตี | สร้างคำขอ POST ไปที่ /api/${resource}/${id} และส่งคืนออบเจ็กต์พร้อมข้อมูลที่จะใช้ใน Edit องค์ประกอบ | resource - ชื่อทรัพยากร, id - ตัวระบุเอนทิตี, params - ออบเจ็กต์ข้อมูลเอนทิตี |
ลบ | การลบเอนทิตี | สร้างคำขอ DELETE ไปที่ /api/${resource}/${id} และส่งคืนออบเจ็กต์พร้อมข้อมูลที่จะใช้ในคอมโพเนนต์ 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
คุณสามารถส่งพารามิเตอร์ page
และ perPage
ไปยังเมธอด getList
และมันจะส่งคืนออบเจ็กต์ PaginationResult
พร้อม items
และฟิลด์ meta
ตัวกรองทำงานร่วมกับเมธอด getList
คุณสามารถส่ง filter[$field]
ไปยังเมธอด getList
และมันจะส่งคืนออบเจ็กต์ PaginationResult
พร้อม items
และฟิลด์ meta
การเรียงลำดับงานด้วยวิธี getList
คุณสามารถส่งพารามิเตอร์ sort[$field]
ไปยังเมธอด getList
และมันจะส่งคืนออบเจ็กต์ PaginationResult
พร้อม items
และฟิลด์ meta
Admiral มีเราเตอร์ ที่ใช้ระบบไฟล์
เพจคือ React Component ที่ส่งออกจากไฟล์ .js, .jsx, .ts หรือ .tsx ในไดเร็กทอรีของเพจ เมื่อไฟล์ถูกเพิ่มลงในไดเร็กทอรีของเพจ ไฟล์นั้นจะสามารถใช้เป็นเส้นทางได้โดยอัตโนมัติ react-router-dom ถูกใช้ภายใต้ประทุน
เราเตอร์จะกำหนดเส้นทางไฟล์ชื่อดัชนีไปยังรูทของไดเร็กทอรีโดยอัตโนมัติ
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 >
ส่วนประกอบยอมรับอุปกรณ์ประกอบฉากต่อไปนี้:
เมนู
ที่นี่คุณสามารถปรับแต่งการนำทางของคุณได้ คุณควรใช้ส่วนประกอบพิเศษจากแพ็คเกจของเรา: Menu, MenuItemLink, SubMenu คุณสามารถหาตัวอย่างได้ที่นี่
โลโก้
คุณสามารถเปลี่ยนโลโก้ที่แสดงในแถบนำทางด้านข้างได้ เสายอมรับลิงก์ไปยัง svg, คอมโพเนนต์ JSX หรือไฟล์ที่มีรูปแบบ svg
เข้าสู่ระบบโลโก้
คุณสามารถเปลี่ยนโลโก้ที่แสดงในแบบฟอร์มการอนุญาตได้ เสายอมรับลิงก์ไปยัง svg, คอมโพเนนต์ JSX หรือไฟล์ที่มีรูปแบบ svg
กันเนื้อหา
ด้วยเครื่องมือนี้ คุณสามารถเพิ่มเนื้อหาที่จำเป็นลงในแถบนำทางด้านข้างใต้ลิงก์ได้ คุณต้องผ่าน ReactNode
dataProvider
สัญญาหลักสำหรับการทำงานกับข้อมูล คุณสามารถรับข้อมูลเพิ่มเติมได้ในเอกสารของเรา
authProvider
สัญญาหลักในการอนุญาตในระบบ คุณสามารถรับข้อมูลเพิ่มเติมได้ในเอกสารของเรา
ธีมที่ตั้งไว้ล่วงหน้า
คุณสามารถปรับแต่งธีมสีสำหรับแอปพลิเคชันของคุณได้ คุณสามารถรับข้อมูลเพิ่มเติมได้ในเอกสารของเรา
สถานที่
รูปแบบการแปลของแผงการดูแลระบบของคุณ ซึ่งคุณสามารถใช้ตะขอ useLocaleProvider คุณสามารถดูตัวอย่างโครงการได้ที่นี่
oauthProviders
ใช้การอนุญาต OAuth โดยใช้อุปกรณ์ประกอบฉากนี้ ส่งชื่อของผู้ให้บริการที่ต้องการในอาร์เรย์โดยใช้ OAuthProvidersEnum enum จากพลเรือเอก
baseAppUrl
เพิ่มอุปกรณ์ประกอบฉากเพื่อเปลี่ยนเส้นทางพื้นฐานของแอป
เมนูคืออาร์เรย์ของวัตถุที่มีโครงสร้างดังต่อไปนี้:
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 hooks คุณสามารถใช้มันได้จากทุกที่ในแอปพลิเคชันภายในส่วนประกอบ React นี่คือตะขอที่คุณสามารถใช้ได้:
เบ็ดนี้ช่วยให้คุณรับและจัดการสถานะของแถบนำทางได้
import { useNav } from '@devfamily/admiral'
const { collapsed , toggleCollapsed , visible , toggle , open , close } = useNav ( )
เบ็ดนี้ช่วยให้คุณรับค่าแบบฟอร์มและจัดการสถานะของแบบฟอร์มได้ hook สามารถใช้ในส่วนประกอบที่ใช้ใน "รูปแบบ" ภายในการกำหนดค่าของฟังก์ชัน 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 Theme ภายใต้ประทุน
คุณสามารถส่งค่าที่ตั้งล่วงหน้าของคุณไปยังองค์ประกอบ Admin
ด้วย themePresets
prop:
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
ตามตัวอย่างด้านบน
❗ หมายเหตุ : ปลั๊กอิน postcss ใช้สำหรับการแปลงสีในตัวอย่างการตั้งค่าล่วงหน้าของพลเรือเอก หากคุณต้องการทำซ้ำ ให้ตั้งค่าปลั๊กอิน postcss และ postcss-color-mod-function
หากคุณต้องการมีส่วนร่วมในการพัฒนา Admiral ให้สร้าง Fork ของพื้นที่เก็บข้อมูล ทำการเปลี่ยนแปลงที่ต้องการ และส่งคำขอดึง เรายินดีที่จะพิจารณาข้อเสนอแนะของคุณ!
ห้องสมุดนี้เผยแพร่ภายใต้ใบอนุญาต MIT
หากคุณมีคำถามใด ๆ โปรดติดต่อเราที่: [email protected] เรายินดีรับฟังความคิดเห็นของคุณเสมอ!