扩展 Microsoft Fabric 前端
可以使用 Microsoft Fabric 工作负载开发工具包来生成工作负载并创建自定义功能来扩展 Fabric 体验。 Fabric 平台旨在与独立软件供应商 (ISV) 功能互操作。 例如,通过在 Fabric 工作区项的上下文中嵌入 ISV 的前端,可以使用项编辑器来创建一致的原生用户体验。
本文使用 Microsoft Fabric 工作负载开发示例存储库 作为指南,将自定义 UX 工作负载 Web 应用与 Microsoft Fabric 集成。 项目和详细示例可帮助你将自己的 UI 组件和操作无缝集成到 Fabric 运行时环境中,以便进行高效的试验和自定义。
示例 UX 工作负载项目前端是一个标准 React Web 应用,该应用将工作负载客户端 SDK 作为标准 npm 包来提供功能。
ISV 在 Fabric 门户的沙盒 <iframe>
元素中托管并运行项目。 它提供了 ISV 特定的 UI 体验,包括项编辑器。
SDK 提供了将常规 Web 应用转换为在 Fabric 门户内无缝运行的微前端 Web 应用所需的所有必要接口、API 和启动函数。
SDK 提供示例 UX 工作负载项目。 示例 :
- 展示如何使用大多数可用的 SDK 调用。
- 演示基于 Fluent UI 的可扩展功能区的示例,该功能区与 Fabric 的外观匹配。
- 允许轻松进行自定义。
- 允许在启用 Fabric 开发人员模式时实时观察 Fabric 中的更改。
先决条件
UX 工作负载 Web 应用
UX 工作负载前端清单
UX 工作负载前端清单是 ISV 提供的 JSON 资源。 该文件包含有关工作负载的基本信息(包括工作负载 Web 应用的 URL),以及各种 UI 详细信息(例如 ISV 项的显示名称和关联的图标)。 ISV 可以使用清单文件自定义用户在 Fabric 门户中与项交互时发生的情况。
在此包中,前端清单文件位于 package 文件夹中。 清单文件包含工作负载清单及其组件的详细说明。
在 Fabric 中启用工作负载开发功能
租户管理员必须先在 Microsoft Fabric 管理门户中启用工作负载开发功能。 可以为整个组织或组织内的特定组启用该功能。 对于租户管理员,若要为特定组启用工作负载开发功能,请完成启用开发租户设置中所述的步骤。
设置前端
若要设置示例项目前端,请执行以下操作:
验证是否已安装 Node.js 和 npm。 安装的 npm 的版本必须是 9 或更高版本。 否则,请安装最新版本的 Node.js 和 npm。
克隆 Microsoft Fabric 工作负载开发示例存储库。
- 包:工作负载包的位置。 包包含前端资源(包括清单和资产)。
- src:工作负载代码,其中包括以下资源:
- index.ts:主要初始化文件(包括
bootstrap
以及index.worker
和index.ui
iFrame)(请参阅本文后面的详细信息)。 - App.tsx:此文件将路径路由到页面。 例如,
/sample-workload-editor
路由到components
下的SampleWorkloadEditor
函数。 - 资产:可以在清单中引用并在 UI 中显示的图像(.jpg、.jpeg 和 png)的位置。 例如,
assets/github.jpg
在清单中设置为产品图标。 - 组件:UI 代码的位置,包括示例使用的编辑器视图和其他视图(功能区、身份验证页和面板)。
- 控制器:控制器调用 SDK API。
- 模型:UI 使用的以及用于与样板后端通信的协定和模型。
- index.ts:主要初始化文件(包括
- 工具:可用于创建设置和配置的元素。
- webpack.config.js:使用此文件可配置本地 Node.js 服务器。
- Web 配置和清单读取器/处理器。
- 验证:示例使用
validateSchema.js
验证产品和项 JSON 文件架构。 它配置为在npm start
上运行。
在存储库文件夹中,转到 Frontend 文件夹安装项目文件:
<repository folder>\Frontend> npm install
通过运行以下命令来启动服务器:
<repository folder>\Frontend> npm start
此命令(通过使用 webpack)启动 Microsoft Fabric 在开发人员模式下连接到的本地 Node.js 服务器。
如需了解服务器启动时显示的端口详细信息,请参阅本地主机服务器说明。
当前的端口是
60006
。localhost 服务器启动后,转到 URL
127.0.0.1:60006/manifests
打开在 Frontend/Package 文件夹中创建的聚合清单。如果更改 Frontend/Package 文件夹中的文件,请再次运行
npm start
。此设置会保留在当前浏览器中。
“Hello World”示例
要运行“Hello World”测试方案,请执行以下操作:
启动本地服务器(按照入门中的步骤运行前端和后端工作负载示例),并确保开发人员模式已启用。
在工作区菜单上,选择“创建中心”图标(该图标有时位于“显示更多”省略号中)。
选择查看全部。
在“示例工作负载”下,选择“示例项”卡以创建项。
新项如以下示例所示:
浏览各种控件以查看 Fabric WorkloadClient API(工作负载 SDK)功能:
- 打开通知和对话框
- 转到页面
- 获取主题和工作负载设置
- 执行操作
大多数可用的 SDK 功能要么配置为按钮操作,要么注册为回调。 结果通常用一个通知或一个消息框显示 API 已调用。
例如:
“操作时执行”会通过名为 sample.Action 的操作调用 action.execute() API。 此操作的功能是显示通知。
选择功能区上的“保存”可调用 dialog.open() API。 API 将打开一个对话框,用户在其中输入名称并将项保存在 Fabric 中。 有关对话框的详细信息,请参阅 CRUD 部分。
“获取主题设置”按钮(通过 theme.get() API)显示 Fabric 主题配置列表。
示例工作负载 UI 托管在 Fabric 沙盒 iframe
元素中,该元素在网页的开发人员模式下显示。
了解代码
以下部分介绍代码元素和相关注意事项。
bootstrap()
在启动之前,检查路径以了解是否需要关闭窗口。 如果使用身份验证 API,则需要此步骤。
const redirectUriPath = '/close';
const url = new URL(window.location.href);
if (url.pathname?.startsWith(redirectUriPath)) {
window.close();
}
每个 Fabric 工作负载应用必须支持两种模式下的初始化:
UI 模式:UI 模式下的应用在可见的 iFrame 中加载。 它侦听自己的路由更改,以呈现相应的 UI 组件,如页面、面板和对话框。
辅助角色模式:辅助角色模式下的应用在不可见的 iFrame 中运行。 不可见的 iFrame 主要用于接收外部命令,然后响应它们。
@ms-fabric/workload-client API 提供了 bootstrap()
方法来简化初始化步骤。 bootstrap()
方法在内部检测当前应用是在 UI 模式还是辅助角色模式下加载。 然后,它调用适当的初始化方法(initializeUI
或 initializeWorker
)。 初始化完成后,bootstrap()
向 Fabric 微前端框架通知初始化成功或失败。
bootstrap({
initializeWorker: (params) =>
import('./index.worker').then(({ initialize }) => initialize(params)),
initializeUI: (params) =>
import('./index.ui').then(({ initialize }) => initialize(params)),
});
index.worker
index.worker
是主要的 onAction
注册。 它处理 Fabric 主机发送的事件,这些事件通过执行的操作触发。
这些操作可由工作负载发送到 Fabric,然后调用回 onAction
处理程序,也可由 Fabric 主机启动。 例如,选择“创建示例项 - 仅前端”时,Fabric 会触发操作 open.createSampleWorkloadFrontendOnly
,而 onAction
处理程序会启动打开工作负载主要 UI 页面。 当前工作区 objectId
值也会传入仅限前端的体验。
下面的代码示例中演示了此序列:
workloadClient.action.onAction((message) => {
switch (message.action) {
/**
* This opens the frontend-only experience, so you can experiment with the UI without using CRUD operations.
* You can still save the item if the backend is connected and registered.
*/
case 'open.createSampleWorkloadFrontendOnly':
const { workspaceObjectId: workspaceObjectId1 } = data as ItemCreateContext;
return workloadClient.page.open({
workloadName: 'Org.WorkloadSample',
route: {
path: `/sample-workload-frontend-only/${workspaceObjectId1}`,
},
});
// . . . elided for brevity . . .
default:
throw new Error('Unknown action received');
}
});
index.ui
initialize()
函数呈现嵌入 App
函数的 React DOM。 要进行 API 调用,传递 workloadClient
SDK 句柄,此句柄在整个代码中使用。
FluentProvider
类确保在各种 FluentUI 控件之间保持样式一致性。 下面是一个示例:
ReactDOM.render(
<FluentProvider theme={fabricLightTheme}>
<App
history={history}
workloadClient={workloadClient}
/>
</FluentProvider>,
document.querySelector("#root")
);
开发流
App
函数将代码路由到SampleWorkloadEditor
。 该函数返回React.JSX.Element
的值。- 该函数包含 UI 结构。 UI 结构包含功能区和页面控件,如按钮和输入字段。
- 从用户收集的信息通过 React
useState()
挂钩存储。 - UI 控件的处理程序会调用
SampleWorkloadController
函数,并传递相关的状态变量。 - 为了支持 CRUD 操作,创建/加载项的状态以及
workspaceObjectId
和有效负载变量的实现示例将存储在artifactItem
中。
以下示例使用 notification.open() API:
状态:
const [apiNotificationTitle, setNotificationTitle] = useState<string>(''); const [apiNotificationMessage, setNotificationMessage] = useState<string>('');
UI:
这些示例配置特定的 UI 元素:
标题:
<Field label="Title" validationMessage={notificationValidationMessage} orientation="horizontal" className="field"> <Input size="small" placeholder="Notification Title" onChange={e => setNotificationTitle(e.target.value)} /> </Field>
“发送”按钮:
<Button icon={<AlertOn24Regular />} appearance="primary" onClick={() => onCallNotification()} > Send Notification </Button>
处理程序:
function onCallNotification() { ... elided for brevity callNotificationOpen(apiNotificationTitle, apiNotificationMessage, undefined, undefined, workloadClient, setNotificationId); };
控制器:
export async function callNotificationOpen( title: string, message: string, type: NotificationType = NotificationType.Success, duration: NotificationToastDuration = NotificationToastDuration.Medium, workloadClient: WorkloadClientAPI, setNotificationId?: Dispatch<SetStateAction<string>>) { const result = await workloadClient.notification.open({ notificationType: type, title, duration, message }); if (type == NotificationType.Success && setNotificationId) { setNotificationId(result?.notificationId); } }
CRUD 操作
虽然仅限前端的开发方案很容易得到支持,但完整的端到端开发人员体验需要保存、读取和编辑现有的工作负载项。
后端实现指南详细介绍了如何设置和使用后端。
后端启动并运行且 Org.WorkloadSample.SampleWorkloadItem
类型在 Fabric 中注册后,就可以对此类型执行 CRUD 操作。
以下操作是使用 ItemCrud API 公开的。
CREATE
若要举例调用 create
,请使用以下示例来演示如何首次保存工作负载项:
const params: CreateItemParams = {
workspaceObjectId,
payload: { itemType, displayName, description, workloadPayload: JSON.stringify(workloadPayload), payloadContentType: "InlineJson", }
};
const result: CreateItemResult = await workloadClient.ItemCrud.createItem(params);
我们的实现示例将创建的项存储在 artifactItem
中。
该项在当前选定的工作区中创建。 必须为工作区分配后端配置中设定的容量。 有关详细信息,请参阅后端文档。
尝试在不兼容的工作区下创建项失败:
后端中的
onCreateFabricItem
回调会阻止CREATE
调用。 此时失败会导致操作失败,并且 Fabric 中未创建任何项。 有关详细信息,请参阅后端的调试和故障排除文档。目前,已保存项不会自动显示在工作区中。 若要查看工作区中保存的项,请刷新页面。
GET
在工作区视图中选择现有示例工作负载项时,Fabric 会转到在 artifacts
>editor
>path
中的前端清单中定义的路由:
"items": [
{
"name": "Org.WorkloadSample.SampleWorkloadItem",
"editor": {
"workload": "Org.WorkloadSample",
"path": "/sample-workload-editor"
},
调用 itemCrud.getItem
时,将同事从 Fabric 后端和工作负载后端加载数据。 这两个源中的数据将加载到打开的 GUI 的 artifactItem
对象中。
UPDATE
若要更新现有项,请使用 itemCrud.updateItem
。 工作负载的有效负载由工作负载后端更新。 在 Fabric 中,在更新后仅项的 lastModifiedTime
更改。
DELETE
可以在 Fabric 工作区视图中以可用于所有项的常规操作的形式调用 delete
操作,也可以从工作负载中通过显式调用 itemCrud.deleteItem
来调用该操作。
这两种类型的调用都会经历工作负载后端的 onDeleteItem
回调。
查看身份验证活动
在示例工作负载编辑器中,可以查看身份验证活动。
在使用身份验证 API 之前,请将应用配置为使用 Microsoft Entra ID 进行身份验证。
此外,请确保正确配置 env.dev 文件。 有关详细信息,请参阅配置工作负载本地清单并获取应用程序的令牌。
调试
若要在浏览器中查看辅助角色和 UI iframe 元素,请选择 F12 以打开浏览器开发人员工具。 选择“选项”选项卡。
可以在辅助角色 iframe 元素中设置断点,并查看传入操作上的主 switch
。 还可以调试 UI iframe 元素。 例如,可以在 SampleWorkloadEditor
中调试代码。
Fluent UI 控件
UX 工作负载使用 Fluent UI 控件确保与 Fabric 的外观保持一致并方便开发。 示例工作负载项目提供了关于如何使用最常见控件的示例。
有关详细信息,请参阅 Fluent UI。
前端清单自定义
前端清单描述了工作负载的前端方面,包括产品外观、名称、视觉资产和可用操作。 前端清单是 Fabric 和工作负载之间的主要联系点。
对于示例工作负载,清单在开发人员模式下加载到 Fabric 中。 清单部分、定义和清单示例显示在前端清单文件中。
刷新页面后,将实时显示清单的条目和操作设置的更改以及视觉资产的更新。
客户端 SDK 支持的 API
支持以下 API:
- notification.open
- notification.hide
- panel.open
- panel.close
- action.onAction
- action.execute
- navigation.navigate
- navigation.onNavigate
- navigation.onBeforeNavigateAway
- navigation.onAfterNavigateAway
- page.open
- dialog.openDialog
- dialog.openMessageBox
- dialog.close
- theme.get
- theme.onChange
- settings.get
- settings.onChange
- errorHandling.openErrorDialog
- errorHandling.handleRequestFailure
- itemCrud.createItem
- itemCrud.getItem
- itemCrud.updateItem
- itemCrud.deleteItem
- itemSchedule.runItemJob
- itemSchedule.cancelItemJob
- itemRecentRuns.open
有关详细信息,请参阅 @ms-fabric/workload-client 包。