Skip to content

Commit 7aeb28c

Browse files
show env, org, user, app names instead of id's in audit log page
1 parent 01b112d commit 7aeb28c

File tree

4 files changed

+114
-28
lines changed

4 files changed

+114
-28
lines changed

Diff for: client/packages/lowcoder/src/api/enterpriseApi.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,12 @@ export const getAuditLogStatistics = async (params = {}) => {
7272
};
7373

7474
export const getMeta = async (formData = {}) => {
75-
const response = await axios.post(`/api/meta`, formData);
75+
const response = await axios.post(`/api/meta/`, formData);
76+
return response.data;
77+
}
78+
79+
export const getEnvironmentsByIds = async (formData: string[] = []) => {
80+
const response = await axios.post(`/api/plugins/enterprise/environments/byIds`, formData);
7681
return response.data;
7782
}
7883

Diff for: client/packages/lowcoder/src/pages/setting/audit/components/statistics.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const Statistics = ({ stats }: { stats: AuditLogStat[] }) => {
2222
return (
2323
<Card size="small" variant="borderless" style={{marginBottom: '20px'}}>
2424
{stats.map(stat => (
25-
<Card.Grid hoverable={false} style={{width, padding: '12px'}}>
25+
<Card.Grid key={stat.eventType} hoverable={false} style={{width, padding: '12px'}}>
2626
<StyledStatistics
2727
title={stat.eventType.split('_').join(' ')}
2828
value={stat.groupCountResult}

Diff for: client/packages/lowcoder/src/pages/setting/audit/dashboard.tsx

+57-12
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ import {
1010
} from "../theme/styledComponents";
1111
import { HeaderBack } from "pages/setting/permission/styledComponents";
1212
import { getUser } from "@lowcoder-ee/redux/selectors/usersSelectors";
13-
import { getAuditLogs, getAuditLogStatistics } from "api/enterpriseApi";
13+
import { getAuditLogs, getAuditLogStatistics, getEnvironmentsByIds, getMeta } from "api/enterpriseApi";
1414
import EventTypeTimeChart from "./charts/eventTypesTime";
15-
import { debounce } from "lodash";
15+
import { debounce, uniqBy } from "lodash";
1616
import { DatePicker } from "antd";
1717
import dayjs, { Dayjs } from "dayjs";
1818
import { Link, useLocation } from "react-router-dom";
@@ -59,6 +59,7 @@ export function AuditLogDashboard() {
5959
const [allLogs, setAllLogs] = useState<AuditLog[]>([]);
6060
const [currentPageLogs, setCurrentPageLogs] = useState<AuditLog[]>([]);
6161
const [statistics, setStatistics] = useState<AuditLogStat[]>([]);
62+
const [dataMap, setDataMap] = useState<Record<string, any>>({});
6263

6364
const [total, setTotal] = useState(0);
6465
const [loading, setLoading] = useState(false);
@@ -94,12 +95,44 @@ export function AuditLogDashboard() {
9495
form.setFieldsValue(getQueryParams());
9596
}, []);
9697

97-
const getAuditLogStatsMap = (stats: AuditLogStat[]) => {
98-
const statsMap = {};
99-
stats.forEach(stat => {
100-
// statsMap.push({})
101-
})
102-
};
98+
const findUniqueDataIds = async () => {
99+
if (!allLogs.length) {
100+
return setDataMap({});
101+
}
102+
103+
const uniqueOrgIds: string[] = uniqBy(allLogs, 'orgId').map(item => item.orgId);
104+
const uniqueUserIds: string[] = uniqBy(allLogs, 'userId').map(item => item.userId);
105+
const uniqueEnvIds: string[] = uniqBy(allLogs, 'environmentId').map(item => item.environmentId);
106+
107+
const metaResponse = await getMeta({
108+
orgIds: uniqueOrgIds,
109+
userIds: uniqueUserIds,
110+
appIds: [],
111+
groupIds: [],
112+
bundleIds: [],
113+
datasourceIds: [],
114+
folderIds: [],
115+
libraryQueryIds: []
116+
});
117+
118+
const envResponse = await getEnvironmentsByIds(uniqueEnvIds);
119+
120+
const tempDataMap: Record<string, any> = {};
121+
metaResponse.data?.orgs?.forEach((org: { id: string; name: string; }) => {
122+
tempDataMap[org.id] = org.name;
123+
});
124+
metaResponse.data?.users?.forEach((user: { id: string; name: string; }) => {
125+
tempDataMap[user.id] = user.name;
126+
});
127+
envResponse.data?.forEach((env: { environmentId: string; environmentType: string; }) => {
128+
tempDataMap[env.environmentId] = env.environmentType;
129+
});
130+
setDataMap(tempDataMap);
131+
}
132+
133+
useEffect(() => {
134+
findUniqueDataIds();
135+
}, [allLogs]);
103136

104137
const getCleanedParams = (newPage?: number) => {
105138
const formValues = form.getFieldsValue();
@@ -308,26 +341,38 @@ export function AuditLogDashboard() {
308341
dataIndex: "environmentId",
309342
key: "environmentId",
310343
render: (text: string) => (
311-
<a onClick={() => handleClickFilter("environmentId", text)}>{text}</a>
344+
<a onClick={() => handleClickFilter("environmentId", text)}>{dataMap[text] ?? text}</a>
312345
),
313346
},
314347
{
315348
title: "Org ID",
316349
dataIndex: "orgId",
317350
key: "orgId",
318-
render: (text: string) => <a onClick={() => handleClickFilter("orgId", text)}>{text}</a>,
351+
render: (text: string) => (
352+
<a onClick={() => handleClickFilter("orgId", text)}>{dataMap[text] ?? text}</a>
353+
),
319354
},
320355
{
321356
title: "User ID",
322357
dataIndex: "userId",
323358
key: "userId",
324-
render: (text: string) => <a onClick={() => handleClickFilter("userId", text)}>{text}</a>,
359+
render: (text: string) => (
360+
<a onClick={() => handleClickFilter("userId", text)}>{dataMap[text] ?? text}</a>
361+
),
325362
},
326363
{
327364
title: "App ID",
328365
dataIndex: "appId",
329366
key: "appId",
330-
render: (text: string) => <a onClick={() => handleClickFilter("appId", text)}>{text}</a>,
367+
render: (text: string, record: any) => (
368+
<a onClick={() => handleClickFilter("appId", text)}>
369+
{
370+
record.details?.applicationName
371+
|| record.details?.applicationId
372+
|| '-'
373+
}
374+
</a>
375+
),
331376
}
332377
];
333378

Diff for: client/packages/lowcoder/src/pages/setting/audit/detail.tsx

+50-14
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,10 @@ import { Map, Marker } from "pigeon-maps"
1010
import Tree from "antd/es/tree";
1111
import Empty from "antd/es/empty";
1212
import { ReactNode, useEffect, useMemo, useState } from "react";
13-
import { getAuditLogs, getMeta } from "@lowcoder-ee/api/enterpriseApi";
13+
import { getAuditLogs, getEnvironmentsByIds, getMeta } from "@lowcoder-ee/api/enterpriseApi";
1414
import { isEmpty } from "lodash";
1515
import { getEventColor, getEventLabel } from "./dashboard";
1616
import Tag from "antd/es/tag";
17-
import { geoLocation } from "./auditContants";
1817

1918
const StyleThemeSettingsCover = styled.div`
2019
display: flex;
@@ -31,7 +30,28 @@ const StyledTree = styled(Tree)`
3130
}
3231
3332
.ant-tree-treenode {
34-
margin-bottom: 24px;
33+
margin-bottom: 12px;
34+
}
35+
36+
.ant-tree-node-content-wrapper {
37+
padding: 8px;
38+
}
39+
40+
.ant-tree-switcher {
41+
padding-top: 8px;
42+
&::before {
43+
top: 8px;
44+
}
45+
}
46+
47+
.ant-tree-switcher_open::after {
48+
content: "";
49+
width: 1px;
50+
height: 100%;
51+
position: absolute;
52+
left: 46%;
53+
top: 26px;
54+
background: #d9d9d9;
3555
}
3656
3757
.ant-descriptions-header {
@@ -63,8 +83,6 @@ const getResourceData = (eventType: string, eventDetail: any) => {
6383
return {
6484
ID: eventDetail.id, Name: eventDetail.name,
6585
}
66-
67-
return undefined;
6886
}
6987

7088
const EventTreeNode = (props: {
@@ -80,14 +98,16 @@ const EventTreeNode = (props: {
8098
title={<span>{props.icon} {props.title}</span>}
8199
>
82100
{Object.keys(props.data).map(dataKey => (
83-
<Descriptions.Item label={dataKey}>{props.data[dataKey] || '-'}</Descriptions.Item>
101+
<Descriptions.Item key={dataKey} label={dataKey}>{props.data[dataKey] || '-'}</Descriptions.Item>
84102
))}
85103
</Descriptions>
86104
)
87105
}
88106
export function AuditLogDetail() {
89107
const { eventId } = useParams<{eventId: string}>();
90108
const [ event, setEvent ] = useState<any>({});
109+
const [ meta, setMeta ] = useState<any>({});
110+
const [ environment, setEnvironment ] = useState<any>({});
91111

92112
const fetchEventData = async () => {
93113
const response = await getAuditLogs({ eventId });
@@ -107,8 +127,14 @@ export function AuditLogDetail() {
107127
folderIds: [],
108128
libraryQueryIds: []
109129
});
110-
console.log(response);
111-
// setEvent(response?.data?.[0]);
130+
setMeta(response.data);
131+
}
132+
133+
const fetchEnvironmentData = async () => {
134+
if (isEmpty(event)) return;
135+
136+
const response = await getEnvironmentsByIds([event.environmentId]);
137+
setEnvironment(response.data?.[0] || {});
112138
}
113139

114140
useEffect(() => {
@@ -117,7 +143,8 @@ export function AuditLogDetail() {
117143

118144
useEffect(() => {
119145
fetchEventMeta();
120-
}, [event]);
146+
fetchEnvironmentData();
147+
}, [JSON.stringify(event)]);
121148

122149
const eventHierarchy = useMemo(() => {
123150
if (isEmpty(event)) return [];
@@ -175,7 +202,10 @@ export function AuditLogDetail() {
175202
<EventTreeNode
176203
icon={<EnvironmentOutlined />}
177204
title="Environment"
178-
data={{ ID: event?.environmentId, Name: event?.environmentName}}
205+
data={{
206+
ID: event?.environmentId,
207+
Name: environment?.environmentType || '-'
208+
}}
179209
/>
180210
),
181211
key: "0",
@@ -185,7 +215,10 @@ export function AuditLogDetail() {
185215
<EventTreeNode
186216
icon={<TeamOutlined />}
187217
title="Workspace"
188-
data={{ ID: event?.orgId, Name: event?.orgName}}
218+
data={{
219+
ID: event?.orgId,
220+
Name: meta?.orgs?.[0]?.name || '-',
221+
}}
189222
/>
190223
),
191224
key: "0-0",
@@ -195,7 +228,10 @@ export function AuditLogDetail() {
195228
<EventTreeNode
196229
icon={<UserOutlined />}
197230
title="User"
198-
data={{ ID: event?.userId, Name: event?.userName}}
231+
data={{
232+
ID: event?.userId,
233+
Name: meta?.users?.[0]?.name || '-',
234+
}}
199235
/>
200236
),
201237
key: "0-0-0",
@@ -206,7 +242,7 @@ export function AuditLogDetail() {
206242
],
207243
},
208244
];
209-
}, [event]);
245+
}, [event, meta, environment]);
210246

211247
if (!Boolean(event)) {
212248
return (
@@ -254,7 +290,7 @@ export function AuditLogDetail() {
254290
<h2 style={{ color: "#ffffff", marginTop: "8px" }}>Browser / System Metadata</h2>
255291
</StyleThemeSettingsCover>
256292
<Card size="small" style={{ marginBottom: "20px", borderTopLeftRadius: 0, borderTopRightRadius: 0 }}>
257-
<Descriptions bordered column={1}>
293+
<Descriptions bordered column={1} size="small">
258294
<Descriptions.Item label={<span><ChromeOutlined className="text-lg mr-2" /> Browser</span>}>{event?.agentName}</Descriptions.Item>
259295
<Descriptions.Item label={<span><AppleOutlined className="text-lg mr-2" /> OS</span>}>{event?.operatingSystemName} ({event?.operatingSystemVersion})</Descriptions.Item>
260296
<Descriptions.Item label={<span><DesktopOutlined className="text-lg mr-2" /> Device</span>}>{event?.deviceName}</Descriptions.Item>

0 commit comments

Comments
 (0)