@e-llm-studio/审计日志
灵活而可调和 反应 库用于提供审计 / 更改- 日志表面, 包括搜索、 排序、 高级过滤、 无限卷轴、 可扩展行细节以及版本恢复 .
它运送一个投放组件—— <AuditLog /> 从几个API终点连接所有东西, 加号 每个子组件被单独导出, 这样您就可以自己编程用户界面 .
软件包 :
@e-llm-studio/audit-log部分内容: e-LLM Studio 组件库
目录
- 你得到的东西
- 安装
- 设置( 样式 + 路由器)
- 快开始
<AuditLog />——完全参考文献- 这个
LogRow形状 - 行为细节
<AuditLog />实例- API合同
- 使用单个组成部分
- 出口参考
- 抓到他们了
1. 所得情况
<AuditLog /> 使完整的审计记录表面:
- A 类 工具栏 关键字搜索(已解开),取出日期段,排序菜单(Lasters / Olest / impact% 高QQLow)和 a 过滤器 按钮.
- A 类 右侧侧边栏 ——多选取"修改由来","更改标题","日期-范围过滤","影响百分比"范围滑动. 使用模式草案(修改仅适用于 应用过滤器) (中文(简体) ).
- A 类 虚拟化数据表 无限卷轴,每行 恢复此版本 动作,可选 可扩展行细节和内线恢复祝酒.
- 一个 内部数据层 ——调用您光标贴出的审计 API,自动集成侧边栏下放,并处理还原. 或者你完全控制外部的数据.
搜索、日期范围、排序、分析过滤器、更改标题过滤器的 URL 状态和撞击范围通过自动处理 react-router-dom是因为 useSearchParams,因此链接是可共享的,后键起作用.
每个子部件——表格、工具栏、侧边栏、取日期器、多选择、撞击滑块——也单独导出,以便完全自定义布局(见 第10节) (中文(简体) ).
2. 安装
npm install @e-llm-studio/audit-log
同伴依赖关系
您的主机应用程序必须提供这些( 它们是 没有 捆绑:
{
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^7.6.2",
"lucide-react": "^0.476.0",
"primeicons": "^7.0.0",
"primereact": "^10.9.7"
}
npm install react react-dom react-router-dom lucide-react primeicons primereact
3. 设置(样式+路由器)
1. 一次导入样式表 (例如,在应用程序入口):
import "@e-llm-studio/audit-log/dist/styles.css";
2. 路由器内部的渲染. 过滤状态存在于 URL, 因此组件必须挂载在 <BrowserRouter> (或任何路由器显示) useSearchParams:
import { BrowserRouter } from "react-router-dom";
<BrowserRouter>
{/* ...your routes, including the page that renders <AuditLog /> */}
</BrowserRouter>
4. 快速启动
import { AuditLog } from "@e-llm-studio/audit-log";
import { useParams } from "react-router-dom";
export function AuditLogPage() {
const { id: externalResourceId } = useParams();
const API = import.meta.env.VITE_BASE_API_URL;
return (
<AuditLog
configId="6a0ab685346f096a6934b358"
getData={{ baseUrl: API, endpoint: "/claims-management-mode/audits/" }}
distinctValuesApi={{ baseUrl: API, endpoint: "/audit-log/distinct-values" }}
restoreApi={{ baseUrl: API, endpoint: "/audit-log/restore", method: "POST" }}
query={{
externalResourceId: [externalResourceId!],
paginationLimit: 20,
}}
table={{ tableProps: { scrollHeight: "60vh" } }}
/>
);
}
这是一个功能齐全的审计日志页面:数据获取,过滤,排序,无限卷轴,侧条倒放,并恢复.
5 (韩语). <AuditLog /> ——完全参考文献
| Prop | 类型 | 需求 | 说明 |
|---|---|---|---|
configId | string | ✅ | 向每个审计API呼叫发送了租户/配置标识符. |
accessToken | string | ✅ | 发送为 Authorization: Bearer <accessToken> 编辑 getData 财务报告和审定财务报表 distinctValuesApi 请求. |
getData | { baseUrl: string; endpoint: string } | 选项1 | 内部获取的API(POST) (中文(简体) ). 需要,除非您使用外部 data。 。 。 . |
distinctValuesApi | { baseUrl: string; endpoint?: string } | 选项 | 如果提供,侧边栏"被修改"和"变化标题"的下行会自动被人口. endpoint 默认为 /audit-log/distinct-values。 。 。 . |
restoreApi | { baseUrl: string; endpoint: string; method?: "POST" | "PUT" } | 选项 | 启用 恢复此版本 按钮。 没有它,只恢复记录一个警告. |
query | { externalResourceId?: string[]; paginationLimit?: number } | 选项 | 用于将日志和页面大小( 以pageSize)为作相. |
filters | Partial<LogFiltersProps> | 选项 | 工具栏的通道覆盖 。 见 第10.2节。 。 。 . |
sidebar | Partial<LogFiltersSidebarProps> | 选项 | 滤波器侧边栏的通过覆盖 。 见 第10.3节。 。 。 . |
table | Partial<LogTableProps> | 选项 | 数据表的通过覆盖。 见 第10.1节。 。 。 . |
config | { showFilters?: boolean; showSidebar?: boolean } | 选项 | 切换整个小节。 两者默认为 true。 。 。 . |
data | LogRow[] | 选项 | 外部数据模式. 跳过内部取取器并制作这些行. |
loading | boolean | 选项 | 初始负载旗 (外部模式). |
loadingMore | boolean | 选项 | "爬取更多"旗 (外模式). |
hasMore | boolean | 选项 | 是否存在更多行( 外部模式) . |
onLoadMore | () => void | 选项 | 无限回转( 外部模式) . |
refetchKey | string | number | 选项 | 更改此值以强制进行内部回溯( 例如在其他地方发生突变后) . |
1 如果两者兼有
data财务报告和审定财务报表getData被通过, 外部数据获胜 ——内取被禁用.
6. 决 议 LogRow 形状
type LogRow = {
id?: string; // table key; auto-derived from change_log_id
historyId?: string; // used as the key for restore
modifiedBy?: string;
actionType?: string; // shown as the chip label in "Change Summary"
actionText?: string; // long text (truncated at 95 chars w/ "See More")
actionDate?: string; // ISO date string
updatedByICE?: boolean; // when true, "Modified By" shows "ICE"
isLive?: boolean; // when true, shows a red "Live" pill instead of Restore
[key: string]: any;
};
当使用内部取取器时,原始 API 响应会自动正常化为这个形状(参见 第9.1节) (中文(简体) ). 在外部模式中,您必须提供匹配此形状的行 .
7. 行为细节
URL 状态
组件通过 URL 存储过滤状态 react-router-dom数字 :
| URL 参数 | 含义 |
|---|---|
keyword | 搜索输入( 已发出350 ms) |
createdAtStart 编号 : createdAtEnd | 日期范围( ISO 字符串) |
orderBy | latest (违约), oldest, (中文(简体) ), impactHighToLow,或 impactLowToHigh |
userEmails | 逗号分隔列表( 由修改后) |
changeTitles | 逗号分隔列表( 更改标题) |
impactMin 编号 : impactMax | 影响百分比范围(应用的设定) |
cursor | 每次过滤器更改时清除 |
边栏草稿状态
边栏使用 草案 模型 – 选择是本地的,直到用户点击为止 应用过滤器,将其写入 URL. 重置过滤器 清除草稿和应用的 URL 状态.
无穷卷轴
内部取取器基于光标 。 当用户滚动到下方的100 px(或者当内容不够高以滚动时), fetchMore() 火灾。 在初始装入时和"再装入"时在底部会变质.
恢复流量
- 用户点击 恢复此版本 - 按钮显示"恢复...".
POST编号 :PUT{baseUrl}{endpoint}调用{ change_log_id }。 。 。 .- 关于成功,内部数据
refetch()s和成功土司秀(通过table.restoreToast) (中文(简体) ). - 带行
isLive === true显示红色 现场直播 药而不是还原按钮.
可扩展行细节
过 table.rowDetail.render 将您自己的内容放入被点击行(AI摘要、diffs、请求/响应有效载荷等)。 默认受孕;通过 multiple: true 允许数个同时打开。 见 第10.1节。 。 。 .
8. 联合国. <AuditLog /> 实例
8.1 最小- API 驱动, 所有默认
<AuditLog
configId={CONFIG_ID}
getData={{ baseUrl: API, endpoint: "/audits" }}
query={{ externalResourceId: [resourceId] }}
/>
8.2 侧边栏倒放+恢复
<AuditLog
configId={CONFIG_ID}
getData={{ baseUrl: API, endpoint: "/audits" }}
distinctValuesApi={{ baseUrl: API }} // endpoint defaults
restoreApi={{ baseUrl: API, endpoint: "/restore" }}
query={{ externalResourceId: [resourceId], paginationLimit: 25 }}
/>
8.3 外部数据模式(您控制获取)
const { rows, isLoading, hasMore, loadMore } = useMyAuditQuery(resourceId);
<AuditLog
configId={CONFIG_ID}
data={rows}
loading={isLoading}
hasMore={hasMore}
onLoadMore={loadMore}
restoreApi={{ baseUrl: API, endpoint: "/restore" }}
/>
8.4 隐藏边栏,只保留工具栏+表格
<AuditLog
configId={CONFIG_ID}
getData={{ baseUrl: API, endpoint: "/audits" }}
query={{ externalResourceId: [resourceId] }}
config={{ showSidebar: false }}
filters={{ config: { showFilterButton: false } }}
/>
8.5 限制排序选项+影响范围
<AuditLog
configId={CONFIG_ID}
getData={{ baseUrl: API, endpoint: "/audits" }}
query={{ externalResourceId: [resourceId] }}
filters={{
config: {
sortOptions: { latest: true, oldest: true, impactHighToLow: false, impactLowToHigh: false },
},
}}
sidebar={{
impactRangeLimits: { min: 0, max: 50 }, // clamp the slider
config: { showImpactPercentage: true },
}}
/>
8.6 可扩展行细节
<AuditLog
configId={CONFIG_ID}
getData={{ baseUrl: API, endpoint: "/audits" }}
query={{ externalResourceId: [resourceId] }}
table={{
rowDetail: {
expandOnRowClick: true, // default
multiple: false, // accordion (default)
render: (row, { close }) => (
<div style={{ padding: 16 }}>
<h4>Change detail — {row.actionType}</h4>
<pre>{row.actionText}</pre>
<button onClick={close}>Close</button>
</div>
),
},
}}
/>
8.7 添加自定义一栏 + tweak 芯片颜色
import { ShieldCheck } from "lucide-react";
<AuditLog
configId={CONFIG_ID}
getData={{ baseUrl: API, endpoint: "/audits" }}
query={{ externalResourceId: [resourceId] }}
table={{
hiddenColumns: ["logId"],
extraColumns: [
{
key: "severity",
header: "Severity",
body: (row) => <span>{row.severity ?? "—"}</span>,
style: { width: "120px" },
},
],
chipConfig: {
getTone: (row) => (row.modifiedBy === "ICE" ? "orange" : "purple"),
getIcon: () => <ShieldCheck size={12} />,
},
tableProps: { scrollHeight: "70vh" },
emptyState: {
title: "No changes yet",
description: "Edit the record to see audit entries here.",
},
}}
/>
8.8 定制还原土司
<AuditLog
configId={CONFIG_ID}
getData={{ baseUrl: API, endpoint: "/audits" }}
restoreApi={{ baseUrl: API, endpoint: "/restore" }}
query={{ externalResourceId: [resourceId] }}
table={{
restoreToast: {
enabled: true, // set false to suppress and handle toasts yourself
position: "top-right",
life: 4000,
success: { summary: "Restored", detail: (id) => `Reverted to ${id}` },
error: { summary: "Oops", detail: () => "Restore failed, try again." },
},
}}
/>
8.9 本地化标签
<AuditLog
configId={CONFIG_ID}
getData={{ baseUrl: API, endpoint: "/audits" }}
query={{ externalResourceId: [resourceId] }}
sidebar={{
labels: {
title: "Filtrer par",
multiSelectLabel: "Modifié par",
dateLabel: "Sélectionner une date",
changeTitleLabel: "Titre du changement",
impactPercentageTitle: "Pourcentage d'impact",
},
}}
/>
8.10 分析——利用每一项互动
<AuditLog
configId={CONFIG_ID}
getData={{ baseUrl: API, endpoint: "/audits" }}
query={{ externalResourceId: [resourceId] }}
filters={{
onChange: {
onSearch: (v) => analytics.track("audit_search", { v }),
onSort: (v) => analytics.track("audit_sort", { v }),
},
}}
sidebar={{
onApply: () => analytics.track("audit_filter_apply"),
onReset: () => analytics.track("audit_filter_reset"),
}}
/>
9. API合同
9.1 国家 getData - 审计记录检索
请求 —— 说 POST {baseUrl}{endpoint}数字 :
{
"configId": "string",
"filters": {
"externalResourceId": ["string"],
"userEmails": ["string?"],
"changeTitle": ["string?"],
"content": "string?",
"modifiedDateStart": "ISO date?",
"modifiedDateEnd": "ISO date?",
"orderBy": "latestFirst", // | oldestFirst | impactPercentageHighToLow | impactPercentageLowToHigh
"impactPercentageStart": 0, // only sent once the impact filter is applied
"impactPercentageEnd": 100
},
"pageSize": 20,
"cursor": "opaque-cursor-from-previous-page?"
}
回应 - 图书馆恢复正常 items 输入 LogRow编号:
{
"data": {
"items": [
{
"change_log_id": "string", // → id + historyId
"external_resource_id": "string",
"modifiedbyname": "string", // → modifiedBy
"modifiedbyemail": "string",
"changeTitle": "string", // → actionType
"change": "string", // → actionText
"created_at": "ISO date" // → actionDate
}
],
"nextCursor": "string?",
"hasNext": true
}
}
9.2 (中文(简体) ) distinctValuesApi
请求 —— 说 GET {baseUrl}{endpoint}/{configId}?external_resource_id=... (每id一个查询参数). endpoint 默认为 /audit-log/distinct-values。 。 。 .
回应数字 :
{
"success": true,
"data": {
"change_made_title": ["string"], // → Change Title options
"change_made_by_user": { "User Name": "user@x" }, // → Modified By options (label: name, value: email)
"truncated": false
}
}
第9.3条 restoreApi
请求 —— 说 POST (或 PUT(中文(简体) ) {baseUrl}{endpoint}数字 :
{ "change_log_id": "string" }
非-2xx 响应抛出 Failed to restore audit version。 。 。 .
10. 使用各个组成部分
每个块都会被导出, 这样您可以编成一个按键布局 而不是使用 <AuditLog />。一次导入样式表(第3节),无论您使用的组件.
import {
LogTable,
LogFilters,
LogFiltersSidebar,
DateRangeSelector,
ImpactRangeSelector,
CustomMultiSelect,
ActionTakenBody,
} from "@e-llm-studio/audit-log";
10.1 对 LogTable 数据表
渲染出行,无限相接骨架,空出状态,芯片+还原细胞,可选择可扩展细节. 你个 拥有数据与页码.
| Prop | 类型 | 说明 |
|---|---|---|
rows | LogRow[] | 画出一行来. |
loading 编号 : loadingMore | boolean | 初始负载 / 负载- 更多旗帜 . |
hasMore | boolean | 有无多行相. |
onLoadMore | () => void | 以自来自来自来自去. |
emptyState | { title?; description? } | 空状态副本. |
hiddenColumns | string[] | 按键隐藏内置 : logId, (中文(简体) ), modifiedBy, (中文(简体) ), changeSummary, (中文(简体) ), changeDateTime, (中文(简体) ), actions。 。 。 . |
extraColumns | { key; header; body; style? }[] | 附加列,或 替换 一个内置的,通过重用它的密钥. |
chipConfig | { getTone?; getIcon?; getStyle? } | 每行芯片定制. getTone 返回用作 audit-chip--{tone}。 。 。 . |
tableProps | Record<string, any> | 已逐字传送到 PrimeReact <DataTable> (单位:千美元)scrollHeight, (中文(简体) ), className(中文(简体) ). |
onRowClick | (row, helpers) => void | 点起一行起火. helpers数字 : { isExpanded, expand, collapse, toggle }。忽略点击按钮/链接/输入. |
rowDetail | { render; expandOnRowClick?; multiple?; className?; style? } | 消费者在一行点击下提供内含细节. render(row, { close })。 。 。 . |
restoringId | string | null | 标记当前恢复的行. |
onRestore | (historyId) => void | Promise | 点击恢复按钮时调用 . |
restoreToast | { enabled?; position?; life?; success?; error? } | 内置PrimeReact 吐司配置. |
import { LogTable } from "@e-llm-studio/audit-log";
function MyTable({ rows, hasMore, loadMore, loading }) {
return (
<LogTable
rows={rows}
loading={loading}
hasMore={hasMore}
onLoadMore={loadMore}
chipConfig={{ getTone: (r) => (r.updatedByICE ? "orange" : "purple") }}
onRestore={async (id) => myRestoreApi(id)}
rowDetail={{
render: (row, { close }) => (
<div style={{ padding: 12 }}>
{row.actionText}
<button onClick={close}>Close</button>
</div>
),
}}
tableProps={{ scrollHeight: "65vh" }}
/>
);
}
10.2 国家 LogFilters 工具栏
控制搜索 / 日期/ 排序工具栏 . value 财务报告和审定财务报表 onChange 需要这样做.
| Prop | 类型 | 说明 |
|---|---|---|
value | { search?; dateRange?; sort? } | 当前工具栏状态 . |
onChange | { onSearch?; onDate?; onSort? } | 换接头. |
config | { showSearch?; showDate?; showSort?; showFilterButton?; sortOptions? } | 切换碎片 . sortOptions 切换每个 latest编号 :oldest编号 :impactHighToLow编号 :impactLowToHigh。 。 。 . |
onOpenFilter | () => void | 单击“过滤器”按钮时已开火. |
import { LogFilters, SortOrder, DateRange } from "@e-llm-studio/audit-log";
import { useState } from "react";
function Toolbar() {
const [search, setSearch] = useState("");
const [dateRange, setDateRange] = useState<DateRange>({ start: null, end: null });
const [sort, setSort] = useState<SortOrder>("latest");
return (
<LogFilters
value={{ search, dateRange, sort }}
onChange={{ onSearch: setSearch, onDate: setDateRange, onSort: setSort }}
config={{ showFilterButton: true }}
onOpenFilter={() => console.log("open sidebar")}
/>
);
}
第10.3条 LogFiltersSidebar ——过滤面板
右侧主反射 Sidebar 带有多选择、日期范围以及撞击滑动器。 完全控制.
| Prop | 类型 | 说明 |
|---|---|---|
visible 编号 : onHide | boolean 编号 : () => void | 开通州. |
options 编号 : selectedValues 编号 : onChange | —— 说 | "被修改"多选取. |
changeTitleOptions 编号 : selectedChangeTitles 编号 : onChangeTitleChange | —— 说 | "变化标题"多选取. |
dateRange 编号 : onDateRangeChange | —— 说 | 约会范围过滤器. |
impactRange 编号 : impactRangeLimits 编号 : onImpactRangeChange | ImpactRange | 影响百分比滑动器{ min, max }) (中文(简体) ). |
onApply 编号 : onReset | () => void | 脚步动作. |
config | { showAnalystFilter?; showDateFilter?; showChangeTitleFilter?; showImpactPercentage? } | 切换块. |
labels | 对象 | 将每个标签/信息/标题本地化. |
import { LogFiltersSidebar } from "@e-llm-studio/audit-log";
<LogFiltersSidebar
visible={open}
onHide={() => setOpen(false)}
options={[{ label: "Renee Ramirez", value: "[email protected]" }]}
selectedValues={analysts}
onChange={setAnalysts}
dateRange={dateRange}
onDateRangeChange={setDateRange}
impactRange={impact}
impactRangeLimits={{ min: 0, max: 100 }}
onImpactRangeChange={setImpact}
onApply={applyFilters}
onReset={resetFilters}
/>
10.4 国家 DateRangeSelector - 测距取日期器
自足日/月/年测距取取器,并附有草稿+应用/重置. 注:承诺 end 保存为 独家 (视觉所选择的结束一天之后).
import { DateRangeSelector, DateRange } from "@e-llm-studio/audit-log";
import { useState } from "react";
const [range, setRange] = useState<DateRange>({ start: null, end: null });
<DateRangeSelector
value={range}
onChange={setRange}
maxDate={new Date()}
endIcon // render the calendar icon on the right (sidebar style)
/>
10.5 (中文(简体) ) ImpactRangeSelector 分钟/最大滑动器
PrimeReact 范围滑动器,带有数值Min/Max输入.
import { ImpactRangeSelector, ImpactRange } from "@e-llm-studio/audit-log";
import { useState } from "react";
const [impact, setImpact] = useState<ImpactRange>({ min: 0, max: 100 });
<ImpactRangeSelector value={impact} onChange={setImpact} min={0} max={100} />
10.6 国家 CustomMultiSelect ——可搜索多选择
轻量级的复选箱倒下,有搜索和"All".
import { CustomMultiSelect, SelectOption } from "@e-llm-studio/audit-log";
import { useState } from "react";
const options: SelectOption[] = [
{ label: "Renee Ramirez", value: "[email protected]" },
{ label: "ICE", value: "[email protected]" },
];
const [selected, setSelected] = useState<string[]>([]);
<CustomMultiSelect
options={options}
value={selected}
onChange={setSelected}
placeholder="Select analysts"
/>
10.7 国家 ActionTakenBody ——芯片+短写文本单元格
台内使用的芯片-外加-"见多"电池渲染器. 用作自定义列 body。 。 。 .
import { ActionTakenBody } from "@e-llm-studio/audit-log";
import { FileText } from "lucide-react";
<ActionTakenBody
title="Field updated"
desciption={row.actionText} // note: prop spelling is `desciption`
tone="purple"
icon={<FileText size={12} />}
/>
11. 出口参考
// Components
import {
AuditLog, // the all-in-one component
LogTable,
LogFilters,
LogFiltersSidebar,
ActionTakenBody,
DateRangeSelector,
ImpactRangeSelector,
CustomMultiSelect,
} from "@e-llm-studio/audit-log";
// Types
import type {
LogRow,
RowClickHelpers,
RowDetailHelpers,
LogTableProps,
LogFiltersProps,
SortOrder,
LogFiltersSidebarProps,
LogFiltersSidebarOption,
DateRange,
ImpactRange,
SelectOption,
} from "@e-llm-studio/audit-log";
// Styles (import once)
import "@e-llm-studio/audit-log/dist/styles.css";
12. 获奖者
<AuditLog />必须 在一个路由器内渲染 —— 过滤状态存在于 URL.- 别忘了 导入样式表 (单位:千美元)
dist/styles.css),或UI会被取消样式. - 若为
query.externalResourceId是空的/ 未定义的, 内部获取器不会开火 . distinctValuesApi以懒散方式取出——只有在侧边栏可见时(config.showSidebar !== false) (中文(简体) ).restoreApi是选入;没有它,只恢复按钮console.warn编号.- 在外部数据模式下,您负责在恢复后进行回推 — 内部
refetch()被跳过。 使用refetchKey(内部模式)从父端强制更新 . paginationLimit以pageSize;如果省略,则由后端决定页面大小.- 撞击过滤器只发送到 API 一次 应用 (承诺
impactMin编号 :impactMax在 URL 中). ActionTakenBody描述道具的拼写desciption(tept for后向相容性).