diff --git a/docs/en/framework/ui/react/admin-console.md b/docs/en/framework/ui/react/admin-console.md new file mode 100644 index 0000000000..41e22a9fd5 --- /dev/null +++ b/docs/en/framework/ui/react/admin-console.md @@ -0,0 +1,133 @@ +```json +//[doc-seo] +{ + "Description": "Learn how the ABP Admin Console works with React UI applications and how it is hosted under /admin-console." +} +``` + +# Admin Console + +The **ABP Admin Console** is the React-based administration UI for ABP applications. It provides management pages for ABP modules and is available in React UI solutions created with ABP Studio v3.0+ or `abp new --modern --ui-framework react`. + +The Admin Console is delivered as the `Volo.Abp.AdminConsole` NuGet package for layered and single-layer solutions. In microservice solutions, the template also includes a standalone `apps/react-admin-console/` React app. + +## What It Provides + +The Admin Console contains administration pages for the ABP modules included in the host application. Module pages are activated based on the backend services available in the host, so a solution only shows pages for modules it actually has. + +The built-in module areas include: + +| Module | Notes | +| --- | --- | +| Identity Pro | User, role, claim, and organization unit management when Identity services are available. | +| Account Pro | Account management pages and account-related flows. | +| OpenIddict | Application and scope management when OpenIddict services are available. | +| Audit Logging UI | Optional. Visible when Audit Logging services are available. | +| AI Management | Optional. Visible when AI Management services are available. | +| Text Template Management | Optional. Visible when Text Template Management services are available. | + +Other module pages, such as Setting Management, SaaS, GDPR, or customization pages, can also be available depending on the solution and installed modules. + +## Hosting Model + +The Admin Console is served under: + +```text +/admin-console/* +``` + +API endpoints used by the Admin Console are served under: + +```text +/admin-console/api/* +``` + +The `Volo.Abp.AdminConsole` package embeds the built React SPA under `wwwroot/admin-console/` and registers it with ABP's Virtual File System. `AdminConsoleSpaMiddleware` then serves static assets and falls back to `index.html` for client-side routes. + +The middleware deliberately lets `/admin-console/api/*` requests pass through to MVC controllers. + +## Layered and Single-Layer Templates + +For layered and single-layer modern templates: + +- The developer-owned React app is in the `react/` folder. +- The Admin Console UI is embedded in the backend through the `Volo.Abp.AdminConsole` NuGet package. +- There is no separate `react-admin-console/` source folder in the generated solution. +- The backend host serves Admin Console pages under `/admin-console/*`. + +Example URL: + +```text +https://localhost:44300/admin-console/ +``` + +The main React app links to the Admin Console through `getAdminConsoleUrl()`. + +## Microservice Template + +For the microservice modern template: + +- The main React app is in `apps/react/`. +- The Admin Console app is in `apps/react-admin-console/`. +- Both are served through the Web Gateway. +- The Admin Console has its own OpenIddict client, normally `_AdminConsole`. + +The main React app uses `adminConsoleUrl` from `dynamic-env.json` to open the Admin Console origin and `/admin-console` base path. + +## Module Discovery + +The Admin Console calls: + +```text +GET /admin-console/api/modules +``` + +The backend checks for module application service contracts and returns which module areas are available. The discovery keys include: + +| Key | Backend service check | +| --- | --- | +| `identity` | `Volo.Abp.Identity.IIdentityUserAppService` | +| `saas` | `Volo.Saas.Host.ITenantAppService` | +| `auditLogging` | `Volo.Abp.AuditLogging.IAuditLogsAppService` | +| `gdpr` | `Volo.Abp.Gdpr.IGdprRequestAppService` | +| `openIddict` | `Volo.Abp.OpenIddict.Applications.IApplicationAppService` | +| `textTemplateManagement` | `Volo.Abp.TextTemplateManagement.TextTemplates.ITemplateDefinitionAppService` | +| `aiManagement` | AI Management service contracts, with a legacy AI engine fallback. | + +`settingManagement` is always returned as available by the discovery endpoint, while access to pages is still controlled by permissions. + +## Configuration Endpoint + +The Admin Console also uses: + +```text +GET /admin-console/api/config +``` + +This endpoint provides Admin Console runtime settings such as authority, client ID, scopes, application name, customization options, and localization language configuration. + +Host applications can configure Admin Console options from the `AdminConsole` configuration section. + +## Permissions + +Admin Console routes still require permissions. For example: + +- Identity pages use `AbpIdentity.*` permissions. +- OpenIddict pages use `OpenIddictPro.Application` and `OpenIddictPro.Scope`. +- Audit Logging uses `AuditLogging.AuditLogs`. +- Text Template Management uses `TextTemplateManagement.*`. +- AI Management uses `AIManagement.*`. + +The main React app's Admin Console menu item only requires authentication. The Admin Console performs detailed permission checks for its own pages. + +## Customization + +The developer-owned React app is intended for application-specific pages. The Admin Console is an ABP-managed administration surface and should normally be updated by updating ABP packages. + +For layered and single-layer hosts, the package supports host-side options such as application name, localization languages, and theme override CSS path. For larger UI changes, prefer building your own pages in the main React app or extending the backend modules through supported ABP extension points. + +## See Also + +- [React UI](./index.md) +- [Environment Variables](./environment-variables.md) +- [Permission Management](./permission-management.md) diff --git a/docs/en/framework/ui/react/components/index.md b/docs/en/framework/ui/react/components/index.md new file mode 100644 index 0000000000..856759acd5 --- /dev/null +++ b/docs/en/framework/ui/react/components/index.md @@ -0,0 +1,184 @@ +```json +//[doc-seo] +{ + "Description": "Learn about the component architecture and UI libraries used by ABP React UI applications." +} +``` + +# Components + +ABP React UI templates use a source-owned component architecture. The generated app includes shadcn/ui-style primitives, layout components, feature components, route pages, and shared infrastructure under `src/lib/`. + +The goal is to give you a working React application that you can customize without replacing framework-owned black boxes. + +## Component Structure + +The main React app is organized like this: + +```text +src/ +├── components/ +│ ├── layout/ +│ ├── ui/ +│ └── identity/ +├── lib/ +│ ├── api/ +│ ├── auth/ +│ ├── i18n/ +│ ├── routing/ +│ └── theme/ +├── locales/ +├── pages/ +└── routes/ +``` + +The exact folders can vary by selected template options and modules. + +## UI Stack + +The React template uses: + +| Library | Purpose | +| --- | --- | +| React | UI rendering. | +| Vite | Build tool and development server. | +| TanStack Router | Client-side routing. | +| TanStack Query | Server state, queries, mutations, and cache invalidation. | +| shadcn/ui-style components | Source-owned UI primitives built on Radix UI and Tailwind CSS. | +| Radix UI | Accessible low-level UI primitives. | +| Tailwind CSS | Utility-first styling and design tokens. | +| React Hook Form | Form state management. | +| Zod | Form and DTO validation schemas. | +| Axios | HTTP client. | +| i18next / react-i18next | Localization. | +| Zustand | Lightweight client state when needed. | +| Sonner | Toast notifications. | +| Lucide React | Icons. | + +## `components/ui` + +`src/components/ui/` contains reusable UI primitives. These components are copied into your project and can be edited directly. + +Common components include: + +- `Button` +- `Input` +- `Label` +- `Table` +- `Dialog` +- `DropdownMenu` +- `Select` +- `Card` +- `Tabs` +- `Badge` +- `DatePicker` +- `ConfirmDialog` + +Use these primitives to build application pages and feature components. + +```tsx +import { Button } from '@/components/ui/button' +import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' + +export function ReportCard() { + return ( + + + Reports + + + + + + ) +} +``` + +## Layout Components + +Layout components are under `src/components/layout/`. + +Important components include: + +- `RootLayout`: root shell used by TanStack Router. +- `Header`: top bar, login button, theme toggle, and user menu. +- `Sidebar`: route-config-driven navigation menu. +- `UserMenu`: account-related dropdown menu. + +The sidebar reads `src/lib/routing/route-config.ts`, checks authentication and permissions, and renders internal or external links. + +## Feature Components + +Feature-specific components should live near the feature that owns them. For example, Identity-specific layout components live under `src/components/identity/`, while Books-specific UI is implemented in `src/pages/books/BooksPage.tsx` in the sample template. + +As a rule: + +- Put generic, reusable primitives in `components/ui`. +- Put application layout in `components/layout`. +- Put feature-specific components under `components/` or next to the page when they are only used by one page. + +## Pages + +Route pages live under `src/pages/`. A page usually combines: + +- UI primitives from `components/ui`. +- API functions from `src/lib/api`. +- Server state from TanStack Query. +- Form state from React Hook Form. +- Validation schemas from Zod. +- Permissions from `usePermissions()`. +- Localized strings from `useTranslation()`. + +The Books page is the best full CRUD reference when the sample CRUD option is selected. + +## Forms + +Forms use React Hook Form and Zod: + +```tsx +const productSchema = z.object({ + name: z.string().min(1, 'Required'), + price: z.number().min(0), +}) + +type ProductFormData = z.infer + +const form = useForm({ + resolver: zodResolver(productSchema), + defaultValues: { + name: '', + price: 0, + }, +}) +``` + +This keeps runtime validation and TypeScript types close to each other. + +## Routing Components + +Routes are configured in `src/routes/router.tsx` with TanStack Router. Use: + +- `authGuard` for authenticated pages. +- `createPermissionGuard('Permission.Name')` for permission-protected pages. +- `RootLayout` and nested layouts for shared page structure. + +Menu entries are configured separately in `src/lib/routing/route-config.ts`, so route registration and navigation display can evolve independently. + +## API Components and Hooks + +API functions live under `src/lib/api/` and use the shared `api` Axios instance. Components normally consume these functions through TanStack Query: + +```tsx +const usersQuery = useQuery({ + queryKey: ['app', 'users', queryParams], + queryFn: () => getAppUsers(queryParams), +}) +``` + +This keeps HTTP details out of rendering components and gives you caching, loading states, refetching, and mutation invalidation. + +## See Also + +- [Customization](../customization.md) +- [HTTP Requests](../http-requests.md) +- [Unit Testing](../unit-testing.md) diff --git a/docs/en/framework/ui/react/customization.md b/docs/en/framework/ui/react/customization.md new file mode 100644 index 0000000000..3e64018dab --- /dev/null +++ b/docs/en/framework/ui/react/customization.md @@ -0,0 +1,208 @@ +```json +//[doc-seo] +{ + "Description": "Learn how to customize ABP React UI applications, including pages, themes, sidebar navigation, and the user menu." +} +``` + +# Customization + +The React app generated by ABP is fully owned by your solution. All source code is available, so you can change pages, components, routes, themes, menus, API calls, and layout behavior just like in any other React application. + +This page focuses on the main developer-owned React app. The same general approach applies to the public-web React app if your solution includes one. The Admin Console is an ABP-managed administration surface; see [Admin Console](./admin-console.md) for details. + +## General Customization + +Application pages live under `src/pages/`. The template includes practical references: + +- **Users page**: a simple page that lists users and links to the Admin Console for full user and role management. +- **Books page**: a full CRUD sample when the sample CRUD option is selected during solution creation. It demonstrates TanStack Query, forms, Zod validation, dialogs, tables, permissions, and toast notifications. + +Shared UI and infrastructure live under: + +```text +src/ +├── components/ +│ ├── layout/ +│ └── ui/ +├── lib/ +│ ├── api/ +│ ├── auth/ +│ ├── i18n/ +│ ├── routing/ +│ └── theme/ +└── pages/ +``` + +## Adding a Page + +Create a page under `src/pages/`: + +```tsx +export function ReportsPage() { + return ( +
+

Reports

+
+ ) +} +``` + +Register it with TanStack Router in `src/routes/router.tsx`: + +```tsx +const reportsRoute = createRoute({ + getParentRoute: () => rootRoute, + path: '/reports', + component: ReportsPage, + beforeLoad: createPermissionGuard('MyProjectName.Reports'), +}) + +const routeTree = rootRoute.addChildren([ + indexRoute, + reportsRoute, +]) +``` + +Use `authGuard` for pages that only require authentication and `createPermissionGuard` for pages that require a permission. + +## Theming + +The React template uses **shadcn/ui**-style components, Radix UI primitives, Tailwind CSS, and CSS variables. + +Theme tokens are defined in `src/styles/globals.css`: + +```css +:root { + --background: oklch(0.978 0.003 264); + --foreground: oklch(0.205 0.008 264); + --primary: oklch(0.48 0.10 278); + --radius: 0.5rem; +} + +.dark { + --background: oklch(0.16 0.004 264); + --foreground: oklch(0.92 0.005 264); + --primary: oklch(0.62 0.12 278); +} +``` + +ABP Studio's modern wizard can generate different shadcn theme color presets and light/dark/system theme behavior. + +## Changing Theme Colors + +To make a quick theme change, edit the CSS variables in `src/styles/globals.css`: + +```css +:root { + --primary: oklch(0.623 0.188 259.6); + --primary-foreground: oklch(1 0 0); +} +``` + +Because the generated shadcn/ui components consume these variables through Tailwind tokens, the change applies across buttons, links, active sidebar entries, focus rings, and other components that use the primary color. + +## Theme Mode Switcher + +Theme mode is handled by `src/lib/theme/ThemeProvider.tsx`. It supports: + +- `light` +- `dark` +- `system` + +The header cycles through the allowed modes: + +```tsx +const THEME_CYCLE: Theme[] = ['light', 'dark', 'system'] + +function ThemeToggle() { + const { theme, resolvedTheme, setTheme } = useTheme() + + function cycleTheme() { + const currentIndex = THEME_CYCLE.indexOf(theme) + const nextIndex = currentIndex < 0 ? 0 : (currentIndex + 1) % THEME_CYCLE.length + setTheme(THEME_CYCLE[nextIndex]) + } + + return +} +``` + +To remove the switcher or replace it with a dropdown, edit `src/components/layout/Header.tsx`. + +## Modifying the Sidebar Menu + +Sidebar navigation is defined in `src/lib/routing/route-config.ts`. + +Add a menu item: + +```ts +import { BarChart3 } from 'lucide-react' + +export const routeConfig: RouteConfigItem[] = [ + { + path: '/reports', + nameKey: 'Menu:Reports', + icon: BarChart3, + order: 10, + requiredPolicy: 'MyProjectName.Reports', + }, +] +``` + +Then add the localization key to `src/locales/en.json`: + +```json +{ + "Menu:Reports": "Reports" +} +``` + +Use these properties depending on the menu item: + +| Property | Use | +| --- | --- | +| `path` | Internal route path or logical path for an external item. | +| `nameKey` | Localization key shown in the sidebar. | +| `icon` | Optional Lucide icon. | +| `order` | Sorting order. | +| `requiredPolicy` | Hide the item unless the permission is granted. | +| `requiresAuth` | Hide the item unless the user is authenticated. | +| `externalHref` | Open an external URL or another app, such as the Admin Console. | +| `children` | Add nested sidebar items. | + +## Sidebar vs User Menu + +Use the **sidebar navigation** for application pages and module entry points. + +Use the **user menu** for account-specific actions, profile links, sessions, security logs, linked accounts, and logout. The user menu is implemented in `src/components/layout/UserMenu.tsx`. + +Example user menu item: + +```tsx + + + + {t('MyAccount::Preferences')} + + +``` + +## Customizing UI Components + +shadcn/ui components are copied into your project under `src/components/ui/`. They are not black-box components from a package. You can edit them directly. + +For example: + +- Change button variants in `src/components/ui/button.tsx`. +- Change dialog structure in `src/components/ui/dialog.tsx`. +- Add a new reusable component under `src/components/ui/`. +- Add feature-specific components under `src/components//`. + +Keep generic primitives in `components/ui` and business-specific components close to the feature or page that owns them. + +## See Also + +- [Components](./components/index.md) +- [Permission Management](./permission-management.md) +- [Admin Console](./admin-console.md)