10 KiB
uikit
Shared library for BI next.js projects.
Install
yarn add git+https://git.d.aiengines.ir/bi/uikit.git
Update
yarn upgrade uikit
imports
| مسیر | کاربرد | dependency اضافی |
|---|---|---|
uikit |
utility functions | - |
uikit/utils |
utility functions | - |
uikit/pagination |
pagination | Chakra + React + react-icons |
uikit/layout |
Header | Chakra + React |
uikit/core |
API، BiProvider، Keycloak، Permission | Chakra + React Query + Axios + Keycloak |
uikit/table |
DataTable | Chakra + TanStack Table + Pagination |
utils
import { toFaDigits, toEnDigits, toFaNumber } from "uikit/utils";
toFaDigits(123456);
toEnDigits("۱۲۳۴۵۶");
toFaNumber(123456);
or
import { toFaDigits } from "uikit";
pagination
required dependencies
yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion react-icons
using
import { Pagination, LightPagination, SimplePagination } from "uikit/pagination";
function Page() {
return (
<Pagination
currentPage={1}
totalCount={100}
totalPages={5}
onPageChange={(page) => console.log(page)}
/>
);
}
Header
required dependencies:
yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion
using:
import { Header } from "uikit/layout";
function AppHeader() {
return (
<Header>
<Header.BrandSection>
<Header.Logo src="/logo.png" />
<Header.Brand>
<Header.Title>عنوان سامانه</Header.Title>
<Header.Description>توضیح کوتاه سامانه</Header.Description>
</Header.Brand>
</Header.BrandSection>
<Header.Bi />
</Header>
);
}
استفاده از core
بخش core شامل این موارد است:
- API config
createApiBiProvider- Keycloak
- Permission
- React Query provider
- Chakra provider
Required dependencies:
yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion @tanstack/react-query axios keycloak-js
استفاده از BiProvider
import { BiProvider } from "uikit/core";
export default function App() {
return (
<BiProvider
apiBaseUrl="https://api.example.com"
keycloakClientId="front-client"
permissionClientId="permission-client"
>
<YourApp />
</BiProvider>
);
}
BiProvider به صورت داخلی این کارها را انجام میدهد:
- تنظیم base url برای API
- راهاندازی Keycloak در صورت فعال بودن
- گرفتن permissionها در صورت فعال بودن
- اضافه کردن
ChakraProvider - اضافه کردن
QueryClientProvider - اضافه کردن فونت و theme داخلی
- فعال کردن اختیاری
UpdateChecker
props مربوط به BiProvider
| Prop | توضیح |
|---|---|
apiBaseUrl |
آدرس اصلی API |
keycloakClientId |
client id مربوط به Keycloak |
permissionClientId |
client id مربوط به Permission |
loading |
کامپوننت loading هنگام init شدن Keycloak یا Permission |
updateChecker |
فعال یا غیرفعال کردن بررسی آپدیت |
updateCheckerProps |
props مربوط به UpdateChecker |
keycloakUrl |
آدرس Keycloak |
keycloakRealm |
realm مربوط به Keycloak |
permissionUrl |
آدرس API مربوط به permission |
keycloakEnabled |
فعال یا غیرفعال کردن Keycloak به صورت دستی |
permissionEnabled |
فعال یا غیرفعال کردن Permission به صورت دستی |
مقدارهای پیشفرض BiProvider
keycloakUrl = "https://auth.ibagher.ir";
keycloakRealm = "bi";
permissionUrl = "https://api.d.aiengines.ir/user_api/v1/permissions/list";
updateChecker = false;
نکته: اگر keycloakClientId داده شود، Keycloak فعال میشود. اگر permissionClientId داده شود، Permission فعال میشود.
برای کنترل دستی:
<BiProvider
apiBaseUrl="https://api.example.com"
keycloakEnabled={false}
permissionEnabled={false}
>
<YourApp />
</BiProvider>
UpdateChecker
به صورت پیشفرض updateChecker خاموش است.
برای فعال کردن:
<BiProvider
apiBaseUrl="https://api.example.com"
keycloakClientId="front-client"
permissionClientId="permission-client"
updateChecker
>
<YourApp />
</BiProvider>
اگر updateChecker را فعال میکنی، پروژه باید فایل version تولید کند. معمولاً باید یک اسکریپت مثل write-version.js در root پروژه داشته باشی و در package.json پروژه target، قبل از build اجرا شود.
نمونه:
{
"scripts": {
"prebuild": "node write-version.js",
"build": "next build"
}
}
استفاده از API پایه
import { api, fetcher, configureApi, getApi } from "uikit/core";
اگر از BiProvider استفاده میکنی، معمولاً نیازی نیست دستی configureApi را صدا بزنی، چون BiProvider این کار را انجام میدهد.
نمونه استفاده مستقیم:
import { api } from "uikit/core";
const response = await api.get("/users");
یا:
import { fetcher } from "uikit/core";
const data = await fetcher("/users");
استفاده از createApi
createApi برای ساختن یک API ساده بر پایه React Query استفاده میشود.
import { createApi } from "uikit/core";
export const profileApi = createApi({
key: "profile",
url: "/content/rokn/profiles",
actions: {
update: {
method: "patch",
url: (id) => `/content/rokn/profiles/${id}`,
},
delete: {
method: "delete",
},
generate: {
method: "post",
url: "/content/rokn/generate/profile",
},
updateImages: {
method: "post",
url: (id) => `/content/rokn/profile-update/${id}/images`,
body: ({ formData }) => formData,
},
},
});
گرفتن لیست
const { data, isLoading, error } = profileApi.useGet({
page: 1,
size: 20,
is_confirmed: true,
});
این request ساخته میشود:
GET /content/rokn/profiles?page=1&size=20&is_confirmed=true
اجرای action
const updateProfile = profileApi.useAction("update");
await updateProfile.mutateAsync({
id: 10,
username: "new_username",
});
در این حالت:
PATCH /content/rokn/profiles/10
body:
{
username: "new_username"
}
id به صورت پیشفرض از body حذف میشود، چون برای ساختن URL استفاده شده است.
action با همان URL اصلی
اگر action همان URL اصلی را لازم دارد، نیازی نیست url را دوباره بنویسی.
export const identityGenerateApi = createApi({
key: "identity-generate",
url: "/content/rokn/identity-generate/logs",
actions: {
delete: {
method: "delete",
},
},
});
یعنی:
DELETE /content/rokn/identity-generate/logs
action با FormData
const updateImages = profileApi.useAction("updateImages");
const formData = new FormData();
formData.append("image", file);
await updateImages.mutateAsync({
id: 10,
formData,
});
در تعریف action:
updateImages: {
method: "post",
url: (id) => `/content/rokn/profile-update/${id}/images`,
body: ({ formData }) => formData,
}
body مشخص میکند چه چیزی واقعاً به عنوان body ارسال شود.
استفاده از Keycloak
import {
getKeycloakToken,
loginKeycloak,
logoutKeycloak,
updateKeycloakToken,
} from "uikit/core";
const token = getKeycloakToken();
await updateKeycloakToken(30);
loginKeycloak();
logoutKeycloak({
redirectUri: window.location.origin,
});
استفاده از Permission
import { Can, usePermission } from "uikit/core";
function Page() {
const { can, cannot, permissions } = usePermission();
return (
<>
{can("users:list") && <div>لیست کاربران</div>}
<Can perm="users:create" fallback={null}>
<button>ایجاد کاربر</button>
</Can>
</>
);
}
نکته: prop کامپوننت Can برابر perm است.
<Can perm="users:list">
<UsersList />
</Can>
استفاده از DataTable
DataTable داخل مسیر uikit/table قرار دارد.
dependencyهای لازم:
yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion @tanstack/react-table react-icons
استفاده:
import { DataTable } from "uikit/table";
function UsersTable({ data, columns }) {
return (
<DataTable
data={data}
columns={columns}
page={1}
size={20}
pagination={{
totalCount: 100,
totalPages: 5,
}}
onPageChange={(page) => console.log(page)}
getRowId={(row) => String(row.id)}
enableSelection
showIndex
>
<DataTable.Topbar>
<DataTable.Title>لیست کاربران</DataTable.Title>
<DataTable.Spacer />
<DataTable.Actions>
<DataTable.SelectAll />
</DataTable.Actions>
</DataTable.Topbar>
<DataTable.Content>
<DataTable.Table />
<DataTable.Pagination />
</DataTable.Content>
</DataTable>
);
}