应用
应用
应用是 src/app/ 下的一个文件夹:+app.ts 声明它,旁边的每个 +<page>.page.svelte 是一个页面。文件夹也可以改为包含 +group.ts——一个导航分组,其中的应用或下级分组都放在它内部。应用的名称就是它的文件夹路径。
src/app/
├── field_ops_controller/
│ ├── +app.ts
│ ├── +dispatch.page.svelte
│ └── +sites.page.svelte
├── field_ops_contractor/
│ ├── +app.ts
│ └── +jobs.page.svelte
└── <group>/
├── +group.ts
└── <app>/+app.ts … 声明应用
// src/app/field_ops_controller/+app.ts (templates/field-operations)
import { app } from '@norbital-ai/bolt';
export default app('field_ops_controller', {
title: 'app.field_ops_controller.title',
description: 'Schedule site jobs and dispatch contractors',
icon: 'lucide:building-2',
banner: 'app-media/field_ops_controller-banner.webp',
pages: {
dispatch: { title: 'app.field_ops_controller.tab_dispatch', icon: 'lucide:kanban' },
sites: { title: 'app.field_ops_controller.tab_sites', icon: 'lucide:map-pinned' }
}
}); app('<name>', { … }) 接收应用卡片的 title、description 与 icon,可选的 banner,audience,以及 pages——以页面文件名为键、按导航顺序排列,每项带 title、可选的 icon、用于分组的 section,以及全屏页面的 kiosk: true。没有条目的页面文件是构建错误。一旦工作区有了 src/i18n/,标题就是消息目录键。
受众
'members'(默认)向员工显示应用,'external' 向外部成员(如客户与供应商门户用户)显示,'all' 向两者显示。{ public: [policies], challenge?: 'turnstile' } 把页面提供给未登录的访客,访客只持有这些策略,只能提交表单与读取已发布的行。
只有当成员的某个策略在 capabilities.apps 中列出该应用(或包含它的分组)时,成员才能看到它。+workspace.ts 中的 apps 设定应用在启动器中的顺序。
页面
<!-- src/app/field_ops_controller/+sites.page.svelte (templates/field-operations, excerpt) -->
<script lang="ts">
import { bolt } from '$bolt';
import { AppShell } from '@norbital-ai/ui/layout';
import { Table } from '@norbital-ai/ui';
const t = bolt.t;
</script>
<AppShell
icon="lucide:map-pinned"
title={t('app.field_ops_controller.tab_sites')}
description={t('app.field_ops_controller.sites_description')}
>
<Table
of="sites"
orderBy={{ name: 'asc' }}
columns={['name', { field: 'client_name', label: t('component.client_tenant') }, 'address']}
/>
</AppShell> 页面是一个 Svelte 5 组件。它从 $bolt 导入 bolt 进行读写,从 @norbital-ai/ui 导入视图,从 @norbital-ai/ui/layout 导入布局。每个页面都是一个 AppShell,其 title、description 与 icon 渲染页面的头图区域。页面从不导入角色模块:它通过 RecordShell 与记录面板打开记录。
分组
src/app/<group>/+group.ts 为 group('<group>', { label, description?, icon, defaultChild })。一个文件夹要么是应用,要么是分组,不能两者兼有;在策略中指定一个分组即可打开其中所有应用。