@jcoder-stack/registry 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,29 +1,29 @@
1
1
  # @jcoder-stack/registry
2
2
 
3
- 认证外壳的 copy-in 源,工厂化到极简:**`auth.config.ts` 是你唯一要看的文件**——一句 `createAbpAuthRuntime(process.env, {…覆盖项})`,默认即现行为,每个覆盖项(cookie 名/寿命、策略启停、登出回跳、身份解析器…)都带默认值,取消注释即生效。其余是薄接线:`runtime.ts`(进程单例)、`server-fns.ts` / `middleware.ts`(TanStack 接线,编译约束必留 copy-in)、`index.ts`(barrel)。
3
+ The copy-in source for the auth shell, factored down to a minimum: **`auth.config.ts` is the only file you need to look at** — a single `createAbpAuthRuntime(process.env, {…overrides})` call, where the defaults are the current behavior and every override (cookie names/lifetimes, strategy toggles, post-logout redirect, identity resolver…) ships with a default; uncomment to activate. The rest is thin wiring: `runtime.ts` (a process singleton), `server-fns.ts` / `middleware.ts` (TanStack wiring that must stay copy-in for compile-time reasons), and `index.ts` (the barrel).
4
4
 
5
- 装配与机制全部下沉包:ABP auth 运行时工厂 `createAbpAuthRuntime` 与登录/回调/登出/文化/租户 handler → `@jcoder-stack/abp-react/proxy`;路由守卫 `requireAuth`/`requirePermission` → `@jcoder-stack/abp-react/router`(TanStack Router beforeLoad,经 `@/auth` barrel 重导出);ABP 代理调用、身份读取、returnUrl/culture 纯函数 → `@jcoder-stack/abp-react/proxy` / `@jcoder-stack/abp-react/auth`。
5
+ All assembly and mechanics live down in the packages: the ABP auth runtime factory `createAbpAuthRuntime` and the login/callback/logout/culture/tenant handlers → `@jcoder-stack/abp-react/proxy`; the route guards `requireAuth`/`requirePermission` → `@jcoder-stack/abp-react/router` (TanStack Router beforeLoad, re-exported through the `@/auth` barrel); ABP proxy calls, identity reads, and the returnUrl/culture pure functions → `@jcoder-stack/abp-react/proxy` / `@jcoder-stack/abp-react/auth`.
6
6
 
7
- `jc-abp add auth` manifest 落位到应用 `src/`;属 ABP React Start 框架,总览见仓库根 README
7
+ `jc-abp add auth` distributes it into the app's `src/` per the manifest. Part of the ABP React Start framework — see the repository root README for the big picture.
8
8
 
9
9
  ## UI blocks
10
10
 
11
- `ui/blocks/` 下是可用官方 shadcn CLI 安装的块,产物在 `public/r/`:
11
+ `ui/blocks/` holds blocks installable with the official shadcn CLI; the built artifacts live in `public/r/`:
12
12
 
13
- | | 内容 |
13
+ | Block | Contents |
14
14
  | --- | --- |
15
- | `abp-layout` | 侧栏布局(AppSidebar / SiteHeader / 面包屑 / 语言与主题切换 / 品牌标识) |
16
- | `abp-login` | 密码登录卡片,含 OIDC 入口 |
17
- | `app-shell` | 应用壳胶水:`_layout`/`_authed`/首页/login 路由 + `abp-fetch.ts` + 起点 `menu.tsx` |
18
- | `data-table` | 通用服务端分页/排序/搜索表格 |
19
- | `combobox` | 单选/多选 combobox(本地过滤或防抖远程 loadOptions |
20
- | `date-picker` | 单日期 / 日期区间 / 日期时间选择器 |
21
- | `form` | 表单壳 + 字段组件 + 服务端字段错误映射 |
22
- | `abp-crud` | ABP CRUD 协议(`createCrudService` / `AbpTableSource`)与共享件 |
23
- | `abp-table` | `useAbpTable`——表格 + 筛选面板 + 批量操作 |
24
- | `abp-sheet` | `useAbpSheet`——增删改抽屉 |
25
- | `tree` | 通用树形块(展开收起 / 勾选,级联策略留给消费方) |
26
- | `abp-permission-sheet` | 权限树 Sheet(组=Accordion,组内 Tree |
27
- | `admin-pages` | users / roles / tenants / settings / profile 五个管理页 |
15
+ | `abp-layout` | The sidebar layout (AppSidebar / SiteHeader / breadcrumbs / locale & theme switchers / brand mark) |
16
+ | `abp-login` | The password sign-in card, with an OIDC entry point |
17
+ | `app-shell` | App-shell glue: the `_layout`/`_authed`/home/login routes + `abp-fetch.ts` + the starting `menu.tsx` |
18
+ | `data-table` | A general server-side paging/sorting/search table |
19
+ | `combobox` | Single/multi-select combobox (local filtering or debounced remote loadOptions) |
20
+ | `date-picker` | Single date / date range / date-time pickers |
21
+ | `form` | The form shell + field components + server-side field error mapping |
22
+ | `abp-crud` | The ABP CRUD protocol (`createCrudService` / `AbpTableSource`) and shared pieces |
23
+ | `abp-table` | `useAbpTable` — table + filter panel + bulk actions |
24
+ | `abp-sheet` | `useAbpSheet` — the create/edit/delete drawer |
25
+ | `tree` | A general tree block (expand/collapse, checking; cascade policy left to the consumer) |
26
+ | `abp-permission-sheet` | The permission tree sheet (groups as Accordion, a Tree per group) |
27
+ | `admin-pages` | The five admin pages: users / roles / tenants / settings / profile |
28
28
 
29
- 装法、依赖顺序与各块的前置条件见 [`docs/guides/install-blocks.md`](../docs/guides/install-blocks.md)。源码改动后用 `bun run build:registry` 重新生成产物。
29
+ Install steps, dependency order, and each block's prerequisites are in [`docs/guides/install-blocks.md`](../docs/guides/install-blocks.md). After changing block sources, rebuild the artifacts with `bun run build:registry`.
@@ -7,16 +7,19 @@ declare global {
7
7
  readonly env: ImportMetaEnv;
8
8
  }
9
9
 
10
+ // 与 @jcoder-stack/abp-react/proxy 的 resolveAbpAuthEnv 读取的变量一一对应。
10
11
  namespace NodeJS {
11
12
  interface ProcessEnv {
12
- readonly OIDC_ISSUER: string;
13
- readonly OIDC_CLIENT_ID: string;
14
- readonly OIDC_CLIENT_SECRET?: string;
15
- readonly OIDC_SCOPE?: string;
16
- readonly API_BASE_URL: string;
13
+ readonly AUTH_ISSUER: string;
14
+ readonly AUTH_CLIENT_ID: string;
15
+ readonly AUTH_CLIENT_SECRET?: string;
16
+ readonly AUTH_SCOPE?: string;
17
+ readonly AUTH_REDIRECT_URI: string;
18
+ readonly AUTH_POST_LOGOUT_REDIRECT_URI?: string;
17
19
  readonly AUTH_SESSION_SECRET: string;
18
- readonly OIDC_REDIRECT_URI: string;
19
- readonly OIDC_POST_LOGOUT_REDIRECT_URI?: string;
20
+ readonly AUTH_ABP_BASE_URL: string;
21
+ readonly AUTH_DEBUG?: string;
22
+ readonly AUTH_EXTRA_CA_FILE?: string;
20
23
  }
21
24
  }
22
25
  }
@@ -6,7 +6,7 @@
6
6
  # "'client_id' is invalid" → 这个 client 不存在,换名字再试
7
7
  # "'redirect_uri' is not valid" → client 对了,回调没登记,去后端补
8
8
  # 302 到 /Account/Login → 两个都对
9
- AUTH_ISSUER=https://localhost:44300
9
+ AUTH_ISSUER=https://localhost:44316
10
10
  AUTH_CLIENT_ID=WebApp
11
11
  # 机密客户端才需要:
12
12
  # AUTH_CLIENT_SECRET=
@@ -18,13 +18,11 @@ AUTH_REDIRECT_URI=http://localhost:3000/api/auth/callback
18
18
  AUTH_POST_LOGOUT_REDIRECT_URI=http://localhost:3000/
19
19
  # ≥32 字符随机串:openssl rand -base64 32
20
20
  AUTH_SESSION_SECRET=
21
- # 后端用自签证书(本地 ABP 默认如此)时,服务端到它的这一跳会失败:页面 500 且只写着 "fetch failed",
22
- # gen 同理。原因是 Node 只认自己内置的 CA 列表,不读系统钥匙串——证书 dev-certs --trust 过、浏览器和
23
- # curl 都放行,Node 依然拒。导出证书后二选一:
21
+ # 后端用自签证书(本地 ABP 默认如此)时,服务端到它的这一跳会被拒——Node 只认自己内置的 CA 列表,
22
+ # 不读系统钥匙串,证书 dev-certs --trust 过、浏览器和 curl 都放行也没用。导出证书后填到下面这行,
23
+ # dev 与 gen 就都信任它(只多信这一张,其余照常校验;需要 Node >= 22.15):
24
24
  # dotnet dev-certs https --export-path ~/.aspnet-dev.crt --format PEM
25
- # NODE_EXTRA_CA_CERTS=~/.aspnet-dev.crt bun run dev ← 只多信这一张,其余照常校验。Node 在启动时读它,
26
- # 写进本文件不生效,必须放在命令上或 shell profile 里
27
- # NODE_TLS_REJECT_UNAUTHORIZED=0 ← 写进本文件有效,但对所有主机关掉校验,只可用于开发
28
- AUTH_ABP_BASE_URL=https://localhost:44300
25
+ # AUTH_EXTRA_CA_FILE=~/.aspnet-dev.crt
26
+ AUTH_ABP_BASE_URL=https://localhost:44316
29
27
  # 开发排障:置 true 打开 auth 全链路 debug 日志(永不输出 token 原文)
30
28
  AUTH_DEBUG=false
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@jcoder-stack/registry",
3
- "description": "认证外壳的 copy-in 源:登录/回调/登出 handler、callAbp 代理、路由守卫、TanStack 接线",
4
- "version": "0.1.1",
3
+ "description": "Copy-in sources for the auth shell and shadcn blocks: login/callback/logout handlers, the callAbp proxy, route guards, and TanStack wiring",
4
+ "version": "0.1.2",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "auth",
@@ -39,7 +39,7 @@
39
39
  },
40
40
  {
41
41
  "path": "ui/blocks/app-shell/routes/_layout/shell-messages.json",
42
- "content": "{\n \"en\": {\n \"\": {\n \"Shell:Loading\": \"Loading…\",\n \"Shell:Forbidden\": \"403 · Forbidden\",\n \"Shell:ForbiddenHint\": \"You're signed in, but you don't have permission to view this page.\",\n \"Shell:ForbiddenBody\": \"You don't have permission to access this resource.\",\n \"Shell:BackHome\": \"Back to home\",\n \"Shell:Unauthorized\": \"401 · Unauthorized\",\n \"Shell:SessionExpired\": \"Your session has expired. Please sign in again.\",\n \"Shell:SignIn\": \"Sign in\",\n \"Shell:NotFound\": \"404 · Page not found\",\n \"Shell:UnexpectedError\": \"Something went wrong\",\n \"Shell:UnknownError\": \"Unknown error\",\n \"Home:Welcome\": \"Welcome\",\n \"Home:WelcomeBack\": \"Welcome back, {0}\",\n \"Home:Tagline\": \"A modern React admin scaffold for your ABP backend — authentication, permissions, multi-tenancy, and localization, all wired up out of the box.\",\n \"Home:SignIn\": \"Sign in to get started\",\n \"Home:FeatureAuthTitle\": \"Identity & Permissions\",\n \"Home:FeatureAuthDesc\": \"OpenIddict sign-in, role management, and fine-grained permission checks kept consistent from backend to UI.\",\n \"Home:FeatureTenantTitle\": \"Multi-tenancy\",\n \"Home:FeatureTenantDesc\": \"Per-tenant data and settings isolation, with tenant switching available from the top bar.\",\n \"Home:FeatureI18nTitle\": \"Localization\",\n \"Home:FeatureI18nDesc\": \"Text and culture synced from the ABP backend, so every screen stays free of hardcoded copy.\",\n \"Home:EditHint\": \"Edit src/routes/_layout/index.tsx to make this home page your own.\",\n \"Showcase:Heading\": \"Built-in components\",\n \"Showcase:Intro\": \"Core interactive components the scaffold ships with. Each section below is a live, clickable example running on local sample data — no backend required.\",\n \"Showcase:DataTableDesc\": \"A server-paginated table primitive: sortable headers, debounced search, localized empty state, and pagination. Click a header to sort, type to search, and page through the rows.\",\n \"Showcase:ColBlock\": \"Block\",\n \"Showcase:ColFiles\": \"Files\",\n \"Showcase:ColStatus\": \"Status\",\n \"Showcase:ColBookName\": \"Title\",\n \"Showcase:ColBookAuthor\": \"Author\",\n \"Showcase:ColBookPrice\": \"Price\",\n \"Showcase:StatusStable\": \"Stable\",\n \"Showcase:StatusBeta\": \"Preview\",\n \"Showcase:SearchBlocks\": \"Search blocks…\",\n \"Showcase:BulkExport\": \"Export {0}\",\n \"Showcase:AbpTableDesc\": \"Everything data-table gives you, wired to an ABP backend: list query, create/edit/delete drawer forms, permission-gated actions, and optimistic refresh — you describe the service, the page comes with it. The table on the right is the real thing; try creating and deleting a row.\",\n \"Showcase:AbpTableCrud\": \"Create/edit/delete drawer forms that refresh the list on success.\",\n \"Showcase:AbpTablePermission\": \"Every action button gated by its ABP permission policy.\",\n \"Showcase:AbpTableConcurrency\": \"Optimistic concurrency: the concurrencyStamp is round-tripped end to end.\",\n \"Showcase:FormDesc\": \"A drawer form container plus the required-field trio: the asterisk mark, inline errors, and blur/submit validation — sharing one error channel with server-side field errors.\",\n \"Showcase:FormOpen\": \"New item\",\n \"Showcase:FormNameLabel\": \"Name\",\n \"Showcase:FormEmailLabel\": \"Email\",\n \"Showcase:FormSuccess\": \"Validated and submitted: {0}\",\n \"Showcase:TreeDesc\": \"A controlled tree: expand/collapse and tri-state checkboxes (including indeterminate). Cascade behavior is composed from the pure tree-helpers functions. Check a parent to try it.\",\n \"Showcase:TreeIdentity\": \"Identity management\",\n \"Showcase:TreeUsers\": \"Users\",\n \"Showcase:TreeRoles\": \"Roles\",\n \"Showcase:PermView\": \"View\",\n \"Showcase:PermEdit\": \"Edit\",\n \"Showcase:TreeSelected\": \"{0} selected\",\n \"Showcase:ComboboxDesc\": \"Single- and multi-select dropdowns: local filtering or remote loadOptions (debounced), with the selected label rendered back automatically. This is the local-filter mode — type to filter.\",\n \"Showcase:ComboboxSingle\": \"Single select\",\n \"Showcase:ComboboxMulti\": \"Multi select\",\n \"Showcase:OptAdmin\": \"Administrator\",\n \"Showcase:OptEditor\": \"Editor\",\n \"Showcase:OptViewer\": \"Viewer\",\n \"Showcase:OptAuditor\": \"Auditor\",\n \"Showcase:OptDeveloper\": \"Developer\",\n \"Showcase:OptOperator\": \"Operator\",\n \"Showcase:DatePickerDesc\": \"Popover-based date pickers built on react-day-picker: a single date, a from–to range, and a date + time combo, all formatted via date-fns and locale-aware. Click any field to open the calendar.\",\n \"Showcase:DatePickerSingle\": \"Pick a date\",\n \"Showcase:DatePickerRange\": \"Pick a range\",\n \"Showcase:DatePickerDateTime\": \"Pick date & time\",\n \"Showcase:DataTableTitle\": \"Server-side tables, out of the box\",\n \"Showcase:DataTableB1\": \"manualPagination / manualSorting semantics\",\n \"Showcase:DataTableB2\": \"Debounced search, submit on Enter\",\n \"Showcase:DataTableB3\": \"Localized empty state and pagination\",\n \"Showcase:FormTitle\": \"Forms, one error channel\",\n \"Showcase:FormB1\": \"Required mark + aria-required\",\n \"Showcase:FormB2\": \"Validates on blur and on submit\",\n \"Showcase:FormB3\": \"Server field errors on the same channel\",\n \"Showcase:TreeTitle\": \"Trees and cascading, composable\",\n \"Showcase:TreeB1\": \"Tri-state checkboxes, including indeterminate\",\n \"Showcase:TreeB2\": \"Pure helpers: collectSubtreeIds / deriveIndeterminate\",\n \"Showcase:TreeB3\": \"Zero business coupling — you own the policy\",\n \"Showcase:ComboboxTitle\": \"Comboboxes, local or remote\",\n \"Showcase:ComboboxB1\": \"Single and multi select\",\n \"Showcase:ComboboxB2\": \"Local filter or debounced remote loadOptions\",\n \"Showcase:ComboboxB3\": \"Selected labels rendered back automatically\",\n \"Showcase:DatePickerTitle\": \"Date pickers, locale-aware\",\n \"Showcase:DatePickerB1\": \"Single, range, and date + time variants\",\n \"Showcase:DatePickerB2\": \"date-fns formatting synced to the current culture\",\n \"Showcase:DatePickerB3\": \"DateField binds straight to an ISO date string in forms\",\n \"Showcase:AbpTableTitle\": \"ABP CRUD, wired by descriptor\",\n \"Landing:NavFeatures\": \"Features\",\n \"Landing:NavComponents\": \"Components\",\n \"Landing:NavConsole\": \"Open console\",\n \"Landing:NavSignIn\": \"Sign in\",\n \"Landing:HeroEyebrow\": \"Pure React · ABP\",\n \"Landing:HeroTitleLead\": \"A modern React admin for your\",\n \"Landing:HeroTitleAccent\": \"ABP backend.\",\n \"Landing:HeroSubtitle\": \"A hand-built, pure-React framework for your ABP backend — authentication, permissions, multi-tenancy, and localization out of the box, with data-table, form, tree, and combobox components ready to use.\",\n \"Landing:HeroWelcomeBack\": \"Welcome back, {0}. Your console is one click away.\",\n \"Landing:HeroPrimary\": \"Get started\",\n \"Landing:HeroSecondary\": \"Explore components\",\n \"Landing:InstallHint\": \"Scaffold a project with one command\",\n \"Landing:Copy\": \"Copy\",\n \"Landing:Copied\": \"Copied\",\n \"Landing:FeaturesEyebrow\": \"Features\",\n \"Landing:FeaturesTitle\": \"Everything an admin needs, already wired up\",\n \"Landing:FeatureAuthTitle\": \"OIDC sign-in\",\n \"Landing:FeatureAuthDesc\": \"Wired to OpenIddict out of the box, and switchable to another identity provider like Keycloak.\",\n \"Landing:FeaturePermTitle\": \"Fine-grained permissions\",\n \"Landing:FeaturePermDesc\": \"Permission checks kept consistent from backend to UI — gate any action by its policy.\",\n \"Landing:FeatureI18nTitle\": \"Front-and-back localization\",\n \"Landing:FeatureI18nDesc\": \"Reuses your ABP backend's localization resources, so front and back share one set of translations; switch culture and it applies instantly.\",\n \"Landing:FeatureApiTitle\": \"Type-safe API\",\n \"Landing:FeatureApiDesc\": \"Orval generates endpoints and models from your ABP Swagger — regenerate with jc-abp gen, and every call stays type-safe.\",\n \"Landing:FeatureAdminTitle\": \"Admin pages, ready\",\n \"Landing:FeatureAdminDesc\": \"Users, roles, tenants, settings, and profile CRUD pages already built on the bundled components.\",\n \"Landing:FeatureTenantTitle\": \"Multi-tenancy\",\n \"Landing:FeatureTenantDesc\": \"Per-tenant data and settings isolation, with tenant switching from the top bar.\",\n \"Landing:InActionEyebrow\": \"In action\",\n \"Landing:InActionTitle\": \"Built-in components, live\",\n \"Landing:UsageEyebrow\": \"Usage\",\n \"Landing:UsageTitle\": \"Wire it in, like this\",\n \"Landing:UsageI18nTitle\": \"Localization · L()\",\n \"Landing:UsageI18nDesc\": \"One L reads every translation shared with the backend, namespaced Resource::Key, with argument interpolation.\",\n \"Landing:UsageI18nB1\": \"useLocalization() gives you L; keys are Resource::Key\",\n \"Landing:UsageI18nB2\": \"Argument interpolation supported (page, total, …)\",\n \"Landing:UsageI18nB3\": \"useCulture() reads the current culture; switch it from the top bar\",\n \"Landing:UsagePermTitle\": \"Permissions · three ways\",\n \"Landing:UsagePermDesc\": \"One policy set, consistent front to back — pick route, imperative, or declarative.\",\n \"Landing:UsagePermB1\": \"requirePermission() guards a route in beforeLoad\",\n \"Landing:UsagePermB2\": \"usePermissionChecker() — imperative can / can.any / can.all\",\n \"Landing:UsagePermB3\": \"PermissionGuard renders children only when granted\",\n \"Landing:UsageCrudTitle\": \"abp-table · full CRUD\",\n \"Landing:UsageCrudDesc\": \"Declare the list/create/update/delete calls and a policy once; useAbpTable / useAbpSheet wire the rest, and t.Table / sheet.Sheet give you paging, search, drawer forms, and optimistic refresh.\",\n \"Landing:UsageCrudB1\": \"createCrudService: list / create / update / delete + policy\",\n \"Landing:UsageCrudB2\": \"useAbpTable + useAbpSheet: two hooks return the table, query form, and drawer, fully wired\",\n \"Landing:UsageCrudB3\": \"t.Table: permission-gated actions, optimistic refresh, concurrency\",\n \"Landing:UsageMenuTitle\": \"Navigation · configured once\",\n \"Landing:UsageMenuDesc\": \"All navigation lives in one menuItems array; the framework prunes it by permission, feature flag, and auth — hiding items and empty parents the user shouldn't see, ordered by order.\",\n \"Landing:UsageMenuB1\": \"One typed MenuItem<FileRouteTypes[\\\"to\\\"]>[] declares everything, with nested children\",\n \"Landing:UsageMenuB2\": \"requiredPolicy filters by permission; requiredFeature by feature flag\",\n \"Landing:UsageMenuB3\": \"Empty parents auto-hidden; items sorted by order\",\n \"Landing:StackEyebrow\": \"Built on\",\n \"Landing:StackTitle\": \"Standing on tools you already know\",\n \"Landing:StackReact\": \"UI runtime.\",\n \"Landing:StackStart\": \"Full-stack framework — SSR, file routing, server functions.\",\n \"Landing:StackQuery\": \"Server state and caching, with optimistic refresh on writes.\",\n \"Landing:StackTable\": \"Headless table engine — sorting and pagination.\",\n \"Landing:StackForm\": \"Form state and per-field validation.\",\n \"Landing:StackShadcn\": \"Radix-based component primitives.\",\n \"Landing:StackTailwind\": \"Utility-first, token-driven theming.\",\n \"Landing:StackOrval\": \"Type-safe API client generated from your ABP Swagger.\",\n \"Landing:StackAbp\": \".NET backend — auth, permissions, and multi-tenancy.\",\n \"Landing:CtaTitle\": \"Ready to build?\",\n \"Landing:CtaSubtitle\": \"Initialize a project and you're looking at a working ABP admin in minutes.\",\n \"Landing:FooterTagline\": \"Built with React, TanStack Start, and shadcn/ui.\"\n }\n },\n \"zh-Hans\": {\n \"\": {\n \"Shell:Loading\": \"加载中…\",\n \"Shell:Forbidden\": \"403 · 无权限\",\n \"Shell:ForbiddenHint\": \"你已登录,但没有访问该页面的权限。\",\n \"Shell:ForbiddenBody\": \"你没有访问该资源的权限。\",\n \"Shell:BackHome\": \"返回首页\",\n \"Shell:Unauthorized\": \"401 · 未登录\",\n \"Shell:SessionExpired\": \"会话已过期,请重新登录。\",\n \"Shell:SignIn\": \"登录\",\n \"Shell:NotFound\": \"404 · 页面不存在\",\n \"Shell:UnexpectedError\": \"出错了\",\n \"Shell:UnknownError\": \"未知错误\",\n \"Home:Welcome\": \"欢迎\",\n \"Home:WelcomeBack\": \"欢迎回来,{0}\",\n \"Home:Tagline\": \"面向 ABP 后端的现代化 React 管理后台脚手架——认证、权限、多租户、国际化开箱即用。\",\n \"Home:SignIn\": \"登录以开始\",\n \"Home:FeatureAuthTitle\": \"身份与权限\",\n \"Home:FeatureAuthDesc\": \"OpenIddict 登录、角色管理与细粒度权限校验,前后端保持一致。\",\n \"Home:FeatureTenantTitle\": \"多租户\",\n \"Home:FeatureTenantDesc\": \"按租户隔离数据与配置,顶栏即可切换租户。\",\n \"Home:FeatureI18nTitle\": \"国际化\",\n \"Home:FeatureI18nDesc\": \"词条与文化设置随 ABP 后端同步,每个页面都无硬编码文案。\",\n \"Home:EditHint\": \"编辑 src/routes/_layout/index.tsx,把这个首页改成你自己的。\",\n \"Showcase:Heading\": \"封装组件\",\n \"Showcase:Intro\": \"脚手架封装好的核心交互组件。下面每一节都是可以直接上手点的实时示例,用本地示例数据、不连后端。\",\n \"Showcase:DataTableDesc\": \"服务端分页语义的通用表格:排序表头、防抖搜索、词条化空态与分页控件。点表头排序、输入搜索、翻页试试。\",\n \"Showcase:ColBlock\": \"块\",\n \"Showcase:ColFiles\": \"文件数\",\n \"Showcase:ColStatus\": \"状态\",\n \"Showcase:ColBookName\": \"书名\",\n \"Showcase:ColBookAuthor\": \"作者\",\n \"Showcase:ColBookPrice\": \"价格\",\n \"Showcase:StatusStable\": \"稳定\",\n \"Showcase:StatusBeta\": \"预览\",\n \"Showcase:SearchBlocks\": \"搜索块…\",\n \"Showcase:BulkExport\": \"导出 {0} 项\",\n \"Showcase:AbpTableDesc\": \"在 data-table 之上接好 ABP 后端:列表查询、增删改侧滑表单、按权限门控的操作、乐观刷新——描述清楚 service,整页就跟着来了。右边这张表就是真货,新建、编辑、删一行试试。\",\n \"Showcase:AbpTableCrud\": \"增删改侧滑表单,成功后自动刷新列表。\",\n \"Showcase:AbpTablePermission\": \"每个操作按钮都按其 ABP 权限策略门控。\",\n \"Showcase:AbpTableConcurrency\": \"乐观并发:concurrencyStamp 全链路回传。\",\n \"Showcase:FormDesc\": \"侧滑表单容器 + 必填三件套:必填星号、内联错误、失焦/提交校验——与服务端字段错误共用同一条错误链路。\",\n \"Showcase:FormOpen\": \"新建条目\",\n \"Showcase:FormNameLabel\": \"名称\",\n \"Showcase:FormEmailLabel\": \"邮箱\",\n \"Showcase:FormSuccess\": \"校验通过,已提交:{0}\",\n \"Showcase:TreeDesc\": \"受控树形组件:展开/收起、三态勾选(含半选)。级联策略用 tree-helpers 纯函数自由组合。勾选父节点试试。\",\n \"Showcase:TreeIdentity\": \"身份管理\",\n \"Showcase:TreeUsers\": \"用户\",\n \"Showcase:TreeRoles\": \"角色\",\n \"Showcase:PermView\": \"查看\",\n \"Showcase:PermEdit\": \"编辑\",\n \"Showcase:TreeSelected\": \"已选 {0} 项\",\n \"Showcase:ComboboxDesc\": \"单选/多选下拉:本地过滤或远程 loadOptions(防抖),选中项 label 自动回显。这里是本地过滤示例,输入即筛选。\",\n \"Showcase:ComboboxSingle\": \"单选\",\n \"Showcase:ComboboxMulti\": \"多选\",\n \"Showcase:OptAdmin\": \"管理员\",\n \"Showcase:OptEditor\": \"编辑\",\n \"Showcase:OptViewer\": \"访客\",\n \"Showcase:OptAuditor\": \"审计员\",\n \"Showcase:OptDeveloper\": \"开发者\",\n \"Showcase:OptOperator\": \"运维\",\n \"Showcase:DatePickerDesc\": \"基于 react-day-picker 的弹层日期选择器:单选、区间与日期+时间三种形态,格式经 date-fns 处理并随文化切换。点击任意输入框打开日历试试。\",\n \"Showcase:DatePickerSingle\": \"选择日期\",\n \"Showcase:DatePickerRange\": \"选择日期范围\",\n \"Showcase:DatePickerDateTime\": \"选择日期时间\",\n \"Showcase:DataTableTitle\": \"服务端分页,拿来即用\",\n \"Showcase:DataTableB1\": \"manualPagination / manualSorting 语义\",\n \"Showcase:DataTableB2\": \"防抖搜索,Enter 立即提交\",\n \"Showcase:DataTableB3\": \"词条化空态与分页控件\",\n \"Showcase:FormTitle\": \"表单校验,同一条链路\",\n \"Showcase:FormB1\": \"必填星号 + aria-required\",\n \"Showcase:FormB2\": \"失焦、提交即校验\",\n \"Showcase:FormB3\": \"服务端字段错误同链回填\",\n \"Showcase:TreeTitle\": \"树形与级联,自由组合\",\n \"Showcase:TreeB1\": \"三态勾选,含半选态\",\n \"Showcase:TreeB2\": \"纯函数 collectSubtreeIds / deriveIndeterminate\",\n \"Showcase:TreeB3\": \"零业务耦合,策略你定\",\n \"Showcase:ComboboxTitle\": \"下拉搜索,本地或远程\",\n \"Showcase:ComboboxB1\": \"单选与多选\",\n \"Showcase:ComboboxB2\": \"本地过滤或远程 loadOptions(防抖)\",\n \"Showcase:ComboboxB3\": \"选中项 label 自动回显\",\n \"Showcase:DatePickerTitle\": \"日期选择器,随文化切换\",\n \"Showcase:DatePickerB1\": \"单选、区间、日期+时间三种形态\",\n \"Showcase:DatePickerB2\": \"date-fns 格式化,随当前文化切换\",\n \"Showcase:DatePickerB3\": \"DateField 直接绑定表单里的 ISO 日期字符串\",\n \"Showcase:AbpTableTitle\": \"ABP CRUD,描述符接线\",\n \"Landing:NavFeatures\": \"特性\",\n \"Landing:NavComponents\": \"组件\",\n \"Landing:NavConsole\": \"进入控制台\",\n \"Landing:NavSignIn\": \"登录\",\n \"Landing:HeroEyebrow\": \"纯 React · ABP\",\n \"Landing:HeroTitleLead\": \"为你的 ABP 后端,备好一套\",\n \"Landing:HeroTitleAccent\": \"现代 React 管理后台\",\n \"Landing:HeroSubtitle\": \"自研的纯 React ABP 框架:认证、权限、多租户、国际化开箱即用,配套 data-table、form、tree、combobox 等封装组件,拿来即用。\",\n \"Landing:HeroWelcomeBack\": \"欢迎回来,{0}。控制台一键即达。\",\n \"Landing:HeroPrimary\": \"开始使用\",\n \"Landing:HeroSecondary\": \"查看组件\",\n \"Landing:InstallHint\": \"一条命令初始化项目\",\n \"Landing:Copy\": \"复制\",\n \"Landing:Copied\": \"已复制\",\n \"Landing:FeaturesEyebrow\": \"特性\",\n \"Landing:FeaturesTitle\": \"后台该有的,都替你接好了\",\n \"Landing:FeatureAuthTitle\": \"OIDC 登录\",\n \"Landing:FeatureAuthDesc\": \"已对接 OpenIddict,开箱即用;也可切换到 Keycloak 等其它身份提供方。\",\n \"Landing:FeaturePermTitle\": \"细粒度权限\",\n \"Landing:FeaturePermDesc\": \"权限校验前后端一致,按策略门控每一个操作。\",\n \"Landing:FeatureI18nTitle\": \"前后端多语言\",\n \"Landing:FeatureI18nDesc\": \"复用 ABP 后端的本地化资源,前后端共享同一套词条;切换文化即时生效。\",\n \"Landing:FeatureApiTitle\": \"类型安全 API\",\n \"Landing:FeatureApiDesc\": \"Orval 从 ABP Swagger 生成端点与模型,jc-abp gen 一键更新,调用处全程类型安全。\",\n \"Landing:FeatureAdminTitle\": \"管理页已接好\",\n \"Landing:FeatureAdminDesc\": \"用户、角色、租户、设置、个人资料等 CRUD 页面,已用封装组件接好。\",\n \"Landing:FeatureTenantTitle\": \"多租户\",\n \"Landing:FeatureTenantDesc\": \"按租户隔离数据与配置,顶栏一键切换租户。\",\n \"Landing:InActionEyebrow\": \"实时演示\",\n \"Landing:InActionTitle\": \"封装组件,点点看\",\n \"Landing:UsageEyebrow\": \"用法\",\n \"Landing:UsageTitle\": \"接进来,就这么写\",\n \"Landing:UsageI18nTitle\": \"多语言 · L()\",\n \"Landing:UsageI18nDesc\": \"一个 L 取遍与后端共享的词条,按 资源::键 命名,支持带参插值。\",\n \"Landing:UsageI18nB1\": \"useLocalization() 拿到 L,资源::键 取词条\",\n \"Landing:UsageI18nB2\": \"支持带参插值(page、total 等)\",\n \"Landing:UsageI18nB3\": \"useCulture() 读当前文化,顶栏 LocaleSwitcher 切换\",\n \"Landing:UsagePermTitle\": \"权限 · 三种写法\",\n \"Landing:UsagePermDesc\": \"同一套策略,前后端一致;路由、命令式、声明式任你选。\",\n \"Landing:UsagePermB1\": \"requirePermission() 在 beforeLoad 做路由守卫\",\n \"Landing:UsagePermB2\": \"usePermissionChecker() 命令式:can / can.any / can.all\",\n \"Landing:UsagePermB3\": \"PermissionGuard 声明式:授权才渲染 children\",\n \"Landing:UsageCrudTitle\": \"abp-table · 完整 CRUD\",\n \"Landing:UsageCrudDesc\": \"createCrudService 声明列表/增删改与权限策略,useAbpTable / useAbpSheet 把接线分别收进两个 hook,t.Table / sheet.Sheet 一挂就有分页、搜索、增删改侧滑与乐观刷新。\",\n \"Landing:UsageCrudB1\": \"createCrudService:list / create / update / delete + policy\",\n \"Landing:UsageCrudB2\": \"useAbpTable + useAbpSheet:两个 hook 返回接好线的表格、查询区与抽屉\",\n \"Landing:UsageCrudB3\": \"t.Table:按权限门控、乐观刷新、并发校验\",\n \"Landing:UsageMenuTitle\": \"菜单导航 · 统一配置\",\n \"Landing:UsageMenuDesc\": \"所有导航在一份 menuItems 数组里声明;框架按权限、功能开关与登录态自动裁剪,无权限的项连同空父级一并隐藏,按 order 排序。\",\n \"Landing:UsageMenuB1\": \"一份类型化 MenuItem<FileRouteTypes[\\\"to\\\"]>[] 声明全部导航,可嵌套 children\",\n \"Landing:UsageMenuB2\": \"requiredPolicy 按权限过滤,requiredFeature 按功能开关过滤\",\n \"Landing:UsageMenuB3\": \"无链接且子项被裁空的父级自动隐藏,按 order 排序\",\n \"Landing:StackEyebrow\": \"技术栈\",\n \"Landing:StackTitle\": \"站在你熟悉的成熟工具之上\",\n \"Landing:StackReact\": \"UI 运行时。\",\n \"Landing:StackStart\": \"全栈框架——SSR、文件路由、server functions。\",\n \"Landing:StackQuery\": \"服务端状态与缓存,写操作乐观刷新。\",\n \"Landing:StackTable\": \"无头表格引擎——排序与分页。\",\n \"Landing:StackForm\": \"表单状态与逐字段校验。\",\n \"Landing:StackShadcn\": \"基于 Radix 的组件原语。\",\n \"Landing:StackTailwind\": \"原子化 + 语义 token 主题。\",\n \"Landing:StackOrval\": \"从 ABP Swagger 生成类型安全 API 客户端。\",\n \"Landing:StackAbp\": \".NET 后端——认证、权限、多租户。\",\n \"Landing:CtaTitle\": \"准备好开始了吗?\",\n \"Landing:CtaSubtitle\": \"初始化一个项目,几分钟后你面对的就是一套能跑的 ABP 后台。\",\n \"Landing:FooterTagline\": \"基于 React、TanStack Start 与 shadcn/ui 构建。\"\n }\n }\n}\n",
42
+ "content": "{\n \"en\": {\n \"\": {\n \"Shell:Loading\": \"Loading…\",\n \"Shell:Forbidden\": \"403 · Forbidden\",\n \"Shell:ForbiddenHint\": \"You're signed in, but you don't have permission to view this page.\",\n \"Shell:ForbiddenBody\": \"You don't have permission to access this resource.\",\n \"Shell:BackHome\": \"Back to home\",\n \"Shell:Unauthorized\": \"401 · Unauthorized\",\n \"Shell:SessionExpired\": \"Your session has expired. Please sign in again.\",\n \"Shell:SignIn\": \"Sign in\",\n \"Shell:NotFound\": \"404 · Page not found\",\n \"Shell:UnexpectedError\": \"Something went wrong\",\n \"Shell:UnknownError\": \"Unknown error\",\n \"Home:Welcome\": \"Welcome\",\n \"Home:WelcomeBack\": \"Welcome back, {0}\",\n \"Home:Tagline\": \"A modern React admin scaffold for your ABP backend — authentication, permissions, multi-tenancy, and localization, all wired up out of the box.\",\n \"Home:SignIn\": \"Sign in to get started\",\n \"Home:FeatureAuthTitle\": \"Identity & Permissions\",\n \"Home:FeatureAuthDesc\": \"OpenIddict sign-in, role management, and fine-grained permission checks kept consistent from backend to UI.\",\n \"Home:FeatureTenantTitle\": \"Multi-tenancy\",\n \"Home:FeatureTenantDesc\": \"Per-tenant data and settings isolation, with tenant switching available from the top bar.\",\n \"Home:FeatureI18nTitle\": \"Localization\",\n \"Home:FeatureI18nDesc\": \"Text and culture synced from the ABP backend, so every screen stays free of hardcoded copy.\",\n \"Home:EditHint\": \"Edit src/routes/_layout/index.tsx to make this home page your own.\",\n \"Showcase:Heading\": \"Built-in components\",\n \"Showcase:Intro\": \"Core interactive components the scaffold ships with. Each section below is a live, clickable example running on local sample data — no backend required.\",\n \"Showcase:DataTableDesc\": \"A server-paginated table primitive: sortable headers, debounced search, localized empty state, and pagination. Click a header to sort, type to search, and page through the rows.\",\n \"Showcase:ColBlock\": \"Block\",\n \"Showcase:ColFiles\": \"Files\",\n \"Showcase:ColStatus\": \"Status\",\n \"Showcase:ColBookName\": \"Title\",\n \"Showcase:ColBookAuthor\": \"Author\",\n \"Showcase:ColBookPrice\": \"Price\",\n \"Showcase:StatusStable\": \"Stable\",\n \"Showcase:StatusBeta\": \"Preview\",\n \"Showcase:SearchBlocks\": \"Search blocks…\",\n \"Showcase:BulkExport\": \"Export {0}\",\n \"Showcase:AbpTableDesc\": \"Everything data-table gives you, wired to an ABP backend: list query, create/edit/delete drawer forms, permission-gated actions, and optimistic refresh — you describe the service, the page comes with it. The table on the right is the real thing; try creating and deleting a row.\",\n \"Showcase:AbpTableCrud\": \"Create/edit/delete drawer forms that refresh the list on success.\",\n \"Showcase:AbpTablePermission\": \"Every action button gated by its ABP permission policy.\",\n \"Showcase:AbpTableConcurrency\": \"Optimistic concurrency: the concurrencyStamp is round-tripped end to end.\",\n \"Showcase:FormDesc\": \"A drawer form container plus the required-field trio: the asterisk mark, inline errors, and blur/submit validation — sharing one error channel with server-side field errors.\",\n \"Showcase:FormOpen\": \"New item\",\n \"Showcase:FormNameLabel\": \"Name\",\n \"Showcase:FormEmailLabel\": \"Email\",\n \"Showcase:FormSuccess\": \"Validated and submitted: {0}\",\n \"Showcase:TreeDesc\": \"A controlled tree: expand/collapse and tri-state checkboxes (including indeterminate). Cascade behavior is composed from the pure tree-helpers functions. Check a parent to try it.\",\n \"Showcase:TreeIdentity\": \"Identity management\",\n \"Showcase:TreeUsers\": \"Users\",\n \"Showcase:TreeRoles\": \"Roles\",\n \"Showcase:PermView\": \"View\",\n \"Showcase:PermEdit\": \"Edit\",\n \"Showcase:TreeSelected\": \"{0} selected\",\n \"Showcase:ComboboxDesc\": \"Single- and multi-select dropdowns: local filtering or remote loadOptions (debounced), with the selected label rendered back automatically. This is the local-filter mode — type to filter.\",\n \"Showcase:ComboboxSingle\": \"Single select\",\n \"Showcase:ComboboxMulti\": \"Multi select\",\n \"Showcase:OptAdmin\": \"Administrator\",\n \"Showcase:OptEditor\": \"Editor\",\n \"Showcase:OptViewer\": \"Viewer\",\n \"Showcase:OptAuditor\": \"Auditor\",\n \"Showcase:OptDeveloper\": \"Developer\",\n \"Showcase:OptOperator\": \"Operator\",\n \"Showcase:DatePickerDesc\": \"Popover-based date pickers built on react-day-picker: a single date, a from–to range, and a date + time combo, all formatted via date-fns and locale-aware. Click any field to open the calendar.\",\n \"Showcase:DatePickerSingle\": \"Pick a date\",\n \"Showcase:DatePickerRange\": \"Pick a range\",\n \"Showcase:DatePickerDateTime\": \"Pick date & time\",\n \"Showcase:DataTableTitle\": \"Server-side tables, out of the box\",\n \"Showcase:DataTableB1\": \"manualPagination / manualSorting semantics\",\n \"Showcase:DataTableB2\": \"Debounced search, submit on Enter\",\n \"Showcase:DataTableB3\": \"Localized empty state and pagination\",\n \"Showcase:FormTitle\": \"Forms, one error channel\",\n \"Showcase:FormB1\": \"Required mark + aria-required\",\n \"Showcase:FormB2\": \"Validates on blur and on submit\",\n \"Showcase:FormB3\": \"Server field errors on the same channel\",\n \"Showcase:TreeTitle\": \"Trees and cascading, composable\",\n \"Showcase:TreeB1\": \"Tri-state checkboxes, including indeterminate\",\n \"Showcase:TreeB2\": \"Pure helpers: collectSubtreeIds / deriveIndeterminate\",\n \"Showcase:TreeB3\": \"Zero business coupling — you own the policy\",\n \"Showcase:ComboboxTitle\": \"Comboboxes, local or remote\",\n \"Showcase:ComboboxB1\": \"Single and multi select\",\n \"Showcase:ComboboxB2\": \"Local filter or debounced remote loadOptions\",\n \"Showcase:ComboboxB3\": \"Selected labels rendered back automatically\",\n \"Showcase:DatePickerTitle\": \"Date pickers, locale-aware\",\n \"Showcase:DatePickerB1\": \"Single, range, and date + time variants\",\n \"Showcase:DatePickerB2\": \"date-fns formatting synced to the current culture\",\n \"Showcase:DatePickerB3\": \"DateField binds straight to an ISO date string in forms\",\n \"Showcase:AbpTableTitle\": \"ABP CRUD, wired by descriptor\",\n \"Landing:NavFeatures\": \"Features\",\n \"Landing:NavComponents\": \"Components\",\n \"Landing:NavConsole\": \"Open console\",\n \"Landing:NavSignIn\": \"Sign in\",\n \"Landing:HeroEyebrow\": \"Pure React · ABP\",\n \"Landing:HeroTitleLead\": \"A modern React admin for your\",\n \"Landing:HeroTitleAccent\": \"ABP backend.\",\n \"Landing:HeroSubtitle\": \"A pure-React framework for your ABP backend — authentication, permissions, multi-tenancy, and localization out of the box, with data-table, form, tree, and combobox components ready to use.\",\n \"Landing:HeroWelcomeBack\": \"Welcome back, {0}. Your console is one click away.\",\n \"Landing:HeroPrimary\": \"Get started\",\n \"Landing:HeroSecondary\": \"Explore components\",\n \"Landing:InstallHint\": \"Scaffold a project with one command\",\n \"Landing:Copy\": \"Copy\",\n \"Landing:Copied\": \"Copied\",\n \"Landing:FeaturesEyebrow\": \"Features\",\n \"Landing:FeaturesTitle\": \"Everything an admin needs, already wired up\",\n \"Landing:FeatureAuthTitle\": \"OIDC sign-in\",\n \"Landing:FeatureAuthDesc\": \"Wired to OpenIddict out of the box, and switchable to another identity provider like Keycloak.\",\n \"Landing:FeaturePermTitle\": \"Fine-grained permissions\",\n \"Landing:FeaturePermDesc\": \"Permission checks kept consistent from backend to UI — gate any action by its policy.\",\n \"Landing:FeatureI18nTitle\": \"Front-and-back localization\",\n \"Landing:FeatureI18nDesc\": \"Reuses your ABP backend's localization resources, so front and back share one set of translations; switch culture and it applies instantly.\",\n \"Landing:FeatureApiTitle\": \"Type-safe API\",\n \"Landing:FeatureApiDesc\": \"Orval generates endpoints and models from your ABP Swagger — regenerate with jc-abp gen, and every call stays type-safe.\",\n \"Landing:FeatureAdminTitle\": \"Admin pages, ready\",\n \"Landing:FeatureAdminDesc\": \"Users, roles, tenants, settings, and profile CRUD pages already built on the bundled components.\",\n \"Landing:FeatureTenantTitle\": \"Multi-tenancy\",\n \"Landing:FeatureTenantDesc\": \"Per-tenant data and settings isolation, with tenant switching from the top bar.\",\n \"Landing:InActionEyebrow\": \"In action\",\n \"Landing:InActionTitle\": \"Built-in components, live\",\n \"Landing:UsageEyebrow\": \"Usage\",\n \"Landing:UsageTitle\": \"Wire it in, like this\",\n \"Landing:UsageI18nTitle\": \"Localization · L()\",\n \"Landing:UsageI18nDesc\": \"One L reads every translation shared with the backend, namespaced Resource::Key, with argument interpolation.\",\n \"Landing:UsageI18nB1\": \"useLocalization() gives you L; keys are Resource::Key\",\n \"Landing:UsageI18nB2\": \"Argument interpolation supported (page, total, …)\",\n \"Landing:UsageI18nB3\": \"useCulture() reads the current culture; switch it from the top bar\",\n \"Landing:UsagePermTitle\": \"Permissions · three ways\",\n \"Landing:UsagePermDesc\": \"One policy set, consistent front to back — pick route, imperative, or declarative.\",\n \"Landing:UsagePermB1\": \"requirePermission() guards a route in beforeLoad\",\n \"Landing:UsagePermB2\": \"usePermissionChecker() — imperative can / can.any / can.all\",\n \"Landing:UsagePermB3\": \"PermissionGuard renders children only when granted\",\n \"Landing:UsageCrudTitle\": \"abp-table · full CRUD\",\n \"Landing:UsageCrudDesc\": \"Declare the list/create/update/delete calls and a policy once; useAbpTable / useAbpSheet wire the rest, and t.Table / sheet.Sheet give you paging, search, drawer forms, and optimistic refresh.\",\n \"Landing:UsageCrudB1\": \"createCrudService: list / create / update / delete + policy\",\n \"Landing:UsageCrudB2\": \"useAbpTable + useAbpSheet: two hooks return the table, query form, and drawer, fully wired\",\n \"Landing:UsageCrudB3\": \"t.Table: permission-gated actions, optimistic refresh, concurrency\",\n \"Landing:UsageMenuTitle\": \"Navigation · configured once\",\n \"Landing:UsageMenuDesc\": \"All navigation lives in one menuItems array; the framework prunes it by permission, feature flag, and auth — hiding items and empty parents the user shouldn't see, ordered by order.\",\n \"Landing:UsageMenuB1\": \"One typed MenuItem<FileRouteTypes[\\\"to\\\"]>[] declares everything, with nested children\",\n \"Landing:UsageMenuB2\": \"requiredPolicy filters by permission; requiredFeature by feature flag\",\n \"Landing:UsageMenuB3\": \"Empty parents auto-hidden; items sorted by order\",\n \"Landing:StackEyebrow\": \"Built on\",\n \"Landing:StackTitle\": \"Standing on tools you already know\",\n \"Landing:StackReact\": \"UI runtime.\",\n \"Landing:StackStart\": \"Full-stack framework — SSR, file routing, server functions.\",\n \"Landing:StackQuery\": \"Server state and caching, with optimistic refresh on writes.\",\n \"Landing:StackTable\": \"Headless table engine — sorting and pagination.\",\n \"Landing:StackForm\": \"Form state and per-field validation.\",\n \"Landing:StackShadcn\": \"Radix-based component primitives.\",\n \"Landing:StackTailwind\": \"Utility-first, token-driven theming.\",\n \"Landing:StackOrval\": \"Type-safe API client generated from your ABP Swagger.\",\n \"Landing:StackAbp\": \".NET backend — auth, permissions, and multi-tenancy.\",\n \"Landing:CtaTitle\": \"Ready to build?\",\n \"Landing:CtaSubtitle\": \"Initialize a project and you're looking at a working ABP admin in minutes.\",\n \"Landing:FooterTagline\": \"Built with React, TanStack Start, and shadcn/ui.\"\n }\n },\n \"zh-Hans\": {\n \"\": {\n \"Shell:Loading\": \"加载中…\",\n \"Shell:Forbidden\": \"403 · 无权限\",\n \"Shell:ForbiddenHint\": \"你已登录,但没有访问该页面的权限。\",\n \"Shell:ForbiddenBody\": \"你没有访问该资源的权限。\",\n \"Shell:BackHome\": \"返回首页\",\n \"Shell:Unauthorized\": \"401 · 未登录\",\n \"Shell:SessionExpired\": \"会话已过期,请重新登录。\",\n \"Shell:SignIn\": \"登录\",\n \"Shell:NotFound\": \"404 · 页面不存在\",\n \"Shell:UnexpectedError\": \"出错了\",\n \"Shell:UnknownError\": \"未知错误\",\n \"Home:Welcome\": \"欢迎\",\n \"Home:WelcomeBack\": \"欢迎回来,{0}\",\n \"Home:Tagline\": \"面向 ABP 后端的现代化 React 管理后台脚手架——认证、权限、多租户、国际化开箱即用。\",\n \"Home:SignIn\": \"登录以开始\",\n \"Home:FeatureAuthTitle\": \"身份与权限\",\n \"Home:FeatureAuthDesc\": \"OpenIddict 登录、角色管理与细粒度权限校验,前后端保持一致。\",\n \"Home:FeatureTenantTitle\": \"多租户\",\n \"Home:FeatureTenantDesc\": \"按租户隔离数据与配置,顶栏即可切换租户。\",\n \"Home:FeatureI18nTitle\": \"国际化\",\n \"Home:FeatureI18nDesc\": \"词条与文化设置随 ABP 后端同步,每个页面都无硬编码文案。\",\n \"Home:EditHint\": \"编辑 src/routes/_layout/index.tsx,把这个首页改成你自己的。\",\n \"Showcase:Heading\": \"封装组件\",\n \"Showcase:Intro\": \"脚手架封装好的核心交互组件。下面每一节都是可以直接上手点的实时示例,用本地示例数据、不连后端。\",\n \"Showcase:DataTableDesc\": \"服务端分页语义的通用表格:排序表头、防抖搜索、词条化空态与分页控件。点表头排序、输入搜索、翻页试试。\",\n \"Showcase:ColBlock\": \"块\",\n \"Showcase:ColFiles\": \"文件数\",\n \"Showcase:ColStatus\": \"状态\",\n \"Showcase:ColBookName\": \"书名\",\n \"Showcase:ColBookAuthor\": \"作者\",\n \"Showcase:ColBookPrice\": \"价格\",\n \"Showcase:StatusStable\": \"稳定\",\n \"Showcase:StatusBeta\": \"预览\",\n \"Showcase:SearchBlocks\": \"搜索块…\",\n \"Showcase:BulkExport\": \"导出 {0} 项\",\n \"Showcase:AbpTableDesc\": \"在 data-table 之上接好 ABP 后端:列表查询、增删改侧滑表单、按权限门控的操作、乐观刷新——描述清楚 service,整页就跟着来了。右边这张表就是真货,新建、编辑、删一行试试。\",\n \"Showcase:AbpTableCrud\": \"增删改侧滑表单,成功后自动刷新列表。\",\n \"Showcase:AbpTablePermission\": \"每个操作按钮都按其 ABP 权限策略门控。\",\n \"Showcase:AbpTableConcurrency\": \"乐观并发:concurrencyStamp 全链路回传。\",\n \"Showcase:FormDesc\": \"侧滑表单容器 + 必填三件套:必填星号、内联错误、失焦/提交校验——与服务端字段错误共用同一条错误链路。\",\n \"Showcase:FormOpen\": \"新建条目\",\n \"Showcase:FormNameLabel\": \"名称\",\n \"Showcase:FormEmailLabel\": \"邮箱\",\n \"Showcase:FormSuccess\": \"校验通过,已提交:{0}\",\n \"Showcase:TreeDesc\": \"受控树形组件:展开/收起、三态勾选(含半选)。级联策略用 tree-helpers 纯函数自由组合。勾选父节点试试。\",\n \"Showcase:TreeIdentity\": \"身份管理\",\n \"Showcase:TreeUsers\": \"用户\",\n \"Showcase:TreeRoles\": \"角色\",\n \"Showcase:PermView\": \"查看\",\n \"Showcase:PermEdit\": \"编辑\",\n \"Showcase:TreeSelected\": \"已选 {0} 项\",\n \"Showcase:ComboboxDesc\": \"单选/多选下拉:本地过滤或远程 loadOptions(防抖),选中项 label 自动回显。这里是本地过滤示例,输入即筛选。\",\n \"Showcase:ComboboxSingle\": \"单选\",\n \"Showcase:ComboboxMulti\": \"多选\",\n \"Showcase:OptAdmin\": \"管理员\",\n \"Showcase:OptEditor\": \"编辑\",\n \"Showcase:OptViewer\": \"访客\",\n \"Showcase:OptAuditor\": \"审计员\",\n \"Showcase:OptDeveloper\": \"开发者\",\n \"Showcase:OptOperator\": \"运维\",\n \"Showcase:DatePickerDesc\": \"基于 react-day-picker 的弹层日期选择器:单选、区间与日期+时间三种形态,格式经 date-fns 处理并随文化切换。点击任意输入框打开日历试试。\",\n \"Showcase:DatePickerSingle\": \"选择日期\",\n \"Showcase:DatePickerRange\": \"选择日期范围\",\n \"Showcase:DatePickerDateTime\": \"选择日期时间\",\n \"Showcase:DataTableTitle\": \"服务端分页,拿来即用\",\n \"Showcase:DataTableB1\": \"manualPagination / manualSorting 语义\",\n \"Showcase:DataTableB2\": \"防抖搜索,Enter 立即提交\",\n \"Showcase:DataTableB3\": \"词条化空态与分页控件\",\n \"Showcase:FormTitle\": \"表单校验,同一条链路\",\n \"Showcase:FormB1\": \"必填星号 + aria-required\",\n \"Showcase:FormB2\": \"失焦、提交即校验\",\n \"Showcase:FormB3\": \"服务端字段错误同链回填\",\n \"Showcase:TreeTitle\": \"树形与级联,自由组合\",\n \"Showcase:TreeB1\": \"三态勾选,含半选态\",\n \"Showcase:TreeB2\": \"纯函数 collectSubtreeIds / deriveIndeterminate\",\n \"Showcase:TreeB3\": \"零业务耦合,策略你定\",\n \"Showcase:ComboboxTitle\": \"下拉搜索,本地或远程\",\n \"Showcase:ComboboxB1\": \"单选与多选\",\n \"Showcase:ComboboxB2\": \"本地过滤或远程 loadOptions(防抖)\",\n \"Showcase:ComboboxB3\": \"选中项 label 自动回显\",\n \"Showcase:DatePickerTitle\": \"日期选择器,随文化切换\",\n \"Showcase:DatePickerB1\": \"单选、区间、日期+时间三种形态\",\n \"Showcase:DatePickerB2\": \"date-fns 格式化,随当前文化切换\",\n \"Showcase:DatePickerB3\": \"DateField 直接绑定表单里的 ISO 日期字符串\",\n \"Showcase:AbpTableTitle\": \"ABP CRUD,描述符接线\",\n \"Landing:NavFeatures\": \"特性\",\n \"Landing:NavComponents\": \"组件\",\n \"Landing:NavConsole\": \"进入控制台\",\n \"Landing:NavSignIn\": \"登录\",\n \"Landing:HeroEyebrow\": \"纯 React · ABP\",\n \"Landing:HeroTitleLead\": \"为你的 ABP 后端,备好一套\",\n \"Landing:HeroTitleAccent\": \"现代 React 管理后台\",\n \"Landing:HeroSubtitle\": \"面向 ABP 后端的纯 React 框架:认证、权限、多租户、国际化开箱即用,配套 data-table、form、tree、combobox 等封装组件,拿来即用。\",\n \"Landing:HeroWelcomeBack\": \"欢迎回来,{0}。控制台一键即达。\",\n \"Landing:HeroPrimary\": \"开始使用\",\n \"Landing:HeroSecondary\": \"查看组件\",\n \"Landing:InstallHint\": \"一条命令初始化项目\",\n \"Landing:Copy\": \"复制\",\n \"Landing:Copied\": \"已复制\",\n \"Landing:FeaturesEyebrow\": \"特性\",\n \"Landing:FeaturesTitle\": \"后台该有的,都替你接好了\",\n \"Landing:FeatureAuthTitle\": \"OIDC 登录\",\n \"Landing:FeatureAuthDesc\": \"已对接 OpenIddict,开箱即用;也可切换到 Keycloak 等其它身份提供方。\",\n \"Landing:FeaturePermTitle\": \"细粒度权限\",\n \"Landing:FeaturePermDesc\": \"权限校验前后端一致,按策略门控每一个操作。\",\n \"Landing:FeatureI18nTitle\": \"前后端多语言\",\n \"Landing:FeatureI18nDesc\": \"复用 ABP 后端的本地化资源,前后端共享同一套词条;切换文化即时生效。\",\n \"Landing:FeatureApiTitle\": \"类型安全 API\",\n \"Landing:FeatureApiDesc\": \"Orval 从 ABP Swagger 生成端点与模型,jc-abp gen 一键更新,调用处全程类型安全。\",\n \"Landing:FeatureAdminTitle\": \"管理页已接好\",\n \"Landing:FeatureAdminDesc\": \"用户、角色、租户、设置、个人资料等 CRUD 页面,已用封装组件接好。\",\n \"Landing:FeatureTenantTitle\": \"多租户\",\n \"Landing:FeatureTenantDesc\": \"按租户隔离数据与配置,顶栏一键切换租户。\",\n \"Landing:InActionEyebrow\": \"实时演示\",\n \"Landing:InActionTitle\": \"封装组件,点点看\",\n \"Landing:UsageEyebrow\": \"用法\",\n \"Landing:UsageTitle\": \"接进来,就这么写\",\n \"Landing:UsageI18nTitle\": \"多语言 · L()\",\n \"Landing:UsageI18nDesc\": \"一个 L 取遍与后端共享的词条,按 资源::键 命名,支持带参插值。\",\n \"Landing:UsageI18nB1\": \"useLocalization() 拿到 L,资源::键 取词条\",\n \"Landing:UsageI18nB2\": \"支持带参插值(page、total 等)\",\n \"Landing:UsageI18nB3\": \"useCulture() 读当前文化,顶栏 LocaleSwitcher 切换\",\n \"Landing:UsagePermTitle\": \"权限 · 三种写法\",\n \"Landing:UsagePermDesc\": \"同一套策略,前后端一致;路由、命令式、声明式任你选。\",\n \"Landing:UsagePermB1\": \"requirePermission() 在 beforeLoad 做路由守卫\",\n \"Landing:UsagePermB2\": \"usePermissionChecker() 命令式:can / can.any / can.all\",\n \"Landing:UsagePermB3\": \"PermissionGuard 声明式:授权才渲染 children\",\n \"Landing:UsageCrudTitle\": \"abp-table · 完整 CRUD\",\n \"Landing:UsageCrudDesc\": \"createCrudService 声明列表/增删改与权限策略,useAbpTable / useAbpSheet 把接线分别收进两个 hook,t.Table / sheet.Sheet 一挂就有分页、搜索、增删改侧滑与乐观刷新。\",\n \"Landing:UsageCrudB1\": \"createCrudService:list / create / update / delete + policy\",\n \"Landing:UsageCrudB2\": \"useAbpTable + useAbpSheet:两个 hook 返回接好线的表格、查询区与抽屉\",\n \"Landing:UsageCrudB3\": \"t.Table:按权限门控、乐观刷新、并发校验\",\n \"Landing:UsageMenuTitle\": \"菜单导航 · 统一配置\",\n \"Landing:UsageMenuDesc\": \"所有导航在一份 menuItems 数组里声明;框架按权限、功能开关与登录态自动裁剪,无权限的项连同空父级一并隐藏,按 order 排序。\",\n \"Landing:UsageMenuB1\": \"一份类型化 MenuItem<FileRouteTypes[\\\"to\\\"]>[] 声明全部导航,可嵌套 children\",\n \"Landing:UsageMenuB2\": \"requiredPolicy 按权限过滤,requiredFeature 按功能开关过滤\",\n \"Landing:UsageMenuB3\": \"无链接且子项被裁空的父级自动隐藏,按 order 排序\",\n \"Landing:StackEyebrow\": \"技术栈\",\n \"Landing:StackTitle\": \"站在你熟悉的成熟工具之上\",\n \"Landing:StackReact\": \"UI 运行时。\",\n \"Landing:StackStart\": \"全栈框架——SSR、文件路由、server functions。\",\n \"Landing:StackQuery\": \"服务端状态与缓存,写操作乐观刷新。\",\n \"Landing:StackTable\": \"无头表格引擎——排序与分页。\",\n \"Landing:StackForm\": \"表单状态与逐字段校验。\",\n \"Landing:StackShadcn\": \"基于 Radix 的组件原语。\",\n \"Landing:StackTailwind\": \"原子化 + 语义 token 主题。\",\n \"Landing:StackOrval\": \"从 ABP Swagger 生成类型安全 API 客户端。\",\n \"Landing:StackAbp\": \".NET 后端——认证、权限、多租户。\",\n \"Landing:CtaTitle\": \"准备好开始了吗?\",\n \"Landing:CtaSubtitle\": \"初始化一个项目,几分钟后你面对的就是一套能跑的 ABP 后台。\",\n \"Landing:FooterTagline\": \"基于 React、TanStack Start 与 shadcn/ui 构建。\"\n }\n }\n}\n",
43
43
  "type": "registry:file",
44
44
  "target": "src/routes/_layout/shell-messages.json"
45
45
  },