Skip to content

Commit 0f6c3bc

Browse files
author
FalkWolsky
committed
Display Workplace API Usage in Settings
1 parent c42d057 commit 0f6c3bc

File tree

10 files changed

+103
-26
lines changed

10 files changed

+103
-26
lines changed

client/packages/lowcoder/src/api/orgApi.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,14 @@ export class OrgApi extends Api {
133133
return Api.put(OrgApi.updateOrgURL(request.id), request);
134134
}
135135

136-
static fetchAPIUsage(orgId: string, lastMonthOnly?: boolean): AxiosPromise<ApiResponse> {
137-
return Api.get(OrgApi.fetchUsage(orgId), lastMonthOnly);
136+
static fetchAPIUsage(orgId: string): AxiosPromise<ApiResponse> {
137+
return Api.get(OrgApi.fetchUsage(orgId));
138138
}
139+
140+
static fetchLastMonthAPIUsage(orgId: string): AxiosPromise<ApiResponse> {
141+
return Api.get(OrgApi.fetchUsage(orgId), { lastMonthOnly: true });
142+
}
143+
139144
}
140145

141146
export default OrgApi;

client/packages/lowcoder/src/constants/reduxActionConstants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ export const ReduxActionTypes = {
102102
MARK_USER_STATUS: "MARK_USER_STATUS",
103103
FETCH_ORG_API_USAGE: "FETCH_ORG_API_USAGE",
104104
FETCH_ORG_API_USAGE_SUCCESS: "FETCH_ORG_API_USAGE_SUCCESS",
105+
FETCH_ORG_LAST_MONTH_API_USAGE: "FETCH_ORG_LAST_MONTH_API_USAGE",
106+
FETCH_ORG_LAST_MONTH_API_USAGE_SUCCESS: "FETCH_ORG_LAST_MONTH_API_USAGE_SUCCESS",
105107

106108
/* home data */
107109
FETCH_HOME_DATA: "FETCH_HOME_DATA",

client/packages/lowcoder/src/i18n/locales/en.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1908,7 +1908,11 @@ export const en = {
19081908
"preloadLibsAddBtn": "Add a Library",
19091909
"saveSuccess": "Saved Successfully",
19101910
"AuthOrgTitle": "Workspace Welcome Screen",
1911-
"AuthOrgDescrition": "The URL for Your Users to Sign In to the Current Workspace."
1911+
"AuthOrgDescrition": "The URL for Your Users to Sign In to the Current Workspace.",
1912+
"APIConsumption": "API Consumption",
1913+
"APIConsumptionDescription": "Here you can see the API Consumption for All Apps in the Current Workspace.",
1914+
"overallAPIConsumption": "Overall API Consumption in this Workspace till now",
1915+
"lastMonthAPIConsumption": "Last Month API Consumption, in this Workspace"
19121916
},
19131917

19141918

client/packages/lowcoder/src/i18n/locales/zh.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1809,6 +1809,10 @@ advanced: {
18091809
preloadLibsEmpty: "尚未添加 JavaScript 库",
18101810
preloadLibsAddBtn: "添加库",
18111811
saveSuccess: "保存成功",
1812+
"APIConsumption": "API 消耗",
1813+
"APIConsumptionDescription": "API 消耗是指当前工作空间中所有应用程序的 API 消耗情况,包括调用次数和调用时间.",
1814+
"overallAPIConsumption": "总体 API 消耗",
1815+
"apiCalls" : "API 调用次数",
18121816
},
18131817
branding: {
18141818
title: "品牌",

client/packages/lowcoder/src/pages/setting/advanced/AdvancedSetting.tsx

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ import React, { useEffect, useState } from "react";
77
import { useDispatch, useSelector } from "react-redux";
88
import { fetchCommonSettings, setCommonSettings } from "redux/reduxActions/commonSettingsActions";
99
import { getCommonSettings } from "redux/selectors/commonSettingSelectors";
10+
import { fetchAPIUsageAction, fetchLastMonthAPIUsageAction } from "redux/reduxActions/orgActions";
1011
import { getUser } from "redux/selectors/usersSelectors";
12+
import { getOrgApiUsage, getOrgLastMonthApiUsage } from "redux/selectors/orgSelectors";
1113
import styled from "styled-components";
1214
import { useShallowEqualSelector } from "util/hooks";
1315
import { Level1SettingPageContent, Level1SettingPageTitle } from "../styled";
@@ -24,6 +26,7 @@ import { getGlobalSettings } from "comps/utils/globalSettings";
2426
import { fetchJSLibrary } from "util/jsLibraryUtils";
2527
import { evalFunc } from "lowcoder-core";
2628
import { messageInstance } from "lowcoder-design";
29+
import Api from "@lowcoder-ee/api/api";
2730

2831
const AdvancedSettingContent = styled.div`
2932
max-width: 840px;
@@ -76,6 +79,16 @@ export function AdvancedSetting() {
7679
label: app.name,
7780
}));
7881

82+
const apiUsage = useSelector(getOrgApiUsage);
83+
useEffect(() => {
84+
dispatch(fetchAPIUsageAction(currentUser.currentOrgId));
85+
}, [currentUser.currentOrgId])
86+
87+
const lastMonthApiUsage = useSelector(getOrgLastMonthApiUsage);
88+
useEffect(() => {
89+
dispatch(fetchLastMonthAPIUsageAction(currentUser.currentOrgId));
90+
}, [currentUser.currentOrgId])
91+
7992
useEffect(() => {
8093
dispatch(fetchCommonSettings({ orgId: currentUser.currentOrgId }));
8194
dispatch(fetchAllApplications({}));
@@ -118,8 +131,8 @@ export function AdvancedSetting() {
118131

119132
const isNotChange = JSON.stringify(commonSettings) === JSON.stringify(settings);
120133
const extraAdvanceSettings = useExtraAdvanceSettings();
121-
122134
const runJSInHost = getGlobalSettings().orgCommonSettings?.runJavaScriptInHost ?? false;
135+
123136
return (
124137
<Level1SettingPageContent>
125138
<Prompt
@@ -262,6 +275,12 @@ export function AdvancedSetting() {
262275
)}
263276
</div>
264277
{extraAdvanceSettings}
278+
<div className="section-title">{trans("advanced.APIConsumption")}</div>
279+
<HelpText style={{ marginBottom: 12 }}>{trans("advanced.APIConsumptionDescription")}</HelpText>
280+
<div className="section-content">
281+
{trans("advanced.overallAPIConsumption")} : {apiUsage ? Intl.NumberFormat('en-GB', { maximumFractionDigits: 2 }).format(apiUsage) + " API Calls.": 'Loading API usage data...'}<br/>
282+
{trans("advanced.lastMonthAPIConsumption")} : {lastMonthApiUsage ? Intl.NumberFormat('en-GB', { maximumFractionDigits: 2 }).format(lastMonthApiUsage) + " API Calls." : 'Loading API usage data...'}
283+
</div>
265284
</AdvancedSettingContent>
266285
</Level1SettingPageContent>
267286
);

client/packages/lowcoder/src/pages/setting/index.tsx

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,6 @@ import SettingHome from "./settingHome";
99
export function Setting() {
1010
const user = useSelector(getUser);
1111

12-
/* fetch Org's API usage
13-
14-
const apiUsage = useSelector(getOrgApiUsage);
15-
useEffect(() => {
16-
dispatch(fetchAPIUsageAction(user.currentOrgId));
17-
}, [user.currentOrgId])
18-
19-
*/
20-
2112
if (!currentOrgAdminOrDev(user)) {
2213
history.push(BASE_URL);
2314
}

client/packages/lowcoder/src/redux/reducers/uiReducers/orgReducer.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
DeleteOrgUserPayload,
1010
GroupUsersPayload,
1111
OrgAPIUsagePayload,
12+
OrgLastMonthAPIUsagePayload,
1213
OrgUsersPayload,
1314
RemoveGroupUserPayload,
1415
} from "redux/reduxActions/orgActions";
@@ -26,6 +27,7 @@ const initialState: OrgReduxState = {
2627
fetchOrgGroupsFinished: false,
2728
orgCreateStatus: "init",
2829
apiUsage: 0,
30+
lastMonthApiUsage: 0,
2931
};
3032

3133
const orgReducer = createImmerReducer(initialState, {
@@ -106,13 +108,22 @@ const orgReducer = createImmerReducer(initialState, {
106108
...state,
107109
orgCreateStatus: "error",
108110
}),
111+
109112
[ReduxActionTypes.FETCH_ORG_API_USAGE_SUCCESS]: (
110113
state: OrgReduxState,
111114
action: ReduxAction<OrgAPIUsagePayload>
112115
): OrgReduxState => ({
113116
...state,
114117
apiUsage: action.payload.apiUsage,
115-
})
118+
}),
119+
120+
[ReduxActionTypes.FETCH_ORG_LAST_MONTH_API_USAGE_SUCCESS]: (
121+
state: OrgReduxState,
122+
action: ReduxAction<OrgLastMonthAPIUsagePayload>
123+
): OrgReduxState => ({
124+
...state,
125+
lastMonthApiUsage: action.payload.lastMonthApiUsage,
126+
}),
116127
});
117128

118129
export interface OrgReduxState {
@@ -125,6 +136,7 @@ export interface OrgReduxState {
125136
fetchOrgGroupsFinished: boolean;
126137
orgCreateStatus: ApiRequestStatus;
127138
apiUsage: number;
139+
lastMonthApiUsage: number;
128140
}
129141

130142
export default orgReducer;

client/packages/lowcoder/src/redux/reduxActions/orgActions.ts

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -152,24 +152,43 @@ export const updateOrgSuccess = (payload: UpdateOrgPayload) => {
152152
};
153153
};
154154

155+
156+
// till now
155157
export type OrgAPIUsagePayload = {
156158
apiUsage: number,
157159
};
158-
159160
export const fetchAPIUsageAction = (
160161
orgId: string,
161-
lastMonthOnly?: boolean,
162162
) => ({
163163
type: ReduxActionTypes.FETCH_ORG_API_USAGE,
164164
payload: {
165165
orgId,
166-
lastMonthOnly,
167166
},
168167
});
169168

170-
export const fetchAPIUsageSuccessAction = (apiUsage: number) => ({
171-
type: ReduxActionTypes.FETCH_ORG_API_USAGE_SUCCESS,
169+
export const fetchAPIUsageActionSuccess = (payload: OrgAPIUsagePayload) => {
170+
return {
171+
type: ReduxActionTypes.FETCH_ORG_API_USAGE_SUCCESS,
172+
payload: payload,
173+
};
174+
};
175+
176+
// last month
177+
export type OrgLastMonthAPIUsagePayload = {
178+
lastMonthApiUsage: number,
179+
};
180+
export const fetchLastMonthAPIUsageAction = (
181+
orgId: string,
182+
) => ({
183+
type: ReduxActionTypes.FETCH_ORG_LAST_MONTH_API_USAGE,
172184
payload: {
173-
apiUsage,
185+
orgId,
174186
},
175187
});
188+
189+
export const fetchLastMonthAPIUsageActionSuccess = (payload: OrgLastMonthAPIUsagePayload) => {
190+
return {
191+
type: ReduxActionTypes.FETCH_ORG_LAST_MONTH_API_USAGE_SUCCESS,
192+
payload: payload,
193+
};
194+
};

client/packages/lowcoder/src/redux/sagas/orgSagas.ts

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import {
2121
UpdateGroupActionPayload,
2222
UpdateOrgPayload,
2323
updateOrgSuccess,
24+
fetchAPIUsageActionSuccess,
25+
fetchLastMonthAPIUsageActionSuccess,
2426
UpdateUserGroupRolePayload,
2527
UpdateUserOrgRolePayload,
2628
} from "redux/reduxActions/orgActions";
@@ -282,20 +284,34 @@ export function* updateOrgSaga(action: ReduxAction<UpdateOrgPayload>) {
282284

283285
export function* fetchAPIUsageSaga(action: ReduxAction<{
284286
orgId: string,
285-
lastMonthOnly?: boolean,
286287
}>) {
287288
try {
288289
const response: AxiosResponse<OrgAPIUsageResponse> = yield call(
289290
OrgApi.fetchAPIUsage,
290291
action.payload.orgId,
291-
action.payload.lastMonthOnly,
292292
);
293293
const isValidResponse: boolean = validateResponse(response);
294294
if (isValidResponse) {
295-
yield put({
296-
type: ReduxActionTypes.FETCH_ORG_API_USAGE_SUCCESS,
297-
payload: response.data.data,
298-
});
295+
yield put(fetchAPIUsageActionSuccess({apiUsage: response.data.data})
296+
);
297+
}
298+
} catch (error) {
299+
log.error(error);
300+
}
301+
}
302+
303+
export function* fetchLastMonthAPIUsageSaga(action: ReduxAction<{
304+
orgId: string,
305+
}>) {
306+
try {
307+
const response: AxiosResponse<OrgAPIUsageResponse> = yield call(
308+
OrgApi.fetchLastMonthAPIUsage,
309+
action.payload.orgId,
310+
);
311+
const isValidResponse: boolean = validateResponse(response);
312+
if (isValidResponse) {
313+
yield put(fetchLastMonthAPIUsageActionSuccess({lastMonthApiUsage: response.data.data})
314+
);
299315
}
300316
} catch (error) {
301317
log.error(error);
@@ -320,5 +336,6 @@ export default function* orgSagas() {
320336
takeLatest(ReduxActionTypes.DELETE_ORG, deleteOrgSaga),
321337
takeLatest(ReduxActionTypes.UPDATE_ORG, updateOrgSaga),
322338
takeLatest(ReduxActionTypes.FETCH_ORG_API_USAGE, fetchAPIUsageSaga),
339+
takeLatest(ReduxActionTypes.FETCH_ORG_LAST_MONTH_API_USAGE, fetchLastMonthAPIUsageSaga),
323340
]);
324341
}

client/packages/lowcoder/src/redux/selectors/orgSelectors.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,7 @@ export const getOrgCreateStatus = (state: AppState) => {
1919
export const getOrgApiUsage = (state: AppState) => {
2020
return state.ui.org.apiUsage;
2121
}
22+
23+
export const getOrgLastMonthApiUsage = (state: AppState) => {
24+
return state.ui.org.lastMonthApiUsage;
25+
}

0 commit comments

Comments
 (0)