@boarteam/boar-pack-users-frontend 2.4.1 → 2.5.0
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.
- package/package.json +3 -3
- package/src/components/Settings/NotificationsSettings.tsx +206 -0
- package/src/components/Settings/settingsContext.tsx +9 -0
- package/src/pages/Settings/index.tsx +35 -0
- package/src/tools/api-client/generated/ApiClient.ts +6 -0
- package/src/tools/api-client/generated/index.ts +5 -0
- package/src/tools/api-client/generated/models/EventSettingsDto.ts +7 -0
- package/src/tools/api-client/generated/models/TelegramSettingsDto.ts +10 -0
- package/src/tools/api-client/generated/models/TelegramSettingsUpdateDto.ts +10 -0
- package/src/tools/api-client/generated/services/SettingsService.ts +36 -0
- package/src/tools/api-client/generated/services/TelegrafService.ts +47 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@boarteam/boar-pack-users-frontend",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"description": "Users frontend package for Boar Pack",
|
|
5
5
|
"repository": "git@github.com:boarteam/boar-pack.git",
|
|
6
6
|
"author": "Andrew Balakirev <balakirev.andrey@gmail.com>",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@ant-design/plots": "^2.3.2",
|
|
18
|
-
"@boarteam/boar-pack-common-frontend": "^2.8.
|
|
18
|
+
"@boarteam/boar-pack-common-frontend": "^2.8.1",
|
|
19
19
|
"@fortawesome/fontawesome-svg-core": "^6.6.0",
|
|
20
20
|
"@fortawesome/free-brands-svg-icons": "^6.6.0",
|
|
21
21
|
"@umijs/max": "^4.1.10",
|
|
@@ -34,5 +34,5 @@
|
|
|
34
34
|
"build": "tsc --project tsconfig.build.json",
|
|
35
35
|
"yalc:push": "yalc push"
|
|
36
36
|
},
|
|
37
|
-
"gitHead": "
|
|
37
|
+
"gitHead": "79fe5a34f9a9bd6e1e3e010f7a64b3b82c9e19b5"
|
|
38
38
|
}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { ProDescriptions } from "@ant-design/pro-components";
|
|
2
|
+
import { Button, Card, message, Space, Typography } from "antd";
|
|
3
|
+
import React, { useContext } from "react";
|
|
4
|
+
import { useIntl } from "umi";
|
|
5
|
+
import apiClient from "@@api/apiClient";
|
|
6
|
+
import { EventSettingsDto, TelegramSettingsUpdateDto } from "@@api/generated";
|
|
7
|
+
import { SettingsContext } from "../../components/Settings/settingsContext";
|
|
8
|
+
|
|
9
|
+
const { Title, Text, Paragraph } = Typography;
|
|
10
|
+
|
|
11
|
+
const isBoolean = (value: any) => {
|
|
12
|
+
return [true, false].includes(value)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async function onSaveTelegramSettings(row: TelegramSettingsUpdateDto) {
|
|
16
|
+
apiClient.telegraf.setTelegramSettings({
|
|
17
|
+
requestBody: row,
|
|
18
|
+
}).catch(e => {
|
|
19
|
+
console.error(e);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async function onSaveEventSettings(row: EventSettingsDto) {
|
|
24
|
+
apiClient.settings.setEventSettings({
|
|
25
|
+
requestBody: row,
|
|
26
|
+
}).catch(e => {
|
|
27
|
+
console.error(e);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const NotificationsSettings: React.FC = () => {
|
|
32
|
+
const [loading, setLoading] = React.useState<boolean>(false);
|
|
33
|
+
const [settingsChanging, setSettingsChanging] = React.useState<boolean>(false);
|
|
34
|
+
const [messageApi, contextHolder] = message.useMessage();
|
|
35
|
+
const intl = useIntl();
|
|
36
|
+
const settingsContext = useContext(SettingsContext);
|
|
37
|
+
|
|
38
|
+
const testSettings = async () => {
|
|
39
|
+
setLoading(true);
|
|
40
|
+
try {
|
|
41
|
+
await apiClient.telegraf.testTelegraf();
|
|
42
|
+
messageApi.success(intl.formatMessage({ id: 'pages.notifications.testSuccess' }));
|
|
43
|
+
} catch (e) {
|
|
44
|
+
console.error(e);
|
|
45
|
+
} finally {
|
|
46
|
+
setLoading(false);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<Card>
|
|
52
|
+
<div>
|
|
53
|
+
<Title level={3}>Introduction</Title>
|
|
54
|
+
<Paragraph>
|
|
55
|
+
This service allows you to receive important event notifications through Telegram. You'll be able to stay
|
|
56
|
+
informed about system usage and health.
|
|
57
|
+
</Paragraph>
|
|
58
|
+
|
|
59
|
+
<Title level={4}>Creation of Telegram Bot</Title>
|
|
60
|
+
<Paragraph>
|
|
61
|
+
<ol>
|
|
62
|
+
<li>Register your bot by sending the command <Text copyable={true} code>/newbot</Text> to <a
|
|
63
|
+
href="https://t.me/BotFather" target="_blank" rel="noreferrer"
|
|
64
|
+
>@BotFather</a> and follow the
|
|
65
|
+
instructions.
|
|
66
|
+
</li>
|
|
67
|
+
<li>Copy the bot token provided by @BotFather and paste it in the "Telegram Bot Access Token" field.</li>
|
|
68
|
+
<li>Add your bot to the group you wish to send notifications to.</li>
|
|
69
|
+
</ol>
|
|
70
|
+
</Paragraph>
|
|
71
|
+
|
|
72
|
+
<Title level={4}>Telegram Notifications Setup</Title>
|
|
73
|
+
|
|
74
|
+
<Title level={5}>Option 1: Personal Notifications</Title>
|
|
75
|
+
<Paragraph>
|
|
76
|
+
<ol>
|
|
77
|
+
<li>Send the command <Text code copyable={true}>/getid</Text> to the bot named <a
|
|
78
|
+
href="https://t.me/myidbot" target="_blank" rel="noreferrer"
|
|
79
|
+
>@myidbot</a> in your Telegram messenger.
|
|
80
|
+
</li>
|
|
81
|
+
<li>Copy the chat ID returned by the bot and paste it in the designated "Telegram Chat ID" field.</li>
|
|
82
|
+
</ol>
|
|
83
|
+
</Paragraph>
|
|
84
|
+
|
|
85
|
+
<Title level={5}>Option 2: Notifications for Telegram Groups</Title>
|
|
86
|
+
<Paragraph>
|
|
87
|
+
<ol>
|
|
88
|
+
<li>Add the bot named <a
|
|
89
|
+
href="https://t.me/myidbot" target="_blank" rel="noreferrer"
|
|
90
|
+
>@myidbot</a> to your Telegram group.</li>
|
|
91
|
+
<li>Send the command <Text code copyable={true}>/getgroupid</Text> to @myidbot within the group chat.
|
|
92
|
+
</li>
|
|
93
|
+
<li>Copy the group ID returned by the bot and paste it in the designated "Telegram Chat ID" field.</li>
|
|
94
|
+
</ol>
|
|
95
|
+
</Paragraph>
|
|
96
|
+
</div>
|
|
97
|
+
|
|
98
|
+
<Space direction={'vertical'} size={"middle"}>
|
|
99
|
+
<ProDescriptions<TelegramSettingsUpdateDto>
|
|
100
|
+
bordered={true}
|
|
101
|
+
size={'small'}
|
|
102
|
+
formProps={{
|
|
103
|
+
onValuesChange: async (changedValues) => {
|
|
104
|
+
if (Object.keys(changedValues).some(key => isBoolean(changedValues[key]))) {
|
|
105
|
+
setSettingsChanging(true);
|
|
106
|
+
await onSaveTelegramSettings(changedValues);
|
|
107
|
+
setSettingsChanging(false);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}}
|
|
111
|
+
columns={[
|
|
112
|
+
{
|
|
113
|
+
title: 'Telegram notifications enabled',
|
|
114
|
+
dataIndex: 'enabled',
|
|
115
|
+
valueType: 'switch',
|
|
116
|
+
span: 4,
|
|
117
|
+
mode: 'update',
|
|
118
|
+
fieldProps: {
|
|
119
|
+
loading: settingsChanging,
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
title: 'Telegram Bot Access Token',
|
|
124
|
+
dataIndex: 'botToken',
|
|
125
|
+
valueType: 'password',
|
|
126
|
+
span: 4,
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
title: 'Telegram Chat ID',
|
|
130
|
+
dataIndex: 'chatId',
|
|
131
|
+
valueType: 'text',
|
|
132
|
+
span: 4,
|
|
133
|
+
},
|
|
134
|
+
]}
|
|
135
|
+
request={async () => {
|
|
136
|
+
return {
|
|
137
|
+
success: true,
|
|
138
|
+
data: await apiClient.telegraf.getTelegramSettings()
|
|
139
|
+
}
|
|
140
|
+
}}
|
|
141
|
+
editable={{
|
|
142
|
+
onSave: async (key, row) => {
|
|
143
|
+
setSettingsChanging(true);
|
|
144
|
+
await onSaveTelegramSettings(row);
|
|
145
|
+
setSettingsChanging(false);
|
|
146
|
+
},
|
|
147
|
+
actionRender: (row, config, dom) => {
|
|
148
|
+
if (config.recordKey === 'enabled') {
|
|
149
|
+
return [];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return [dom.save, dom.cancel];
|
|
153
|
+
}
|
|
154
|
+
}}
|
|
155
|
+
/>
|
|
156
|
+
{settingsContext.columns.length > 0 && (
|
|
157
|
+
<ProDescriptions<EventSettingsDto>
|
|
158
|
+
title='Events'
|
|
159
|
+
bordered={true}
|
|
160
|
+
size={'small'}
|
|
161
|
+
formProps={{
|
|
162
|
+
onValuesChange: async (changedValues) => {
|
|
163
|
+
if (Object.keys(changedValues).some(key => isBoolean(changedValues[key]))) {
|
|
164
|
+
setSettingsChanging(true);
|
|
165
|
+
await onSaveEventSettings(changedValues);
|
|
166
|
+
setSettingsChanging(false);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}}
|
|
170
|
+
columns={[
|
|
171
|
+
...settingsContext.columns.map(column => ({
|
|
172
|
+
...column,
|
|
173
|
+
fieldProps: {
|
|
174
|
+
loading: settingsChanging,
|
|
175
|
+
...column.fieldProps,
|
|
176
|
+
},
|
|
177
|
+
})),
|
|
178
|
+
]}
|
|
179
|
+
request={async () => {
|
|
180
|
+
return {
|
|
181
|
+
success: true,
|
|
182
|
+
data: await apiClient.settings.getEventSettings()
|
|
183
|
+
}
|
|
184
|
+
}}
|
|
185
|
+
editable={{
|
|
186
|
+
onSave: async (key, row) => {
|
|
187
|
+
setSettingsChanging(true);
|
|
188
|
+
await onSaveEventSettings(row);
|
|
189
|
+
setSettingsChanging(false);
|
|
190
|
+
},
|
|
191
|
+
actionRender: () => {
|
|
192
|
+
return [];
|
|
193
|
+
}
|
|
194
|
+
}}
|
|
195
|
+
/>
|
|
196
|
+
)}
|
|
197
|
+
<Button
|
|
198
|
+
type="primary"
|
|
199
|
+
loading={loading}
|
|
200
|
+
onClick={testSettings}
|
|
201
|
+
>Send test message</Button>
|
|
202
|
+
</Space>
|
|
203
|
+
{contextHolder}
|
|
204
|
+
</Card>
|
|
205
|
+
)
|
|
206
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createContext } from "react";
|
|
2
|
+
import { ProDescriptionsItemProps } from "@ant-design/pro-descriptions";
|
|
3
|
+
import { TelegramSettingsUpdateDto } from "@@api/generated";
|
|
4
|
+
|
|
5
|
+
type TSettingsContext = {
|
|
6
|
+
columns: ProDescriptionsItemProps<TelegramSettingsUpdateDto, 'text'>[]
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const SettingsContext = createContext<TSettingsContext | undefined>(undefined);
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { useIntl } from "@umijs/max";
|
|
3
|
+
import { NotificationsSettings } from "../../components/Settings/NotificationsSettings";
|
|
4
|
+
import { PageContainer } from "@ant-design/pro-components";
|
|
5
|
+
import { useTabs } from "@boarteam/boar-pack-common-frontend";
|
|
6
|
+
|
|
7
|
+
enum Tabs {
|
|
8
|
+
notifications = 'notifications',
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const Settings: React.FC = () => {
|
|
12
|
+
const [activeTab, setActiveTab] = useTabs<Tabs>(Tabs.notifications);
|
|
13
|
+
const intl = useIntl();
|
|
14
|
+
|
|
15
|
+
const tabList = [
|
|
16
|
+
{
|
|
17
|
+
key: Tabs.notifications,
|
|
18
|
+
tab: intl.formatMessage({ id: 'pages.settings.notifications' }),
|
|
19
|
+
},
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<PageContainer
|
|
24
|
+
tabList={tabList}
|
|
25
|
+
tabActiveKey={activeTab}
|
|
26
|
+
onTabChange={(key) => {
|
|
27
|
+
setActiveTab(key as Tabs);
|
|
28
|
+
}}
|
|
29
|
+
>
|
|
30
|
+
{activeTab === Tabs.notifications ? <NotificationsSettings /> : null}
|
|
31
|
+
</PageContainer>
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export default Settings;
|
|
@@ -6,11 +6,15 @@ import type { BaseHttpRequest } from './core/BaseHttpRequest';
|
|
|
6
6
|
import type { OpenAPIConfig } from './core/OpenAPI';
|
|
7
7
|
import { NodeHttpRequest } from './core/NodeHttpRequest';
|
|
8
8
|
import { EventLogsService } from './services/EventLogsService';
|
|
9
|
+
import { SettingsService } from './services/SettingsService';
|
|
10
|
+
import { TelegrafService } from './services/TelegrafService';
|
|
9
11
|
import { TokensService } from './services/TokensService';
|
|
10
12
|
import { UsersService } from './services/UsersService';
|
|
11
13
|
type HttpRequestConstructor = new (config: OpenAPIConfig) => BaseHttpRequest;
|
|
12
14
|
export class ApiClient {
|
|
13
15
|
public readonly eventLogs: EventLogsService;
|
|
16
|
+
public readonly settings: SettingsService;
|
|
17
|
+
public readonly telegraf: TelegrafService;
|
|
14
18
|
public readonly tokens: TokensService;
|
|
15
19
|
public readonly users: UsersService;
|
|
16
20
|
public readonly request: BaseHttpRequest;
|
|
@@ -27,6 +31,8 @@ export class ApiClient {
|
|
|
27
31
|
ENCODE_PATH: config?.ENCODE_PATH,
|
|
28
32
|
});
|
|
29
33
|
this.eventLogs = new EventLogsService(this.request);
|
|
34
|
+
this.settings = new SettingsService(this.request);
|
|
35
|
+
this.telegraf = new TelegrafService(this.request);
|
|
30
36
|
this.tokens = new TokensService(this.request);
|
|
31
37
|
this.users = new UsersService(this.request);
|
|
32
38
|
}
|
|
@@ -15,10 +15,13 @@ export { EventLogCreateDto } from './models/EventLogCreateDto';
|
|
|
15
15
|
export { EventLogTimelineDto } from './models/EventLogTimelineDto';
|
|
16
16
|
export type { EventLogTimelineQueryDto } from './models/EventLogTimelineQueryDto';
|
|
17
17
|
export { EventLogUpdateDto } from './models/EventLogUpdateDto';
|
|
18
|
+
export type { EventSettingsDto } from './models/EventSettingsDto';
|
|
18
19
|
export type { GetManyEventLogResponseDto } from './models/GetManyEventLogResponseDto';
|
|
19
20
|
export type { GetManyTokenResponseDto } from './models/GetManyTokenResponseDto';
|
|
20
21
|
export type { GetManyUserResponseDto } from './models/GetManyUserResponseDto';
|
|
21
22
|
export type { PermissionDto } from './models/PermissionDto';
|
|
23
|
+
export type { TelegramSettingsDto } from './models/TelegramSettingsDto';
|
|
24
|
+
export type { TelegramSettingsUpdateDto } from './models/TelegramSettingsUpdateDto';
|
|
22
25
|
export type { Token } from './models/Token';
|
|
23
26
|
export type { TokenCreateDto } from './models/TokenCreateDto';
|
|
24
27
|
export type { TokenUpdateDto } from './models/TokenUpdateDto';
|
|
@@ -28,5 +31,7 @@ export { UserCreateDto } from './models/UserCreateDto';
|
|
|
28
31
|
export { UserUpdateDto } from './models/UserUpdateDto';
|
|
29
32
|
|
|
30
33
|
export { EventLogsService } from './services/EventLogsService';
|
|
34
|
+
export { SettingsService } from './services/SettingsService';
|
|
35
|
+
export { TelegrafService } from './services/TelegrafService';
|
|
31
36
|
export { TokensService } from './services/TokensService';
|
|
32
37
|
export { UsersService } from './services/UsersService';
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/* generated using openapi-typescript-codegen -- do not edit */
|
|
2
|
+
/* istanbul ignore file */
|
|
3
|
+
/* tslint:disable */
|
|
4
|
+
/* eslint-disable */
|
|
5
|
+
import type { EventSettingsDto } from '../models/EventSettingsDto';
|
|
6
|
+
import type { CancelablePromise } from '../core/CancelablePromise';
|
|
7
|
+
import type { BaseHttpRequest } from '../core/BaseHttpRequest';
|
|
8
|
+
export class SettingsService {
|
|
9
|
+
constructor(public readonly httpRequest: BaseHttpRequest) {}
|
|
10
|
+
/**
|
|
11
|
+
* @returns EventSettingsDto
|
|
12
|
+
* @throws ApiError
|
|
13
|
+
*/
|
|
14
|
+
public getEventSettings(): CancelablePromise<EventSettingsDto> {
|
|
15
|
+
return this.httpRequest.request({
|
|
16
|
+
method: 'GET',
|
|
17
|
+
url: '/settings/events',
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* @returns any
|
|
22
|
+
* @throws ApiError
|
|
23
|
+
*/
|
|
24
|
+
public setEventSettings({
|
|
25
|
+
requestBody,
|
|
26
|
+
}: {
|
|
27
|
+
requestBody: EventSettingsDto,
|
|
28
|
+
}): CancelablePromise<any> {
|
|
29
|
+
return this.httpRequest.request({
|
|
30
|
+
method: 'PATCH',
|
|
31
|
+
url: '/settings/events',
|
|
32
|
+
body: requestBody,
|
|
33
|
+
mediaType: 'application/json',
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/* generated using openapi-typescript-codegen -- do not edit */
|
|
2
|
+
/* istanbul ignore file */
|
|
3
|
+
/* tslint:disable */
|
|
4
|
+
/* eslint-disable */
|
|
5
|
+
import type { TelegramSettingsDto } from '../models/TelegramSettingsDto';
|
|
6
|
+
import type { TelegramSettingsUpdateDto } from '../models/TelegramSettingsUpdateDto';
|
|
7
|
+
import type { CancelablePromise } from '../core/CancelablePromise';
|
|
8
|
+
import type { BaseHttpRequest } from '../core/BaseHttpRequest';
|
|
9
|
+
export class TelegrafService {
|
|
10
|
+
constructor(public readonly httpRequest: BaseHttpRequest) {}
|
|
11
|
+
/**
|
|
12
|
+
* @returns TelegramSettingsDto
|
|
13
|
+
* @throws ApiError
|
|
14
|
+
*/
|
|
15
|
+
public getTelegramSettings(): CancelablePromise<TelegramSettingsDto> {
|
|
16
|
+
return this.httpRequest.request({
|
|
17
|
+
method: 'GET',
|
|
18
|
+
url: '/telegraf/telegram',
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* @returns any
|
|
23
|
+
* @throws ApiError
|
|
24
|
+
*/
|
|
25
|
+
public setTelegramSettings({
|
|
26
|
+
requestBody,
|
|
27
|
+
}: {
|
|
28
|
+
requestBody: TelegramSettingsUpdateDto,
|
|
29
|
+
}): CancelablePromise<any> {
|
|
30
|
+
return this.httpRequest.request({
|
|
31
|
+
method: 'PATCH',
|
|
32
|
+
url: '/telegraf/telegram',
|
|
33
|
+
body: requestBody,
|
|
34
|
+
mediaType: 'application/json',
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* @returns any
|
|
39
|
+
* @throws ApiError
|
|
40
|
+
*/
|
|
41
|
+
public testTelegraf(): CancelablePromise<any> {
|
|
42
|
+
return this.httpRequest.request({
|
|
43
|
+
method: 'POST',
|
|
44
|
+
url: '/telegraf/test',
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|