@boarteam/boar-pack-users-frontend 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/package.json +38 -0
  2. package/src/.umi/core/EmptyRoute.tsx +9 -0
  3. package/src/.umi/core/defineApp.ts +17 -0
  4. package/src/.umi/core/helmet.ts +10 -0
  5. package/src/.umi/core/helmetContext.ts +4 -0
  6. package/src/.umi/core/history.ts +66 -0
  7. package/src/.umi/core/historyIntelli.ts +132 -0
  8. package/src/.umi/core/plugin.ts +55 -0
  9. package/src/.umi/core/pluginConfig.ts +299 -0
  10. package/src/.umi/core/pluginConfigJoi.d.ts +7 -0
  11. package/src/.umi/core/polyfill.ts +220 -0
  12. package/src/.umi/core/route.tsx +29 -0
  13. package/src/.umi/core/routeProps.ts +6 -0
  14. package/src/.umi/core/terminal.ts +37 -0
  15. package/src/.umi/exports.ts +23 -0
  16. package/src/.umi/plugin-access/context.ts +7 -0
  17. package/src/.umi/plugin-access/index.tsx +87 -0
  18. package/src/.umi/plugin-access/runtime.tsx +23 -0
  19. package/src/.umi/plugin-access/types.d.ts +5 -0
  20. package/src/.umi/plugin-locale/SelectLang.tsx +390 -0
  21. package/src/.umi/plugin-locale/index.ts +5 -0
  22. package/src/.umi/plugin-locale/locale.tsx +52 -0
  23. package/src/.umi/plugin-locale/localeExports.ts +279 -0
  24. package/src/.umi/plugin-locale/runtime.tsx +9 -0
  25. package/src/.umi/plugin-locale/runtimeConfig.d.ts +13 -0
  26. package/src/.umi/plugin-model/index.tsx +183 -0
  27. package/src/.umi/plugin-model/model.ts +6 -0
  28. package/src/.umi/plugin-model/runtime.tsx +20 -0
  29. package/src/.umi/testBrowser.tsx +87 -0
  30. package/src/.umi/tsconfig.json +44 -0
  31. package/src/.umi/typings.d.ts +136 -0
  32. package/src/.umi/umi.ts +76 -0
  33. package/src/access.ts +5 -0
  34. package/src/components/EventLogs/EventLogExplanation.tsx +166 -0
  35. package/src/components/EventLogs/EventLogsTable.tsx +146 -0
  36. package/src/components/EventLogs/EventLogsTimeline.tsx +109 -0
  37. package/src/components/EventLogs/UserAgentDisplay.tsx +21 -0
  38. package/src/components/EventLogs/eventLogsSearchableColumns.ts +87 -0
  39. package/src/components/EventLogs/getBrowserIcon.ts +27 -0
  40. package/src/components/EventLogs/useEventLogsColumns.tsx +375 -0
  41. package/src/components/index.tsx +7 -0
  42. package/src/index.tsx +1 -0
  43. package/src/pages/EventLogs/index.tsx +26 -0
  44. package/src/pages/getInitialState.tsx +114 -0
  45. package/src/tools/action.enum.ts +7 -0
  46. package/src/tools/api-client/apiClient.ts +6 -0
  47. package/src/tools/api-client/generated/ApiClient.ts +38 -0
  48. package/src/tools/api-client/generated/core/ApiError.ts +25 -0
  49. package/src/tools/api-client/generated/core/ApiRequestOptions.ts +17 -0
  50. package/src/tools/api-client/generated/core/ApiResult.ts +11 -0
  51. package/src/tools/api-client/generated/core/BaseHttpRequest.ts +14 -0
  52. package/src/tools/api-client/generated/core/CancelablePromise.ts +131 -0
  53. package/src/tools/api-client/generated/core/NodeHttpRequest.ts +26 -0
  54. package/src/tools/api-client/generated/core/OpenAPI.ts +32 -0
  55. package/src/tools/api-client/generated/core/request.ts +320 -0
  56. package/src/tools/api-client/generated/index.ts +26 -0
  57. package/src/tools/api-client/generated/models/EventLog.ts +56 -0
  58. package/src/tools/api-client/generated/models/EventLogCreateDto.ts +39 -0
  59. package/src/tools/api-client/generated/models/EventLogTimelineDto.ts +24 -0
  60. package/src/tools/api-client/generated/models/EventLogTimelineQueryDto.ts +11 -0
  61. package/src/tools/api-client/generated/models/EventLogUpdateDto.ts +39 -0
  62. package/src/tools/api-client/generated/models/GetManyEventLogResponseDto.ts +15 -0
  63. package/src/tools/api-client/generated/models/GetManyUserResponseDto.ts +15 -0
  64. package/src/tools/api-client/generated/models/PermissionDto.ts +9 -0
  65. package/src/tools/api-client/generated/models/User.ts +27 -0
  66. package/src/tools/api-client/generated/models/UserCreateDto.ts +23 -0
  67. package/src/tools/api-client/generated/models/UserUpdateDto.ts +23 -0
  68. package/src/tools/api-client/generated/services/EventLogsService.ts +178 -0
  69. package/src/tools/api-client/generated/services/UsersService.ts +226 -0
  70. package/src/tools/api-client/index.ts +2 -0
@@ -0,0 +1,87 @@
1
+ import { Operators, TSearchableColumn } from "@boarteam/boar-pack-common-frontend";
2
+
3
+ export const eventLogsSearchableColumns: TSearchableColumn[] = [
4
+ {
5
+ field: 'logType',
6
+ searchField: null,
7
+ operator: Operators.equals,
8
+ filterOperator: Operators.in,
9
+ },
10
+ {
11
+ field: 'serviceId',
12
+ operator: Operators.containsLow,
13
+ },
14
+ {
15
+ field: 'userRole',
16
+ searchField: null,
17
+ operator: Operators.equals,
18
+ filterOperator: Operators.in,
19
+ },
20
+ {
21
+ field: 'method',
22
+ operator: Operators.containsLow,
23
+ filterOperator: Operators.in,
24
+ },
25
+ {
26
+ field: 'logLevel',
27
+ searchField: null,
28
+ operator: Operators.equals,
29
+ filterOperator: Operators.in,
30
+ },
31
+ {
32
+ field: 'service',
33
+ operator: Operators.containsLow,
34
+ filterOperator: Operators.in,
35
+ },
36
+ {
37
+ field: 'user',
38
+ searchField: 'user.name',
39
+ filterField: 'user.id',
40
+ operator: Operators.containsLow,
41
+ filterOperator: Operators.in,
42
+ },
43
+ {
44
+ field: 'externalUserId',
45
+ operator: Operators.containsLow,
46
+ },
47
+ {
48
+ field: 'action',
49
+ operator: Operators.containsLow,
50
+ },
51
+ {
52
+ field: 'entity',
53
+ operator: Operators.containsLow,
54
+ },
55
+ {
56
+ field: 'entityId',
57
+ operator: Operators.equals,
58
+ },
59
+ {
60
+ field: 'url',
61
+ operator: Operators.containsLow,
62
+ },
63
+ {
64
+ field: 'ipAddress',
65
+ operator: Operators.containsLow,
66
+ },
67
+ {
68
+ field: 'userAgent',
69
+ operator: Operators.containsLow,
70
+ },
71
+ {
72
+ field: 'duration',
73
+ operator: Operators.equals,
74
+ numeric: true,
75
+ },
76
+ {
77
+ field: 'statusCode',
78
+ operator: Operators.equals,
79
+ numeric: true,
80
+ },
81
+ {
82
+ field: 'createdAt',
83
+ searchField: null,
84
+ operator: Operators.equals,
85
+ filterOperator: Operators.between,
86
+ }
87
+ ];
@@ -0,0 +1,27 @@
1
+ import Bowser from 'bowser';
2
+ import { library, dom } from '@fortawesome/fontawesome-svg-core';
3
+ import { faChrome, faFirefox, faSafari, faEdge, faOpera } from '@fortawesome/free-brands-svg-icons';
4
+
5
+ // Add icons to the library
6
+ library.add(faChrome, faFirefox, faSafari, faEdge, faOpera);
7
+ dom.watch();
8
+
9
+ export function getBrowserIcon(userAgent: string): string {
10
+ const browser = Bowser.getParser(userAgent);
11
+ const browserName = browser.getBrowserName();
12
+
13
+ switch (browserName) {
14
+ case 'Chrome':
15
+ return 'fab fa-chrome';
16
+ case 'Firefox':
17
+ return 'fab fa-firefox';
18
+ case 'Safari':
19
+ return 'fab fa-safari';
20
+ case 'Microsoft Edge':
21
+ return 'fab fa-edge';
22
+ case 'Opera':
23
+ return 'fab fa-opera';
24
+ default:
25
+ return 'fas fa-question-circle'; // Default icon for unknown browsers
26
+ }
27
+ }
@@ -0,0 +1,375 @@
1
+ import { ProColumns } from "@ant-design/pro-components";
2
+ import { Badge, Collapse, CollapseProps, Space, Tooltip, Typography } from "antd";
3
+ import { EventLog, EventLogTimelineQueryDto } from "@@api/generated";
4
+ import {
5
+ AppstoreOutlined,
6
+ ExclamationCircleOutlined,
7
+ InfoCircleTwoTone,
8
+ SettingOutlined,
9
+ UserOutlined,
10
+ WarningOutlined
11
+ } from "@ant-design/icons";
12
+ import { useEffect, useState } from "react";
13
+ import UserAgentDisplay from "./UserAgentDisplay";
14
+ import apiClient from "@@api/apiClient";
15
+ import { getUserRoleIcon } from "./EventLogExplanation";
16
+
17
+ import { DateRange } from "@boarteam/boar-pack-common-frontend";
18
+
19
+ const { Text } = Typography;
20
+
21
+ const serviceNameToAbbreviation: Record<string, string> = {
22
+ 'TID Main App': 'TID',
23
+ 'Liquidity Manager': 'LM',
24
+ 'Quotes Monitor': 'QM',
25
+ 'Admin Panel - Main': 'ADM',
26
+ 'Manager Panel - Main': 'MNG',
27
+ 'Admin RealTimeData': 'ARTD',
28
+ 'Manager RealTimeData': 'MRTD',
29
+ } as const;
30
+
31
+ const logTypes = {
32
+ [EventLog.logType.AUDIT]: {
33
+ text: 'Audit',
34
+ icon: <UserOutlined />,
35
+ },
36
+ [EventLog.logType.OPERATIONAL]: {
37
+ text: 'Operational',
38
+ icon: <SettingOutlined />,
39
+ },
40
+ [EventLog.logType.APPLICATION]: {
41
+ text: 'Application',
42
+ icon: <AppstoreOutlined />,
43
+ },
44
+ };
45
+
46
+ const logLevels = {
47
+ [EventLog.logLevel.INFO]: {
48
+ text: 'Info',
49
+ icon: <InfoCircleTwoTone />,
50
+ type: undefined as undefined,
51
+ },
52
+ [EventLog.logLevel.WARNING]: {
53
+ text: 'Warning',
54
+ icon: <WarningOutlined />,
55
+ type: 'warning',
56
+ },
57
+ [EventLog.logLevel.ERROR]: {
58
+ text: 'Error',
59
+ icon: <ExclamationCircleOutlined />,
60
+ type: 'danger',
61
+ },
62
+ } as const;
63
+
64
+ export const useEventLogsColumns = ({
65
+ startTime,
66
+ endTime,
67
+ onDateRangeChange,
68
+ }: EventLogTimelineQueryDto & {
69
+ onDateRangeChange: (start: string | undefined, end: string | undefined) => void;
70
+ }): ProColumns<EventLog>[] => {
71
+ const [users, setUsers] = useState<{ text: string, value: string }[]>([]);
72
+
73
+ useEffect(() => {
74
+ apiClient.users.getManyBaseUsersControllerUser({
75
+ sort: ['name,ASC'],
76
+ }).then((users) => {
77
+ setUsers(users.data.map((item) => ({ text: item.name, value: item.id })));
78
+ });
79
+ }, []);
80
+
81
+ return [
82
+ {
83
+ title: 'Type',
84
+ dataIndex: 'logType',
85
+ valueType: 'select',
86
+ width: 50,
87
+ valueEnum: Object.fromEntries(
88
+ Object.entries(logTypes).map(([key, value]) => [
89
+ key,
90
+ {
91
+ text: value.text,
92
+ }
93
+ ])
94
+ ),
95
+ render(dom, record) {
96
+ return <Tooltip title={logTypes[record.logType].text}>{logTypes[record.logType].icon}</Tooltip>;
97
+ },
98
+ filters: true,
99
+ align: 'center',
100
+ hideInSearch: true,
101
+ },
102
+ {
103
+ title: 'Service',
104
+ dataIndex: 'service',
105
+ render(dom, record) {
106
+ return serviceNameToAbbreviation[record.service]
107
+ ? <Tooltip title={record.service}>{serviceNameToAbbreviation[record.service]}</Tooltip>
108
+ : record.service;
109
+ },
110
+ width: 10,
111
+ valueEnum: Object.fromEntries(
112
+ Object.entries(serviceNameToAbbreviation).map(([key, value]) => [
113
+ key,
114
+ {
115
+ text: key,
116
+ }
117
+ ])
118
+ ),
119
+ filters: true,
120
+ hideInSearch: true,
121
+ },
122
+ {
123
+ title: 'Service Id',
124
+ dataIndex: 'serviceId',
125
+ copyable: true,
126
+ hideInSearch: true,
127
+ },
128
+ {
129
+ title: 'Time',
130
+ dataIndex: 'createdAt',
131
+ valueType: 'dateTime',
132
+ sorter: true,
133
+ renderFormItem: () => <DateRange
134
+ value={startTime && endTime ? [startTime, endTime] : null}
135
+ onChange={(value) => onDateRangeChange(value?.[0] || undefined, value?.[1] || undefined)}
136
+ />,
137
+ },
138
+ {
139
+ title: 'User',
140
+ dataIndex: 'user',
141
+ render: (text, record) => {
142
+ return <Space>
143
+ {getUserRoleIcon(record.userRole)}
144
+ {
145
+ record.userName
146
+ || record.user?.name
147
+ || record.userId
148
+ || record.externalUserId
149
+ || <Text type={'secondary'}>role: {record.userRole}</Text>
150
+ }
151
+ </Space>;
152
+ },
153
+ filters: users,
154
+ filterSearch: true,
155
+ hideInSearch: true,
156
+ },
157
+ {
158
+ title: 'User Role',
159
+ dataIndex: 'userRole',
160
+ valueEnum: {
161
+ [EventLog.userRole.ADMIN]: {
162
+ text: 'Admin',
163
+ },
164
+ [EventLog.userRole.USER]: {
165
+ text: 'User',
166
+ },
167
+ [EventLog.userRole.GUEST]: {
168
+ text: 'Guest',
169
+ },
170
+ [EventLog.userRole.SYSTEM]: {
171
+ text: 'System',
172
+ },
173
+ },
174
+ filters: true,
175
+ hideInSearch: true,
176
+ },
177
+ {
178
+ title: 'User Name',
179
+ dataIndex: 'userName',
180
+ hideInSearch: true,
181
+ },
182
+ {
183
+ title: 'User Inst ID',
184
+ dataIndex: 'externalUserId',
185
+ copyable: true,
186
+ hideInSearch: true,
187
+ },
188
+ {
189
+ title: 'Action',
190
+ dataIndex: 'action',
191
+ render(dom, record) {
192
+ // getManyBase -> Get Many
193
+ const action = record.action
194
+ .replace('Base', '')
195
+ .replace(/([a-z])([A-Z])/g, '$1 $2');
196
+ return action[0].toUpperCase() + action.slice(1);
197
+ },
198
+ hideInSearch: true,
199
+ },
200
+ {
201
+ title: 'Entity',
202
+ dataIndex: 'entity',
203
+ render(dom, record) {
204
+ // EventLogsController -> Event Logs
205
+ return record.entity
206
+ .replace('Controller', '')
207
+ .replace(/([a-z])([A-Z])/g, '$1 $2');
208
+ },
209
+ hideInSearch: true,
210
+ },
211
+ {
212
+ title: 'Entity ID',
213
+ dataIndex: 'entityId',
214
+ copyable: true,
215
+ hideInSearch: true,
216
+ },
217
+ {
218
+ title: 'Method',
219
+ dataIndex: 'method',
220
+ valueEnum: {
221
+ GET: {
222
+ text: 'GET',
223
+ },
224
+ POST: {
225
+ text: 'POST',
226
+ },
227
+ PUT: {
228
+ text: 'PUT',
229
+ },
230
+ PATCH: {
231
+ text: 'PATCH',
232
+ },
233
+ DELETE: {
234
+ text: 'DELETE',
235
+ },
236
+ OPTIONS: {
237
+ text: 'OPTIONS',
238
+ },
239
+ HEAD: {
240
+ text: 'HEAD',
241
+ },
242
+ },
243
+ filters: true,
244
+ hideInSearch: true,
245
+ },
246
+ {
247
+ title: 'URL',
248
+ dataIndex: 'url',
249
+ width: 600,
250
+ render(dom, record) {
251
+ return <Typography.Paragraph
252
+ style={{
253
+ width: 600,
254
+ margin: 0,
255
+ }}
256
+ ellipsis={{
257
+ rows: 1,
258
+ expandable: true,
259
+ }}
260
+ copyable={true}
261
+ >{record.url}</Typography.Paragraph>;
262
+ },
263
+ hideInSearch: true,
264
+ },
265
+ {
266
+ title: 'Payload',
267
+ dataIndex: 'payload',
268
+ render(dom, record) {
269
+ if (record.payload === null) {
270
+ return 'N/A';
271
+ }
272
+
273
+ if ('message' in record.payload) {
274
+ const items: CollapseProps['items'] = [
275
+ {
276
+ key: '1',
277
+ label: <pre style={{ margin: 0 }}>{record.payload.message}</pre>,
278
+ children: <pre
279
+ style={{ margin: 0 }}
280
+ >{
281
+ JSON.stringify(record.payload, null, 2).replace(/\n/g, '\n')
282
+ }</pre>,
283
+ },
284
+ ];
285
+
286
+ return <Collapse items={items} ghost />;
287
+ }
288
+
289
+ return <pre style={{ margin: 0 }}>{JSON.stringify(record.payload)}</pre>;
290
+ },
291
+ hideInSearch: true,
292
+ },
293
+ {
294
+ title: 'IP Address',
295
+ dataIndex: 'ipAddress',
296
+ copyable: true,
297
+ hideInSearch: true,
298
+ },
299
+ {
300
+ title: 'User Agent',
301
+ dataIndex: 'userAgent',
302
+ render(dom, record) {
303
+ if (record.userAgent === null) {
304
+ return 'N/A';
305
+ }
306
+
307
+ return <UserAgentDisplay userAgent={record.userAgent} />;
308
+ },
309
+ hideInSearch: true,
310
+
311
+ },
312
+ {
313
+ title: 'Duration',
314
+ dataIndex: 'duration',
315
+ render(dom, record) {
316
+ const text = record.duration + ' ms';
317
+
318
+ if (record.duration === null) {
319
+ return 'N/A';
320
+ }
321
+
322
+ if (record.duration >= 1000) {
323
+ return <Typography.Text type='danger'>{text}</Typography.Text>;
324
+ }
325
+
326
+ if (record.duration >= 200) {
327
+ return <Typography.Text type='warning'>{text}</Typography.Text>;
328
+ }
329
+
330
+ return text;
331
+ },
332
+ valueType: 'digit',
333
+ sorter: true,
334
+ hideInSearch: true,
335
+ },
336
+ {
337
+ title: 'Status Code',
338
+ dataIndex: 'statusCode',
339
+ render(dom, record) {
340
+ if (record.statusCode === null) {
341
+ return 'N/A';
342
+ }
343
+
344
+ if (record.statusCode >= 500) {
345
+ return <Badge color={'red'} text={record.statusCode} />;
346
+ }
347
+
348
+ if (record.statusCode >= 300) {
349
+ return <Badge color={'orange'} text={record.statusCode} />;
350
+ }
351
+
352
+ return <Badge color={'green'} text={record.statusCode} />;
353
+ },
354
+ hideInSearch: true,
355
+ },
356
+ {
357
+ title: 'Log Level',
358
+ dataIndex: 'logLevel',
359
+ render(dom, record) {
360
+ return <Text
361
+ type={logLevels[record.logLevel].type}>{logLevels[record.logLevel].icon} {logLevels[record.logLevel].text}</Text>;
362
+ },
363
+ valueEnum: Object.fromEntries(
364
+ Object.entries(logLevels).map(([key, value]) => [
365
+ key,
366
+ {
367
+ text: <Text type={value.type}>{value.icon} {value.text}</Text>,
368
+ }
369
+ ])
370
+ ),
371
+ filters: true,
372
+ hideInSearch: true,
373
+ }
374
+ ];
375
+ };
@@ -0,0 +1,7 @@
1
+ export * from './EventLogs/EventLogExplanation';
2
+ export * from './EventLogs/eventLogsSearchableColumns';
3
+ export * from './EventLogs/EventLogsTable';
4
+ export * from './EventLogs/EventLogsTimeline';
5
+ export * from './EventLogs/getBrowserIcon';
6
+ export * from './EventLogs/useEventLogsColumns';
7
+ export {default as UserAgentDisplay} from './EventLogs/UserAgentDisplay';
package/src/index.tsx ADDED
@@ -0,0 +1 @@
1
+ export * from './components'
@@ -0,0 +1,26 @@
1
+ import { PageContainer } from "@ant-design/pro-components";
2
+ import React, { useState } from "react";
3
+ import EventLogsTable from "../../components/EventLogs/EventLogsTable";
4
+ import { EventLogsTimeline } from "../../components/EventLogs/EventLogsTimeline";
5
+ import { Card } from "antd";
6
+
7
+ const EventLogs: React.FC = () => {
8
+ const [startTime, setStartTime] = useState<string | undefined>(undefined);
9
+ const [endTime, setEndTime] = useState<string | undefined>(undefined);
10
+
11
+ const handleDateRangeChange = (start: string | undefined, end: string | undefined) => {
12
+ setStartTime(start);
13
+ setEndTime(end);
14
+ };
15
+
16
+ return (
17
+ <PageContainer>
18
+ <Card>
19
+ <EventLogsTimeline startTime={startTime} endTime={endTime} onDateRangeChange={handleDateRangeChange} />
20
+ <EventLogsTable startTime={startTime} endTime={endTime} onDateRangeChange={handleDateRangeChange} />
21
+ </Card>
22
+ </PageContainer>
23
+ )
24
+ }
25
+
26
+ export default EventLogs;
@@ -0,0 +1,114 @@
1
+ import { PageLoading } from "@ant-design/pro-layout";
2
+ import { PureAbility } from "@casl/ability";
3
+ import { unpackRules } from "@casl/ability/extra";
4
+ import { stringify } from "querystring";
5
+ import { history } from '@umijs/max';
6
+ import { Action } from "@/tools/action.enum";
7
+ import defaultSettings, { appSettings } from "@/../config/defaultSettings";
8
+ import { CancelablePromise } from "@@api/generated";
9
+
10
+ export const loginPath = appSettings.loginPath;
11
+ const resetPasswordPath = appSettings.resetPasswordPath;
12
+
13
+ export function goToLogin(forceSearch?: string) {
14
+ const { search, pathname } = history.location;
15
+ if (pathname !== loginPath) {
16
+ console.log(`Redirect to ${loginPath}`);
17
+ let searchParam = '';
18
+ if (typeof forceSearch === 'string') {
19
+ searchParam = forceSearch;
20
+ } else if (pathname !== '/') {
21
+ searchParam = stringify({
22
+ redirect: pathname + search,
23
+ });
24
+ }
25
+ history.replace({
26
+ pathname: loginPath,
27
+ search: searchParam,
28
+ });
29
+ } else {
30
+ console.log('Staying on login page, redirect is not necessary');
31
+ }
32
+ }
33
+
34
+ export function goToMain() {
35
+ if (!history) return;
36
+ // @ts-ignore
37
+ const { query = {} } = history.location;
38
+ const { redirect } = query as { redirect: string };
39
+ const url = redirect || '/';
40
+ history.push(url);
41
+ }
42
+
43
+ export async function fetchUserInfo<TUser>(fetchUserInfoCallback: () => CancelablePromise<TUser>) {
44
+ try {
45
+ return fetchUserInfoCallback();
46
+ } catch (error) {
47
+ console.error('Error while fetching user info, redirecting to login');
48
+ console.error(error);
49
+ goToLogin();
50
+ }
51
+ return undefined;
52
+ }
53
+
54
+ export async function logout(logoutCallback: () => CancelablePromise<void>) {
55
+ await logoutCallback();
56
+ goToLogin();
57
+ }
58
+
59
+ export const initialStateConfig = {
60
+ loading: <PageLoading />,
61
+ };
62
+
63
+ export type TInitialState<TUser> = {
64
+ settings?: typeof defaultSettings;
65
+ currentUser?: TUser;
66
+ currentCompany?: string;
67
+ loading?: boolean;
68
+ ability?: PureAbility<[Action, string]>,
69
+ }
70
+
71
+ export function onPageChange<TUser>(initialState?: TInitialState<TUser>) {
72
+ const currentUser = initialState?.currentUser;
73
+
74
+ if (!currentUser) {
75
+ console.log('There is no current user in the state, going to login');
76
+ goToLogin();
77
+ return;
78
+ }
79
+ }
80
+
81
+ /**
82
+ * @see https://umijs.org/zh-CN/plugins/plugin-initial-state
83
+ */
84
+ export async function getInitialState<TUser>(
85
+ afterLogin = false,
86
+ projectSettings: typeof defaultSettings = {},
87
+ fetchUserInfoCallback: () => CancelablePromise<TUser>
88
+ ): Promise<TInitialState<TUser>> {
89
+ const ability = new PureAbility<[Action, string]>();
90
+ const pathname = history.location.pathname;
91
+
92
+ const state: TInitialState<TUser> = {
93
+ settings: {
94
+ ...defaultSettings,
95
+ ...projectSettings
96
+ },
97
+ ability,
98
+ };
99
+
100
+ if (![loginPath, resetPasswordPath].some(path => pathname.startsWith(path)) || afterLogin) {
101
+ const currentUser = await fetchUserInfo(fetchUserInfoCallback);
102
+
103
+ if (!currentUser) {
104
+ console.log('User is not authenticated');
105
+ throw new Error('User is not authenticated');
106
+ }
107
+
108
+ console.log('User is authenticated and ready to work with the system');
109
+ ability.update(unpackRules(currentUser.policies));
110
+ state.currentUser = currentUser;
111
+ }
112
+
113
+ return state;
114
+ }
@@ -0,0 +1,7 @@
1
+ export enum Action {
2
+ Manage = 'manage',
3
+ Create = 'create',
4
+ Read = 'read',
5
+ Update = 'update',
6
+ Delete = 'delete',
7
+ }
@@ -0,0 +1,6 @@
1
+ import { ApiClient } from "./generated";
2
+
3
+ export default new ApiClient({
4
+ BASE: '/api',
5
+ ENCODE_PATH: encodeURIComponent,
6
+ });
@@ -0,0 +1,38 @@
1
+ /* generated using openapi-typescript-codegen -- do no edit */
2
+ /* istanbul ignore file */
3
+ /* tslint:disable */
4
+ /* eslint-disable */
5
+ import type { BaseHttpRequest } from './core/BaseHttpRequest';
6
+ import type { OpenAPIConfig } from './core/OpenAPI';
7
+ import { NodeHttpRequest } from './core/NodeHttpRequest';
8
+
9
+ import { EventLogsService } from './services/EventLogsService';
10
+ import { UsersService } from './services/UsersService';
11
+
12
+ type HttpRequestConstructor = new (config: OpenAPIConfig) => BaseHttpRequest;
13
+
14
+ export class ApiClient {
15
+
16
+ public readonly eventLogs: EventLogsService;
17
+ public readonly users: UsersService;
18
+
19
+ public readonly request: BaseHttpRequest;
20
+
21
+ constructor(config?: Partial<OpenAPIConfig>, HttpRequest: HttpRequestConstructor = NodeHttpRequest) {
22
+ this.request = new HttpRequest({
23
+ BASE: config?.BASE ?? '',
24
+ VERSION: config?.VERSION ?? '1.0',
25
+ WITH_CREDENTIALS: config?.WITH_CREDENTIALS ?? false,
26
+ CREDENTIALS: config?.CREDENTIALS ?? 'include',
27
+ TOKEN: config?.TOKEN,
28
+ USERNAME: config?.USERNAME,
29
+ PASSWORD: config?.PASSWORD,
30
+ HEADERS: config?.HEADERS,
31
+ ENCODE_PATH: config?.ENCODE_PATH,
32
+ });
33
+
34
+ this.eventLogs = new EventLogsService(this.request);
35
+ this.users = new UsersService(this.request);
36
+ }
37
+ }
38
+