seeder-st2110-components 1.7.12 → 1.7.14
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/dist/index.esm.js +1068 -924
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1067 -923
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { memo, useState, useCallback, useMemo, useEffect, useRef } from 'react';
|
|
2
|
-
import { Tooltip, Modal, App, Form, Input,
|
|
2
|
+
import { Tooltip, Modal, App, Alert, Form, Input, message, Dropdown, Spin, Divider, Typography, InputNumber, ConfigProvider, Badge, Switch, Select, List, Empty, Button, Space, Flex, Checkbox, Row, Col, Result } from 'antd';
|
|
3
3
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
import { useWebSocket, useInterval } from 'ahooks';
|
|
5
5
|
import { LoadingOutlined, ExclamationCircleFilled, PlusOutlined } from '@ant-design/icons';
|
|
@@ -69,6 +69,260 @@ function _toPropertyKey$1(t) {
|
|
|
69
69
|
return "symbol" == typeof i ? i : i + "";
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
/**
|
|
73
|
+
* 国际化调试工具
|
|
74
|
+
* 在浏览器控制台运行 window.debugI18n() 查看当前国际化状态
|
|
75
|
+
*/
|
|
76
|
+
|
|
77
|
+
const debugI18n = () => {
|
|
78
|
+
var _window$g_initialProp, _window$g_initialProp2, _window$g_initialProp3, _window$g_initialProp4, _window$g_initialProp5, _window$g_initialProp6;
|
|
79
|
+
if (typeof window === 'undefined') {
|
|
80
|
+
console.log('[i18n debug] Not in browser environment');
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
console.group('🌍 I18n Debug Information');
|
|
84
|
+
|
|
85
|
+
// 1. 当前语言环境
|
|
86
|
+
console.log('📍 Current Locale Sources:');
|
|
87
|
+
console.log(' - window.g_initialProps?.locale:', (_window$g_initialProp = window.g_initialProps) === null || _window$g_initialProp === void 0 ? void 0 : _window$g_initialProp.locale);
|
|
88
|
+
console.log(' - window.g_initialProps?.___g_initialPropsFromServer?.locale:', (_window$g_initialProp2 = window.g_initialProps) === null || _window$g_initialProp2 === void 0 || (_window$g_initialProp2 = _window$g_initialProp2.___g_initialPropsFromServer) === null || _window$g_initialProp2 === void 0 ? void 0 : _window$g_initialProp2.locale);
|
|
89
|
+
try {
|
|
90
|
+
console.log(' - localStorage.umi-locale:', localStorage.getItem('umi-locale'));
|
|
91
|
+
} catch (e) {
|
|
92
|
+
console.log(' - localStorage: not available');
|
|
93
|
+
}
|
|
94
|
+
console.log(' - window.__COMPONENT_LOCALE__:', window.__COMPONENT_LOCALE__);
|
|
95
|
+
|
|
96
|
+
// 2. 语言包
|
|
97
|
+
console.log('\n📦 Available Message Sources:');
|
|
98
|
+
console.log(' - window.__COMPONENT_I18N_MESSAGES__:', window.__COMPONENT_I18N_MESSAGES__);
|
|
99
|
+
console.log(' - window.__PROJECT_I18N_MESSAGES__:', window.__PROJECT_I18N_MESSAGES__);
|
|
100
|
+
console.log(' - window.g_initialProps?.messages:', (_window$g_initialProp3 = window.g_initialProps) === null || _window$g_initialProp3 === void 0 ? void 0 : _window$g_initialProp3.messages);
|
|
101
|
+
|
|
102
|
+
// 3. 合并后的语言包
|
|
103
|
+
const componentMessages = window.__COMPONENT_I18N_MESSAGES__ || {};
|
|
104
|
+
const projectMessages = window.__PROJECT_I18N_MESSAGES__ || {};
|
|
105
|
+
const umiMessages = ((_window$g_initialProp4 = window.g_initialProps) === null || _window$g_initialProp4 === void 0 ? void 0 : _window$g_initialProp4.messages) || {};
|
|
106
|
+
const allLocales = new Set([...Object.keys(componentMessages), ...Object.keys(projectMessages), ...Object.keys(umiMessages)]);
|
|
107
|
+
console.log('\n🔧 Merged Locales:', Array.from(allLocales));
|
|
108
|
+
allLocales.forEach(locale => {
|
|
109
|
+
const merged = _objectSpread2$1(_objectSpread2$1(_objectSpread2$1({}, umiMessages[locale] || {}), projectMessages[locale] || {}), componentMessages[locale] || {});
|
|
110
|
+
console.log("\n \uD83D\uDCC4 ".concat(locale, " (").concat(Object.keys(merged).length, " keys):"), merged);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// 4. 测试几个关键的 key
|
|
114
|
+
console.log('\n🧪 Test Translation:');
|
|
115
|
+
const testKeys = ['networkSettings.title', 'button.ok', 'button.cancel', 'button.apply', 'button.close'];
|
|
116
|
+
const currentLocale = ((_window$g_initialProp5 = window.g_initialProps) === null || _window$g_initialProp5 === void 0 ? void 0 : _window$g_initialProp5.locale) || ((_window$g_initialProp6 = window.g_initialProps) === null || _window$g_initialProp6 === void 0 || (_window$g_initialProp6 = _window$g_initialProp6.___g_initialPropsFromServer) === null || _window$g_initialProp6 === void 0 ? void 0 : _window$g_initialProp6.locale) || localStorage.getItem('umi-locale') || 'zh-CN';
|
|
117
|
+
const allMessages = {};
|
|
118
|
+
allLocales.forEach(locale => {
|
|
119
|
+
allMessages[locale] = _objectSpread2$1(_objectSpread2$1(_objectSpread2$1({}, umiMessages[locale] || {}), projectMessages[locale] || {}), componentMessages[locale] || {});
|
|
120
|
+
});
|
|
121
|
+
testKeys.forEach(key => {
|
|
122
|
+
var _allMessages$currentL, _allMessages$enUS;
|
|
123
|
+
const translation = ((_allMessages$currentL = allMessages[currentLocale]) === null || _allMessages$currentL === void 0 ? void 0 : _allMessages$currentL[key]) || ((_allMessages$enUS = allMessages['en-US']) === null || _allMessages$enUS === void 0 ? void 0 : _allMessages$enUS[key]) || '❌ NOT FOUND';
|
|
124
|
+
console.log(" - ".concat(key, ": ").concat(translation));
|
|
125
|
+
});
|
|
126
|
+
console.groupEnd();
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
// 自动在开发环境注册到 window
|
|
130
|
+
if (process.env.NODE_ENV === 'development' && typeof window !== 'undefined') {
|
|
131
|
+
window.debugI18n = debugI18n;
|
|
132
|
+
console.log('💡 I18n debug tool available. Run window.debugI18n() in console to check i18n status.');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* seeder-st2110-components 组件库国际化 Hook
|
|
137
|
+
*
|
|
138
|
+
* 设计目标:
|
|
139
|
+
* 1. 不依赖特定的国际化库(react-intl, i18next 等)
|
|
140
|
+
* 2. 可以与主项目(Umi)的国际化集成
|
|
141
|
+
* 3. 支持简单的变量替换
|
|
142
|
+
* 4. 降级处理:如果没有翻译,显示 key 本身
|
|
143
|
+
*/
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* 获取当前语言环境
|
|
147
|
+
* 优先从 Umi 全局变量读取,其次使用默认值
|
|
148
|
+
*/
|
|
149
|
+
const getLocale = () => {
|
|
150
|
+
// 尝试从 Umi 获取语言设置
|
|
151
|
+
if (typeof window !== 'undefined') {
|
|
152
|
+
var _window$g_initialProp, _window$g_initialProp2;
|
|
153
|
+
// 方式 1:Umi 的 g_initialProps
|
|
154
|
+
if ((_window$g_initialProp = window.g_initialProps) !== null && _window$g_initialProp !== void 0 && _window$g_initialProp.locale) {
|
|
155
|
+
return window.g_initialProps.locale;
|
|
156
|
+
}
|
|
157
|
+
// 方式 2:Umi 的全局语言标记
|
|
158
|
+
if ((_window$g_initialProp2 = window.g_initialProps) !== null && _window$g_initialProp2 !== void 0 && (_window$g_initialProp2 = _window$g_initialProp2.___g_initialPropsFromServer) !== null && _window$g_initialProp2 !== void 0 && _window$g_initialProp2.locale) {
|
|
159
|
+
return window.g_initialProps.___g_initialPropsFromServer.locale;
|
|
160
|
+
}
|
|
161
|
+
// 方式 3:从 localStorage 读取(Umi 默认行为)
|
|
162
|
+
try {
|
|
163
|
+
const storedLocale = localStorage.getItem('umi-locale');
|
|
164
|
+
if (storedLocale) {
|
|
165
|
+
return storedLocale;
|
|
166
|
+
}
|
|
167
|
+
} catch (e) {
|
|
168
|
+
// localStorage 不可用时忽略
|
|
169
|
+
}
|
|
170
|
+
// 方式 4:组件库自定义语言标记
|
|
171
|
+
if (window.__COMPONENT_LOCALE__) {
|
|
172
|
+
return window.__COMPONENT_LOCALE__;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// 默认语言
|
|
176
|
+
return 'zh-CN';
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* 获取语言包
|
|
181
|
+
* 优先从主项目读取,其次使用组件库自带的语言包
|
|
182
|
+
*/
|
|
183
|
+
const getMessages = () => {
|
|
184
|
+
if (typeof window !== 'undefined') {
|
|
185
|
+
var _window$g_initialProp3;
|
|
186
|
+
// 尝试从多个来源读取语言包
|
|
187
|
+
const messages = {};
|
|
188
|
+
|
|
189
|
+
// 1. 组件库注册的语言包
|
|
190
|
+
const componentMessages = window.__COMPONENT_I18N_MESSAGES__ || {};
|
|
191
|
+
|
|
192
|
+
// 2. 主项目的语言包
|
|
193
|
+
const projectMessages = window.__PROJECT_I18N_MESSAGES__ || {};
|
|
194
|
+
|
|
195
|
+
// 3. Umi 的语言包
|
|
196
|
+
const umiMessages = ((_window$g_initialProp3 = window.g_initialProps) === null || _window$g_initialProp3 === void 0 ? void 0 : _window$g_initialProp3.messages) || {};
|
|
197
|
+
|
|
198
|
+
// 合并语言包(组件库的优先级最高,其次是主项目,最后是 Umi)
|
|
199
|
+
const allLocales = new Set([...Object.keys(componentMessages), ...Object.keys(projectMessages), ...Object.keys(umiMessages)]);
|
|
200
|
+
allLocales.forEach(locale => {
|
|
201
|
+
messages[locale] = _objectSpread2$1(_objectSpread2$1(_objectSpread2$1({}, umiMessages[locale] || {}), projectMessages[locale] || {}), componentMessages[locale] || {});
|
|
202
|
+
});
|
|
203
|
+
return messages;
|
|
204
|
+
}
|
|
205
|
+
return {};
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* 格式化消息
|
|
210
|
+
* @param {string} id - 国际化 key
|
|
211
|
+
* @param {object} values - 变量替换值
|
|
212
|
+
* @param {string} locale - 语言环境
|
|
213
|
+
* @param {object} messages - 语言包
|
|
214
|
+
*/
|
|
215
|
+
const formatMessage = function (_ref) {
|
|
216
|
+
var _messages$locale, _messages$enUS;
|
|
217
|
+
let {
|
|
218
|
+
id
|
|
219
|
+
} = _ref;
|
|
220
|
+
let values = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
221
|
+
let locale = arguments.length > 2 ? arguments[2] : undefined;
|
|
222
|
+
let messages = arguments.length > 3 ? arguments[3] : undefined;
|
|
223
|
+
const message = ((_messages$locale = messages[locale]) === null || _messages$locale === void 0 ? void 0 : _messages$locale[id]) || ((_messages$enUS = messages['en-US']) === null || _messages$enUS === void 0 ? void 0 : _messages$enUS[id]) || id;
|
|
224
|
+
|
|
225
|
+
// 支持变量替换 {min}, {max}, {value} 等
|
|
226
|
+
return message.replace(/\{(\w+)\}/g, (match, key) => {
|
|
227
|
+
return values[key] !== undefined ? values[key] : match;
|
|
228
|
+
});
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* 国际化 Hook
|
|
233
|
+
*
|
|
234
|
+
* @returns {{
|
|
235
|
+
* locale: string,
|
|
236
|
+
* formatMessage: function,
|
|
237
|
+
* messages: object
|
|
238
|
+
* }}
|
|
239
|
+
*
|
|
240
|
+
* @example
|
|
241
|
+
* const intl = useIntl();
|
|
242
|
+
* const title = intl.formatMessage({ id: 'networkSettings.title' });
|
|
243
|
+
* const message = intl.formatMessage({ id: 'validation.minLength' }, { min: 3 });
|
|
244
|
+
*/
|
|
245
|
+
const useIntl = () => {
|
|
246
|
+
const locale = getLocale();
|
|
247
|
+
const messages = getMessages();
|
|
248
|
+
const formatMessageFn = function (_ref2) {
|
|
249
|
+
let {
|
|
250
|
+
id
|
|
251
|
+
} = _ref2;
|
|
252
|
+
let values = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
253
|
+
return formatMessage({
|
|
254
|
+
id
|
|
255
|
+
}, values, locale, messages);
|
|
256
|
+
};
|
|
257
|
+
return {
|
|
258
|
+
locale,
|
|
259
|
+
formatMessage: formatMessageFn,
|
|
260
|
+
messages
|
|
261
|
+
};
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* 设置语言环境(可选)
|
|
266
|
+
* 如果需要在运行时切换语言,可以调用此函数
|
|
267
|
+
*
|
|
268
|
+
* @param {string} locale - 语言代码,如 'zh-CN' 或 'en-US'
|
|
269
|
+
*/
|
|
270
|
+
const setLocale = locale => {
|
|
271
|
+
if (typeof window !== 'undefined') {
|
|
272
|
+
window.__COMPONENT_LOCALE__ = locale;
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* 注册语言包(可选)
|
|
278
|
+
* 如果需要在运行时注册语言包,可以调用此函数
|
|
279
|
+
*
|
|
280
|
+
* @param {string} locale - 语言代码
|
|
281
|
+
* @param {object} messages - 语言包对象
|
|
282
|
+
*/
|
|
283
|
+
const addMessages = (locale, messages) => {
|
|
284
|
+
if (typeof window !== 'undefined') {
|
|
285
|
+
if (!window.__COMPONENT_I18N_MESSAGES__) {
|
|
286
|
+
window.__COMPONENT_I18N_MESSAGES__ = {};
|
|
287
|
+
}
|
|
288
|
+
window.__COMPONENT_I18N_MESSAGES__[locale] = messages;
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* 初始化国际化
|
|
294
|
+
* 在组件库初始化时调用,注册默认语言包
|
|
295
|
+
*/
|
|
296
|
+
const initI18n = () => {
|
|
297
|
+
// 注册中文语言包
|
|
298
|
+
addMessages('zh-CN', {
|
|
299
|
+
'button.ok': '确定',
|
|
300
|
+
'button.cancel': '取消',
|
|
301
|
+
'button.save': '保存',
|
|
302
|
+
'button.delete': '删除',
|
|
303
|
+
'button.edit': '编辑',
|
|
304
|
+
'button.add': '添加',
|
|
305
|
+
'button.confirm': '确认',
|
|
306
|
+
'button.close': '关闭',
|
|
307
|
+
'button.apply': '应用'
|
|
308
|
+
// ... 其他默认翻译
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
// 注册英文语言包
|
|
312
|
+
addMessages('en-US', {
|
|
313
|
+
'button.ok': 'OK',
|
|
314
|
+
'button.cancel': 'Cancel',
|
|
315
|
+
'button.save': 'Save',
|
|
316
|
+
'button.delete': 'Delete',
|
|
317
|
+
'button.edit': 'Edit',
|
|
318
|
+
'button.add': 'Add',
|
|
319
|
+
'button.confirm': 'Confirm',
|
|
320
|
+
'button.close': 'Close',
|
|
321
|
+
'button.apply': 'Apply'
|
|
322
|
+
// ... 其他默认翻译
|
|
323
|
+
});
|
|
324
|
+
};
|
|
325
|
+
|
|
72
326
|
const formatBytes = function (bytes) {
|
|
73
327
|
let decimals = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
|
|
74
328
|
if (bytes === 0 || !bytes || bytes < 0) return '0 Bytes';
|
|
@@ -85,12 +339,17 @@ const UsageItem = /*#__PURE__*/memo(_ref => {
|
|
|
85
339
|
children,
|
|
86
340
|
memTotal
|
|
87
341
|
} = _ref;
|
|
342
|
+
const intl = useIntl();
|
|
88
343
|
return /*#__PURE__*/jsx(Tooltip, {
|
|
89
344
|
title: /*#__PURE__*/jsxs(Fragment, {
|
|
90
345
|
children: [/*#__PURE__*/jsx("div", {
|
|
91
346
|
children: title
|
|
92
|
-
}), title ===
|
|
93
|
-
|
|
347
|
+
}), title === intl.formatMessage({
|
|
348
|
+
id: 'usage.memory'
|
|
349
|
+
}) && memTotal !== undefined && /*#__PURE__*/jsxs("div", {
|
|
350
|
+
children: [intl.formatMessage({
|
|
351
|
+
id: 'usage.totalMemory'
|
|
352
|
+
}), ": ", formatBytes(memTotal)]
|
|
94
353
|
})]
|
|
95
354
|
}),
|
|
96
355
|
destroyOnHidden: false,
|
|
@@ -198,43 +457,60 @@ const createMetricItem = (title, iconClass, value, unit) => {
|
|
|
198
457
|
value: numValue
|
|
199
458
|
};
|
|
200
459
|
};
|
|
201
|
-
const getItems = details => {
|
|
460
|
+
const getItems = (details, intl) => {
|
|
202
461
|
const items = [];
|
|
203
462
|
if (details.cpu_usage !== null && details.cpu_usage !== undefined) {
|
|
204
|
-
items.push(createMetricItem(
|
|
463
|
+
items.push(createMetricItem(intl.formatMessage({
|
|
464
|
+
id: 'usage.cpu'
|
|
465
|
+
}), 'seeder-icon-CPU', details.cpu_usage, '%'));
|
|
205
466
|
}
|
|
206
467
|
if (details.cpu_temp !== null && details.cpu_temp !== undefined) {
|
|
207
|
-
items.push(createMetricItem(
|
|
468
|
+
items.push(createMetricItem(intl.formatMessage({
|
|
469
|
+
id: 'usage.cpuTemp'
|
|
470
|
+
}), 'seeder-icon-CPUwendu', details.cpu_temp, '℃'));
|
|
208
471
|
}
|
|
209
472
|
if (details.mem_usage !== null && details.mem_usage !== undefined) {
|
|
210
|
-
items.push(_objectSpread2$1(_objectSpread2$1({}, createMetricItem(
|
|
473
|
+
items.push(_objectSpread2$1(_objectSpread2$1({}, createMetricItem(intl.formatMessage({
|
|
474
|
+
id: 'usage.memory'
|
|
475
|
+
}), 'seeder-icon-shiyongshuai', details.mem_usage, '%')), {}, {
|
|
211
476
|
memTotal: details.mem_total
|
|
212
477
|
}));
|
|
213
478
|
}
|
|
214
479
|
if (details.mem_temp !== null && details.mem_temp !== undefined) {
|
|
215
|
-
items.push(createMetricItem(
|
|
480
|
+
items.push(createMetricItem(intl.formatMessage({
|
|
481
|
+
id: 'usage.memTemp'
|
|
482
|
+
}), 'seeder-icon-wendu', details.mem_temp, '℃'));
|
|
216
483
|
}
|
|
217
484
|
if (details.nic_temp !== null && details.nic_temp !== undefined) {
|
|
218
|
-
items.push(createMetricItem(
|
|
485
|
+
items.push(createMetricItem(intl.formatMessage({
|
|
486
|
+
id: 'usage.nicTemp'
|
|
487
|
+
}), 'seeder-icon-wuliwangka', details.nic_temp, '℃'));
|
|
219
488
|
}
|
|
220
489
|
if (details.hd_temp !== null && details.hd_temp !== undefined) {
|
|
221
|
-
items.push(createMetricItem(
|
|
490
|
+
items.push(createMetricItem(intl.formatMessage({
|
|
491
|
+
id: 'usage.diskTemp'
|
|
492
|
+
}), 'seeder-icon-yingpan', details.hd_temp, '℃'));
|
|
222
493
|
}
|
|
223
494
|
if (details.gpu_usage !== null && details.gpu_usage !== undefined) {
|
|
224
|
-
items.push(createMetricItem(
|
|
495
|
+
items.push(createMetricItem(intl.formatMessage({
|
|
496
|
+
id: 'usage.gpu'
|
|
497
|
+
}), 'seeder-icon-gpufuwu', details.gpu_usage, '%'));
|
|
225
498
|
}
|
|
226
499
|
if (details.gpu_temp !== null && details.gpu_temp !== undefined) {
|
|
227
|
-
items.push(createMetricItem(
|
|
500
|
+
items.push(createMetricItem(intl.formatMessage({
|
|
501
|
+
id: 'usage.gpuTemp'
|
|
502
|
+
}), 'seeder-icon-CPUwendu', details.gpu_temp, '℃'));
|
|
228
503
|
}
|
|
229
504
|
return items;
|
|
230
505
|
};
|
|
231
506
|
const useHardwareUsage = socketUrl => {
|
|
507
|
+
const intl = useIntl();
|
|
232
508
|
const {
|
|
233
509
|
ps_status
|
|
234
510
|
} = useHardwareWebSocket$1(socketUrl);
|
|
235
511
|
return useMemo(() => {
|
|
236
512
|
if (!ps_status || typeof ps_status !== 'object') return null;
|
|
237
|
-
const statusItems = getItems(getDetail(ps_status));
|
|
513
|
+
const statusItems = getItems(getDetail(ps_status), intl);
|
|
238
514
|
return /*#__PURE__*/jsx("div", {
|
|
239
515
|
className: "usage-container",
|
|
240
516
|
children: statusItems.map((item, index) => /*#__PURE__*/jsx("div", {
|
|
@@ -253,14 +529,23 @@ var useHardwareUsage$1 = useHardwareUsage;
|
|
|
253
529
|
|
|
254
530
|
const _excluded$4 = ["width", "okText", "cancelText", "styles"];
|
|
255
531
|
const StyledModal$2 = props => {
|
|
532
|
+
const intl = useIntl();
|
|
256
533
|
const {
|
|
257
534
|
width = "520px",
|
|
258
|
-
okText = "
|
|
259
|
-
cancelText = "
|
|
535
|
+
okText = "button.apply",
|
|
536
|
+
cancelText = "button.close",
|
|
260
537
|
styles: propStyles = {}
|
|
261
538
|
} = props,
|
|
262
539
|
restProps = _objectWithoutProperties$1(props, _excluded$4);
|
|
263
540
|
|
|
541
|
+
// 处理国际化文本
|
|
542
|
+
const okButtonText = typeof okText === 'string' && okText.includes('.') ? intl.formatMessage({
|
|
543
|
+
id: okText
|
|
544
|
+
}) : okText;
|
|
545
|
+
const cancelButtonText = typeof cancelText === 'string' && cancelText.includes('.') ? intl.formatMessage({
|
|
546
|
+
id: cancelText
|
|
547
|
+
}) : cancelText;
|
|
548
|
+
|
|
264
549
|
// 基础样式配置
|
|
265
550
|
const baseStyles = {
|
|
266
551
|
content: {
|
|
@@ -290,8 +575,8 @@ const StyledModal$2 = props => {
|
|
|
290
575
|
const styles = _objectSpread2$1(_objectSpread2$1({}, baseStyles), propStyles);
|
|
291
576
|
return /*#__PURE__*/jsx(Modal, _objectSpread2$1({
|
|
292
577
|
width: width,
|
|
293
|
-
okText:
|
|
294
|
-
cancelText:
|
|
578
|
+
okText: okButtonText,
|
|
579
|
+
cancelText: cancelButtonText,
|
|
295
580
|
styles: styles
|
|
296
581
|
}, restProps));
|
|
297
582
|
};
|
|
@@ -302,47 +587,79 @@ const AuthorizationModal = _ref => {
|
|
|
302
587
|
onCancel,
|
|
303
588
|
onOk,
|
|
304
589
|
authData,
|
|
305
|
-
title = '
|
|
590
|
+
title = 'license.title',
|
|
306
591
|
okText,
|
|
307
|
-
cancelText = '
|
|
592
|
+
cancelText = 'license.button.ignore',
|
|
308
593
|
width = 600
|
|
309
594
|
} = _ref;
|
|
595
|
+
const intl = useIntl();
|
|
310
596
|
const {
|
|
311
597
|
message
|
|
312
598
|
} = App.useApp();
|
|
313
599
|
const [code, setCode] = useState('');
|
|
314
600
|
const {
|
|
315
601
|
accredit_status: isActivated,
|
|
316
|
-
message: statusMessage
|
|
602
|
+
message: statusMessage,
|
|
317
603
|
bios_id: uuid,
|
|
318
604
|
expires_time: expiresTime
|
|
319
605
|
} = authData || {};
|
|
606
|
+
|
|
607
|
+
// 服务端返回的状态文本映射到国际化 key
|
|
608
|
+
const getStatusMessageKey = msg => {
|
|
609
|
+
if (!msg) return 'license.status.unactivated';
|
|
610
|
+
|
|
611
|
+
// 根据服务端返回的英文文本映射
|
|
612
|
+
const statusMap = {
|
|
613
|
+
'Already activated': 'license.status.activated',
|
|
614
|
+
'Unactivated': 'license.status.unactivated',
|
|
615
|
+
'Expired': 'license.status.expired',
|
|
616
|
+
'Invalid': 'license.status.invalid'
|
|
617
|
+
};
|
|
618
|
+
return statusMap[msg] || 'license.status.unactivated';
|
|
619
|
+
};
|
|
620
|
+
const statusMessageKey = getStatusMessageKey(statusMessage);
|
|
320
621
|
const handleOk = () => {
|
|
321
622
|
const trimmedCode = code.trim();
|
|
322
623
|
if (!trimmedCode) {
|
|
323
|
-
message.error(
|
|
624
|
+
message.error(intl.formatMessage({
|
|
625
|
+
id: 'license.validation.keyRequired'
|
|
626
|
+
}));
|
|
324
627
|
return;
|
|
325
628
|
}
|
|
326
629
|
onOk(trimmedCode);
|
|
327
630
|
};
|
|
328
631
|
const statusAlert = isActivated ? /*#__PURE__*/jsx(Alert, {
|
|
329
|
-
message: "".concat(
|
|
632
|
+
message: "".concat(intl.formatMessage({
|
|
633
|
+
id: statusMessageKey
|
|
634
|
+
}), ", ").concat(intl.formatMessage({
|
|
635
|
+
id: 'license.status.expiresOn'
|
|
636
|
+
}), " ").concat(expiresTime),
|
|
330
637
|
type: "success",
|
|
331
638
|
showIcon: true
|
|
332
639
|
}) : /*#__PURE__*/jsx(Alert, {
|
|
333
|
-
message:
|
|
640
|
+
message: intl.formatMessage({
|
|
641
|
+
id: statusMessageKey
|
|
642
|
+
}),
|
|
334
643
|
type: "warning",
|
|
335
644
|
showIcon: true
|
|
336
645
|
});
|
|
337
|
-
const defaultOkText = isActivated ?
|
|
646
|
+
const defaultOkText = isActivated ? intl.formatMessage({
|
|
647
|
+
id: 'license.button.reactivate'
|
|
648
|
+
}) : intl.formatMessage({
|
|
649
|
+
id: 'license.button.activate'
|
|
650
|
+
});
|
|
338
651
|
return /*#__PURE__*/jsx(StyledModal$3, {
|
|
339
|
-
title:
|
|
652
|
+
title: intl.formatMessage({
|
|
653
|
+
id: title
|
|
654
|
+
}),
|
|
340
655
|
width: width,
|
|
341
656
|
open: true,
|
|
342
657
|
onCancel: onCancel,
|
|
343
658
|
onOk: handleOk,
|
|
344
659
|
okText: okText || defaultOkText,
|
|
345
|
-
cancelText:
|
|
660
|
+
cancelText: intl.formatMessage({
|
|
661
|
+
id: cancelText
|
|
662
|
+
}),
|
|
346
663
|
cancelButtonProps: {
|
|
347
664
|
disabled: !isActivated
|
|
348
665
|
},
|
|
@@ -363,14 +680,18 @@ const AuthorizationModal = _ref => {
|
|
|
363
680
|
},
|
|
364
681
|
children: statusAlert
|
|
365
682
|
}), /*#__PURE__*/jsx(Form.Item, {
|
|
366
|
-
label:
|
|
683
|
+
label: intl.formatMessage({
|
|
684
|
+
id: 'license.machineCode'
|
|
685
|
+
}),
|
|
367
686
|
required: true,
|
|
368
687
|
children: /*#__PURE__*/jsx(Input, {
|
|
369
688
|
value: uuid,
|
|
370
689
|
readOnly: true
|
|
371
690
|
})
|
|
372
691
|
}), /*#__PURE__*/jsx(Form.Item, {
|
|
373
|
-
label:
|
|
692
|
+
label: intl.formatMessage({
|
|
693
|
+
id: 'license.key'
|
|
694
|
+
}),
|
|
374
695
|
required: true,
|
|
375
696
|
children: /*#__PURE__*/jsx(Input.TextArea, {
|
|
376
697
|
value: code,
|
|
@@ -379,7 +700,9 @@ const AuthorizationModal = _ref => {
|
|
|
379
700
|
minRows: 6,
|
|
380
701
|
maxRows: 6
|
|
381
702
|
},
|
|
382
|
-
placeholder:
|
|
703
|
+
placeholder: intl.formatMessage({
|
|
704
|
+
id: 'license.placeholder.enterKey'
|
|
705
|
+
})
|
|
383
706
|
})
|
|
384
707
|
})]
|
|
385
708
|
})
|
|
@@ -391,12 +714,13 @@ const DEFAULT_AUTH = {
|
|
|
391
714
|
accredit_status: false,
|
|
392
715
|
// 授权状态
|
|
393
716
|
bios_id: '',
|
|
394
|
-
// 主机id
|
|
395
|
-
message: '
|
|
717
|
+
// 主机 id
|
|
718
|
+
message: 'license.status.unactivated',
|
|
396
719
|
// 激活信息
|
|
397
720
|
expires_time: '' // 授权到期时间
|
|
398
721
|
};
|
|
399
722
|
const useAuth = options => {
|
|
723
|
+
const intl = useIntl();
|
|
400
724
|
const {
|
|
401
725
|
fetchAuthInfo,
|
|
402
726
|
authorize,
|
|
@@ -449,7 +773,12 @@ const useAuth = options => {
|
|
|
449
773
|
setAuthData(commands);
|
|
450
774
|
closeModal();
|
|
451
775
|
} else {
|
|
452
|
-
|
|
776
|
+
// 处理错误消息的国际化
|
|
777
|
+
const errorMsg = commands.ciphertext_status || 'license.error.authorizationFailed';
|
|
778
|
+
const errorMessage = typeof errorMsg === 'string' && errorMsg.includes('.') ? intl.formatMessage({
|
|
779
|
+
id: errorMsg
|
|
780
|
+
}) : errorMsg;
|
|
781
|
+
messageApi.error(errorMessage);
|
|
453
782
|
}
|
|
454
783
|
}
|
|
455
784
|
} catch (error) {
|
|
@@ -488,9 +817,12 @@ const useUpgrade = _ref => {
|
|
|
488
817
|
uploadCompleteDelay = 3000,
|
|
489
818
|
statusPollingInterval = 1000
|
|
490
819
|
} = _ref;
|
|
820
|
+
const intl = useIntl();
|
|
491
821
|
const [isSpinning, setIsSpinning] = useState(false);
|
|
492
822
|
const [pollingInterval, setPollingInterval] = useState(undefined); // 间隔时间,当设置值为 undefined 时会停止计时器
|
|
493
|
-
const [currentStatus, setCurrentStatus] = useState(
|
|
823
|
+
const [currentStatus, setCurrentStatus] = useState(intl.formatMessage({
|
|
824
|
+
id: 'upgrade.status.idle'
|
|
825
|
+
})); // 'idle' | 'uploading' | 'Upload complete, starting upgrade...' | 'upgrading'
|
|
494
826
|
const [uploadProgress, setUploadProgress] = useState(0);
|
|
495
827
|
const inputRef = useRef(null);
|
|
496
828
|
// 控制并发上传
|
|
@@ -514,27 +846,29 @@ const useUpgrade = _ref => {
|
|
|
514
846
|
}
|
|
515
847
|
const licenseIndex = menuItems.findIndex(item => item.key === 'license');
|
|
516
848
|
|
|
517
|
-
// 如果没有license,在末尾添加
|
|
849
|
+
// 如果没有 license,在末尾添加
|
|
518
850
|
if (licenseIndex === -1) {
|
|
519
851
|
const itemsToAdd = [];
|
|
520
852
|
if (menuItems.length > 0) itemsToAdd.push({
|
|
521
853
|
type: 'divider'
|
|
522
854
|
});
|
|
523
|
-
// if (!hasDownload) itemsToAdd.push({ key: "download", label:
|
|
855
|
+
// if (!hasDownload) itemsToAdd.push({ key: "download", label: intl.formatMessage({ id: 'upgrade.menu.download' }) });
|
|
524
856
|
if (!hasUpload) itemsToAdd.push({
|
|
525
857
|
key: "upload",
|
|
526
|
-
label:
|
|
858
|
+
label: intl.formatMessage({
|
|
859
|
+
id: 'upgrade.menu.softwareUpdate'
|
|
860
|
+
})
|
|
527
861
|
});
|
|
528
862
|
return [...menuItems, ...itemsToAdd];
|
|
529
863
|
}
|
|
530
864
|
|
|
531
|
-
// 有license,在license前面插入
|
|
865
|
+
// 有 license,在 license 前面插入
|
|
532
866
|
const beforeLicense = menuItems.slice(0, licenseIndex);
|
|
533
867
|
const licenseItem = menuItems[licenseIndex];
|
|
534
868
|
const afterLicense = menuItems.slice(licenseIndex + 1);
|
|
535
869
|
const itemsToInsert = [];
|
|
536
870
|
|
|
537
|
-
// 1. 前面的分隔符(如果beforeLicense不为空且最后一项不是分隔符)
|
|
871
|
+
// 1. 前面的分隔符(如果 beforeLicense 不为空且最后一项不是分隔符)
|
|
538
872
|
if (beforeLicense.length > 0 && beforeLicense[beforeLicense.length - 1].type !== 'divider') {
|
|
539
873
|
itemsToInsert.push({
|
|
540
874
|
type: 'divider'
|
|
@@ -542,18 +876,20 @@ const useUpgrade = _ref => {
|
|
|
542
876
|
}
|
|
543
877
|
|
|
544
878
|
// 2. 添加缺少的项
|
|
545
|
-
// if (!hasDownload) itemsToInsert.push({ key: "download", label:
|
|
879
|
+
// if (!hasDownload) itemsToInsert.push({ key: "download", label: intl.formatMessage({ id: 'upgrade.menu.download' }) });
|
|
546
880
|
if (!hasUpload) itemsToInsert.push({
|
|
547
881
|
key: "upload",
|
|
548
|
-
label:
|
|
882
|
+
label: intl.formatMessage({
|
|
883
|
+
id: 'upgrade.menu.softwareUpdate'
|
|
884
|
+
})
|
|
549
885
|
});
|
|
550
886
|
|
|
551
|
-
// 3. 后面的分隔符(与license之间)
|
|
887
|
+
// 3. 后面的分隔符(与 license 之间)
|
|
552
888
|
itemsToInsert.push({
|
|
553
889
|
type: 'divider'
|
|
554
890
|
});
|
|
555
891
|
return [...beforeLicense, ...itemsToInsert, licenseItem, ...afterLicense];
|
|
556
|
-
}, [menuItems]);
|
|
892
|
+
}, [menuItems, intl]);
|
|
557
893
|
const handleMenuClick = _ref2 => {
|
|
558
894
|
let {
|
|
559
895
|
key
|
|
@@ -577,7 +913,9 @@ const useUpgrade = _ref => {
|
|
|
577
913
|
const onDownload = async () => {
|
|
578
914
|
if (!downloadFiles) {
|
|
579
915
|
console.error('downloadFiles function is required for download operation');
|
|
580
|
-
message.error(
|
|
916
|
+
message.error(intl.formatMessage({
|
|
917
|
+
id: 'upgrade.error.downloadNotConfigured'
|
|
918
|
+
}));
|
|
581
919
|
return;
|
|
582
920
|
}
|
|
583
921
|
try {
|
|
@@ -604,7 +942,7 @@ const useUpgrade = _ref => {
|
|
|
604
942
|
});
|
|
605
943
|
const url = window.URL.createObjectURL(blob);
|
|
606
944
|
|
|
607
|
-
// 下面就是创建一个a标签并触发click事件,来下载该文件
|
|
945
|
+
// 下面就是创建一个 a 标签并触发 click 事件,来下载该文件
|
|
608
946
|
const link = document.createElement('a');
|
|
609
947
|
link.style.display = 'none';
|
|
610
948
|
link.href = url;
|
|
@@ -613,12 +951,14 @@ const useUpgrade = _ref => {
|
|
|
613
951
|
document.body.appendChild(link);
|
|
614
952
|
link.click();
|
|
615
953
|
|
|
616
|
-
// 最后移除a标签并删除创建的ObjectURL对象,防止内存泄漏
|
|
954
|
+
// 最后移除 a 标签并删除创建的 ObjectURL 对象,防止内存泄漏
|
|
617
955
|
link.parentNode.removeChild(link);
|
|
618
956
|
window.URL.revokeObjectURL(url);
|
|
619
957
|
} catch (error) {
|
|
620
958
|
console.error('Download failed:', error);
|
|
621
|
-
message.error(
|
|
959
|
+
message.error(intl.formatMessage({
|
|
960
|
+
id: 'upgrade.error.downloadFailed'
|
|
961
|
+
}));
|
|
622
962
|
}
|
|
623
963
|
};
|
|
624
964
|
const onUpload = () => {
|
|
@@ -637,7 +977,9 @@ const useUpgrade = _ref => {
|
|
|
637
977
|
}
|
|
638
978
|
isUploadingRef.current = true;
|
|
639
979
|
showLoader();
|
|
640
|
-
setCurrentStatus(
|
|
980
|
+
setCurrentStatus(intl.formatMessage({
|
|
981
|
+
id: 'upgrade.status.uploading'
|
|
982
|
+
}));
|
|
641
983
|
setUploadProgress(0);
|
|
642
984
|
|
|
643
985
|
// 重置取消令牌
|
|
@@ -663,9 +1005,11 @@ const useUpgrade = _ref => {
|
|
|
663
1005
|
|
|
664
1006
|
// 检查业务 code
|
|
665
1007
|
if ((response === null || response === void 0 ? void 0 : response.code) !== 200) {
|
|
666
|
-
// 即使上传成功,但如果服务器返回非200,说明有问题
|
|
1008
|
+
// 即使上传成功,但如果服务器返回非 200,说明有问题
|
|
667
1009
|
if (isMountedRef.current) {
|
|
668
|
-
const errorMsg = (response === null || response === void 0 ? void 0 : response.message) ||
|
|
1010
|
+
const errorMsg = (response === null || response === void 0 ? void 0 : response.message) || intl.formatMessage({
|
|
1011
|
+
id: 'upgrade.error.invalidFileFormat'
|
|
1012
|
+
});
|
|
669
1013
|
message.error(errorMsg);
|
|
670
1014
|
cancelRequest();
|
|
671
1015
|
}
|
|
@@ -674,19 +1018,25 @@ const useUpgrade = _ref => {
|
|
|
674
1018
|
|
|
675
1019
|
// 上传成功,进入等待升级阶段
|
|
676
1020
|
if (!isMountedRef.current) return;
|
|
677
|
-
setCurrentStatus(
|
|
1021
|
+
setCurrentStatus(intl.formatMessage({
|
|
1022
|
+
id: 'upgrade.status.uploadComplete'
|
|
1023
|
+
}));
|
|
678
1024
|
|
|
679
1025
|
// 延迟后启动轮询
|
|
680
1026
|
setTimeout(() => {
|
|
681
1027
|
if (!isMountedRef.current) return;
|
|
682
1028
|
setPollingInterval(statusPollingInterval);
|
|
683
|
-
setCurrentStatus(
|
|
1029
|
+
setCurrentStatus(intl.formatMessage({
|
|
1030
|
+
id: 'upgrade.status.upgrading'
|
|
1031
|
+
}));
|
|
684
1032
|
}, uploadCompleteDelay);
|
|
685
1033
|
} catch (error) {
|
|
686
1034
|
if (!isMountedRef.current) return;
|
|
687
1035
|
if (!axios.isCancel(error)) {
|
|
688
1036
|
console.error("Upload error:", error);
|
|
689
|
-
message.error(
|
|
1037
|
+
message.error(intl.formatMessage({
|
|
1038
|
+
id: 'upgrade.error.uploadFailed'
|
|
1039
|
+
}));
|
|
690
1040
|
}
|
|
691
1041
|
cancelRequest();
|
|
692
1042
|
} finally {
|
|
@@ -733,7 +1083,9 @@ const useUpgrade = _ref => {
|
|
|
733
1083
|
default:
|
|
734
1084
|
// 其他 code 如 500、400 等
|
|
735
1085
|
if (isMountedRef.current) {
|
|
736
|
-
message.error(statusMessage ||
|
|
1086
|
+
message.error(statusMessage || intl.formatMessage({
|
|
1087
|
+
id: 'upgrade.error.upgradeFailed'
|
|
1088
|
+
}));
|
|
737
1089
|
cancelRequest();
|
|
738
1090
|
}
|
|
739
1091
|
break;
|
|
@@ -799,7 +1151,9 @@ const useUpgrade = _ref => {
|
|
|
799
1151
|
},
|
|
800
1152
|
spin: true
|
|
801
1153
|
}),
|
|
802
|
-
tip: currentStatus ===
|
|
1154
|
+
tip: currentStatus === intl.formatMessage({
|
|
1155
|
+
id: 'upgrade.status.uploading'
|
|
1156
|
+
}) ? "".concat(currentStatus, " ").concat(uploadProgress, "%") : currentStatus,
|
|
803
1157
|
size: "large",
|
|
804
1158
|
fullscreen: true
|
|
805
1159
|
})]
|
|
@@ -812,21 +1166,37 @@ const useSystemOperations = function () {
|
|
|
812
1166
|
let {
|
|
813
1167
|
onPowerOff,
|
|
814
1168
|
onRestart,
|
|
815
|
-
confirmTitle = "
|
|
816
|
-
cancelText = "
|
|
817
|
-
okText = "
|
|
1169
|
+
confirmTitle = "system.confirm.title",
|
|
1170
|
+
cancelText = "system.button.cancel",
|
|
1171
|
+
okText = "system.button.confirm",
|
|
818
1172
|
run
|
|
819
1173
|
} = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
1174
|
+
const intl = useIntl();
|
|
820
1175
|
const {
|
|
821
1176
|
modal: AntdModal
|
|
822
1177
|
} = App.useApp();
|
|
1178
|
+
|
|
1179
|
+
// 处理国际化文本
|
|
1180
|
+
const confirmTitleText = typeof confirmTitle === 'string' && confirmTitle.includes('.') ? intl.formatMessage({
|
|
1181
|
+
id: confirmTitle
|
|
1182
|
+
}) : confirmTitle;
|
|
1183
|
+
const cancelTextValue = typeof cancelText === 'string' && cancelText.includes('.') ? intl.formatMessage({
|
|
1184
|
+
id: cancelText
|
|
1185
|
+
}) : cancelText;
|
|
1186
|
+
const okTextValue = typeof okText === 'string' && okText.includes('.') ? intl.formatMessage({
|
|
1187
|
+
id: okText
|
|
1188
|
+
}) : okText;
|
|
823
1189
|
const doAction = useCallback(action => {
|
|
824
1190
|
try {
|
|
825
1191
|
AntdModal.confirm({
|
|
826
1192
|
icon: /*#__PURE__*/jsx(ExclamationCircleFilled, {}),
|
|
827
|
-
title: "".concat(
|
|
828
|
-
|
|
829
|
-
|
|
1193
|
+
title: "".concat(confirmTitleText, " ").concat(action === 'poweroff' ? intl.formatMessage({
|
|
1194
|
+
id: 'system.action.powerOff'
|
|
1195
|
+
}) : intl.formatMessage({
|
|
1196
|
+
id: 'system.action.restart'
|
|
1197
|
+
}), "?"),
|
|
1198
|
+
cancelText: cancelTextValue,
|
|
1199
|
+
okText: okTextValue,
|
|
830
1200
|
onOk: () => {
|
|
831
1201
|
if (action === 'poweroff' && onPowerOff) {
|
|
832
1202
|
onPowerOff();
|
|
@@ -843,14 +1213,18 @@ const useSystemOperations = function () {
|
|
|
843
1213
|
} catch (error) {
|
|
844
1214
|
console.error("".concat(action.toUpperCase(), " ERROR: "), error);
|
|
845
1215
|
}
|
|
846
|
-
}, [AntdModal,
|
|
1216
|
+
}, [AntdModal, confirmTitleText, cancelTextValue, okTextValue, onPowerOff, onRestart, intl]);
|
|
847
1217
|
const getMenuItems = useCallback(() => [{
|
|
848
1218
|
key: "poweroff",
|
|
849
|
-
label:
|
|
1219
|
+
label: intl.formatMessage({
|
|
1220
|
+
id: 'system.poweroff'
|
|
1221
|
+
})
|
|
850
1222
|
}, {
|
|
851
1223
|
key: "restart",
|
|
852
|
-
label:
|
|
853
|
-
|
|
1224
|
+
label: intl.formatMessage({
|
|
1225
|
+
id: 'system.restart'
|
|
1226
|
+
})
|
|
1227
|
+
}], [intl]);
|
|
854
1228
|
const handleMenuClick = useCallback(_ref => {
|
|
855
1229
|
let {
|
|
856
1230
|
key
|
|
@@ -1157,438 +1531,177 @@ const useHeartbeat = function (sendMessage, readyState, config, logger) {
|
|
|
1157
1531
|
}
|
|
1158
1532
|
}
|
|
1159
1533
|
}, currentConfig.interval);
|
|
1160
|
-
}, [stopHeartbeat, logger]);
|
|
1161
|
-
|
|
1162
|
-
// 自动管理心跳
|
|
1163
|
-
useEffect(() => {
|
|
1164
|
-
const currentState = stateRef.current;
|
|
1165
|
-
if (currentState.enabled) {
|
|
1166
|
-
if (currentState.readyState === 1) {
|
|
1167
|
-
startHeartbeat();
|
|
1168
|
-
} else {
|
|
1169
|
-
stopHeartbeat();
|
|
1170
|
-
}
|
|
1171
|
-
} else {
|
|
1172
|
-
stopHeartbeat();
|
|
1173
|
-
}
|
|
1174
|
-
return () => {
|
|
1175
|
-
if (heartbeatTimerRef.current) {
|
|
1176
|
-
clearInterval(heartbeatTimerRef.current);
|
|
1177
|
-
heartbeatTimerRef.current = null;
|
|
1178
|
-
}
|
|
1179
|
-
};
|
|
1180
|
-
}, [readyState, enabled, startHeartbeat, stopHeartbeat]);
|
|
1181
|
-
const heartbeatImpl = useMemo(() => {
|
|
1182
|
-
if (!enabled) {
|
|
1183
|
-
return {
|
|
1184
|
-
startHeartbeat: () => {},
|
|
1185
|
-
stopHeartbeat: () => {},
|
|
1186
|
-
getLastHeartbeatTime: () => null,
|
|
1187
|
-
isEnabled: false
|
|
1188
|
-
};
|
|
1189
|
-
}
|
|
1190
|
-
return {
|
|
1191
|
-
startHeartbeat,
|
|
1192
|
-
stopHeartbeat,
|
|
1193
|
-
getLastHeartbeatTime: () => lastHeartbeatTimeRef.current,
|
|
1194
|
-
isEnabled: true
|
|
1195
|
-
};
|
|
1196
|
-
}, [enabled, startHeartbeat, stopHeartbeat]);
|
|
1197
|
-
return heartbeatImpl;
|
|
1198
|
-
};
|
|
1199
|
-
const useWebSocketWithFeatures = config => {
|
|
1200
|
-
const {
|
|
1201
|
-
url,
|
|
1202
|
-
options = {},
|
|
1203
|
-
heartbeat: heartbeatConfig = false,
|
|
1204
|
-
enableLog = true
|
|
1205
|
-
} = config;
|
|
1206
|
-
const [isConnected, setIsConnected] = useState(false);
|
|
1207
|
-
|
|
1208
|
-
// 创建 logger 实例
|
|
1209
|
-
const logger = useMemo(() => {
|
|
1210
|
-
if (enableLog) {
|
|
1211
|
-
return createGlobalLogger(url);
|
|
1212
|
-
}
|
|
1213
|
-
return createDummyLogger();
|
|
1214
|
-
}, [url, enableLog]);
|
|
1215
|
-
const websocketOptions = useMemo(() => _objectSpread2$1(_objectSpread2$1({}, options), {}, {
|
|
1216
|
-
onOpen: event => {
|
|
1217
|
-
var _options$onOpen;
|
|
1218
|
-
logger.log('INFO', 'WebSocket 连接成功', {
|
|
1219
|
-
url,
|
|
1220
|
-
readyState: getReadyStateText(1),
|
|
1221
|
-
// 连接成功时 readyState 为 1
|
|
1222
|
-
eventCode: event === null || event === void 0 ? void 0 : event.code
|
|
1223
|
-
});
|
|
1224
|
-
setIsConnected(true);
|
|
1225
|
-
(_options$onOpen = options.onOpen) === null || _options$onOpen === void 0 || _options$onOpen.call(options, event);
|
|
1226
|
-
},
|
|
1227
|
-
onError: error => {
|
|
1228
|
-
var _options$onError;
|
|
1229
|
-
logger.log('ERROR', 'WebSocket 连接错误', {
|
|
1230
|
-
url,
|
|
1231
|
-
error: error.message,
|
|
1232
|
-
errorType: error.type,
|
|
1233
|
-
readyState: getReadyStateText(3) // 错误时 readyState 为 3
|
|
1234
|
-
});
|
|
1235
|
-
setIsConnected(false);
|
|
1236
|
-
(_options$onError = options.onError) === null || _options$onError === void 0 || _options$onError.call(options, error);
|
|
1237
|
-
},
|
|
1238
|
-
onClose: event => {
|
|
1239
|
-
var _options$onClose;
|
|
1240
|
-
logger.log('WARN', 'WebSocket 连接断开', {
|
|
1241
|
-
url,
|
|
1242
|
-
code: event.code,
|
|
1243
|
-
reason: event.reason,
|
|
1244
|
-
wasClean: event.wasClean,
|
|
1245
|
-
readyState: getReadyStateText(3) // 关闭时 readyState 为 3
|
|
1246
|
-
});
|
|
1247
|
-
setIsConnected(false);
|
|
1248
|
-
(_options$onClose = options.onClose) === null || _options$onClose === void 0 || _options$onClose.call(options, event);
|
|
1249
|
-
},
|
|
1250
|
-
onReconnect: count => {
|
|
1251
|
-
var _options$onReconnect;
|
|
1252
|
-
logger.log('INFO', '尝试重新连接', {
|
|
1253
|
-
url,
|
|
1254
|
-
attempt: count,
|
|
1255
|
-
maxAttempts: options.reconnectLimit || 10
|
|
1256
|
-
});
|
|
1257
|
-
(_options$onReconnect = options.onReconnect) === null || _options$onReconnect === void 0 || _options$onReconnect.call(options, count);
|
|
1258
|
-
}
|
|
1259
|
-
}), [url, options, logger]);
|
|
1260
|
-
const {
|
|
1261
|
-
latestMessage,
|
|
1262
|
-
readyState,
|
|
1263
|
-
sendMessage,
|
|
1264
|
-
connect,
|
|
1265
|
-
disconnect
|
|
1266
|
-
} = useWebSocket(url, websocketOptions);
|
|
1267
|
-
const heartbeatOptions = useMemo(() => heartbeatConfig === true ? {} : heartbeatConfig, [heartbeatConfig]);
|
|
1268
|
-
const heartbeatEnabled = useMemo(() => heartbeatConfig !== false, [heartbeatConfig]);
|
|
1269
|
-
const heartbeat = useHeartbeat(sendMessage, readyState, heartbeatOptions, logger, heartbeatEnabled);
|
|
1270
|
-
|
|
1271
|
-
// 在全局暴露日志方法
|
|
1272
|
-
useEffect(() => {
|
|
1273
|
-
if (typeof window !== 'undefined' && enableLog) {
|
|
1274
|
-
// 生成唯一的键名:基于URL进行base64编码
|
|
1275
|
-
const key = "exportWebSocketLogs_".concat(btoa(url));
|
|
1276
|
-
// 在window对象上添加方法
|
|
1277
|
-
window[key] = () => logger.exportLogs();
|
|
1278
|
-
}
|
|
1279
|
-
return () => {
|
|
1280
|
-
if (typeof window !== 'undefined' && enableLog) {
|
|
1281
|
-
const key = "exportWebSocketLogs_".concat(btoa(url));
|
|
1282
|
-
delete window[key];
|
|
1283
|
-
}
|
|
1284
|
-
};
|
|
1285
|
-
}, [url, enableLog, logger]);
|
|
1286
|
-
const loggerMethods = useMemo(() => ({
|
|
1287
|
-
log: (level, message, data) => logger.log(level, message, data),
|
|
1288
|
-
exportLogs: () => logger.exportLogs(),
|
|
1289
|
-
getLogStats: () => logger.getLogStats(),
|
|
1290
|
-
clearLogs: () => logger.clearLogs()
|
|
1291
|
-
}), [logger]);
|
|
1292
|
-
return {
|
|
1293
|
-
latestMessage,
|
|
1294
|
-
readyState,
|
|
1295
|
-
sendMessage,
|
|
1296
|
-
connect,
|
|
1297
|
-
disconnect,
|
|
1298
|
-
isConnected,
|
|
1299
|
-
readyStateText: getReadyStateText(readyState),
|
|
1300
|
-
// 心跳功能
|
|
1301
|
-
heartbeat,
|
|
1302
|
-
// 日志功能
|
|
1303
|
-
logger: enableLog ? loggerMethods : null
|
|
1304
|
-
};
|
|
1305
|
-
};
|
|
1306
|
-
var useWebSocketWithFeatures$1 = useWebSocketWithFeatures;
|
|
1307
|
-
|
|
1308
|
-
// 在控制台中直接查看所有可用的导出方法 Object.keys(window).filter(key => key.startsWith('exportWebSocketLogs_'))
|
|
1309
|
-
// 导出特定连接的日志 window['exportWebSocketLogs_d3M6Ly8xOTIuMTY4LjEyMy4yMDQvd3MvZHZyL3ZpZGVvX3N0YXR1c19jaGFuZ2U=']();
|
|
1310
|
-
|
|
1311
|
-
/**
|
|
1312
|
-
* 国际化调试工具
|
|
1313
|
-
* 在浏览器控制台运行 window.debugI18n() 查看当前国际化状态
|
|
1314
|
-
*/
|
|
1315
|
-
|
|
1316
|
-
const debugI18n = () => {
|
|
1317
|
-
var _window$g_initialProp, _window$g_initialProp2, _window$g_initialProp3, _window$g_initialProp4, _window$g_initialProp5, _window$g_initialProp6;
|
|
1318
|
-
if (typeof window === 'undefined') {
|
|
1319
|
-
console.log('[i18n debug] Not in browser environment');
|
|
1320
|
-
return;
|
|
1321
|
-
}
|
|
1322
|
-
console.group('🌍 I18n Debug Information');
|
|
1323
|
-
|
|
1324
|
-
// 1. 当前语言环境
|
|
1325
|
-
console.log('📍 Current Locale Sources:');
|
|
1326
|
-
console.log(' - window.g_initialProps?.locale:', (_window$g_initialProp = window.g_initialProps) === null || _window$g_initialProp === void 0 ? void 0 : _window$g_initialProp.locale);
|
|
1327
|
-
console.log(' - window.g_initialProps?.___g_initialPropsFromServer?.locale:', (_window$g_initialProp2 = window.g_initialProps) === null || _window$g_initialProp2 === void 0 || (_window$g_initialProp2 = _window$g_initialProp2.___g_initialPropsFromServer) === null || _window$g_initialProp2 === void 0 ? void 0 : _window$g_initialProp2.locale);
|
|
1328
|
-
try {
|
|
1329
|
-
console.log(' - localStorage.umi-locale:', localStorage.getItem('umi-locale'));
|
|
1330
|
-
} catch (e) {
|
|
1331
|
-
console.log(' - localStorage: not available');
|
|
1332
|
-
}
|
|
1333
|
-
console.log(' - window.__COMPONENT_LOCALE__:', window.__COMPONENT_LOCALE__);
|
|
1334
|
-
|
|
1335
|
-
// 2. 语言包
|
|
1336
|
-
console.log('\n📦 Available Message Sources:');
|
|
1337
|
-
console.log(' - window.__COMPONENT_I18N_MESSAGES__:', window.__COMPONENT_I18N_MESSAGES__);
|
|
1338
|
-
console.log(' - window.__PROJECT_I18N_MESSAGES__:', window.__PROJECT_I18N_MESSAGES__);
|
|
1339
|
-
console.log(' - window.g_initialProps?.messages:', (_window$g_initialProp3 = window.g_initialProps) === null || _window$g_initialProp3 === void 0 ? void 0 : _window$g_initialProp3.messages);
|
|
1340
|
-
|
|
1341
|
-
// 3. 合并后的语言包
|
|
1342
|
-
const componentMessages = window.__COMPONENT_I18N_MESSAGES__ || {};
|
|
1343
|
-
const projectMessages = window.__PROJECT_I18N_MESSAGES__ || {};
|
|
1344
|
-
const umiMessages = ((_window$g_initialProp4 = window.g_initialProps) === null || _window$g_initialProp4 === void 0 ? void 0 : _window$g_initialProp4.messages) || {};
|
|
1345
|
-
const allLocales = new Set([...Object.keys(componentMessages), ...Object.keys(projectMessages), ...Object.keys(umiMessages)]);
|
|
1346
|
-
console.log('\n🔧 Merged Locales:', Array.from(allLocales));
|
|
1347
|
-
allLocales.forEach(locale => {
|
|
1348
|
-
const merged = _objectSpread2$1(_objectSpread2$1(_objectSpread2$1({}, umiMessages[locale] || {}), projectMessages[locale] || {}), componentMessages[locale] || {});
|
|
1349
|
-
console.log("\n \uD83D\uDCC4 ".concat(locale, " (").concat(Object.keys(merged).length, " keys):"), merged);
|
|
1350
|
-
});
|
|
1351
|
-
|
|
1352
|
-
// 4. 测试几个关键的 key
|
|
1353
|
-
console.log('\n🧪 Test Translation:');
|
|
1354
|
-
const testKeys = ['networkSettings.title', 'button.ok', 'button.cancel', 'button.apply', 'button.close'];
|
|
1355
|
-
const currentLocale = ((_window$g_initialProp5 = window.g_initialProps) === null || _window$g_initialProp5 === void 0 ? void 0 : _window$g_initialProp5.locale) || ((_window$g_initialProp6 = window.g_initialProps) === null || _window$g_initialProp6 === void 0 || (_window$g_initialProp6 = _window$g_initialProp6.___g_initialPropsFromServer) === null || _window$g_initialProp6 === void 0 ? void 0 : _window$g_initialProp6.locale) || localStorage.getItem('umi-locale') || 'zh-CN';
|
|
1356
|
-
const allMessages = {};
|
|
1357
|
-
allLocales.forEach(locale => {
|
|
1358
|
-
allMessages[locale] = _objectSpread2$1(_objectSpread2$1(_objectSpread2$1({}, umiMessages[locale] || {}), projectMessages[locale] || {}), componentMessages[locale] || {});
|
|
1359
|
-
});
|
|
1360
|
-
testKeys.forEach(key => {
|
|
1361
|
-
var _allMessages$currentL, _allMessages$enUS;
|
|
1362
|
-
const translation = ((_allMessages$currentL = allMessages[currentLocale]) === null || _allMessages$currentL === void 0 ? void 0 : _allMessages$currentL[key]) || ((_allMessages$enUS = allMessages['en-US']) === null || _allMessages$enUS === void 0 ? void 0 : _allMessages$enUS[key]) || '❌ NOT FOUND';
|
|
1363
|
-
console.log(" - ".concat(key, ": ").concat(translation));
|
|
1364
|
-
});
|
|
1365
|
-
console.groupEnd();
|
|
1366
|
-
};
|
|
1367
|
-
|
|
1368
|
-
// 自动在开发环境注册到 window
|
|
1369
|
-
if (process.env.NODE_ENV === 'development' && typeof window !== 'undefined') {
|
|
1370
|
-
window.debugI18n = debugI18n;
|
|
1371
|
-
console.log('💡 I18n debug tool available. Run window.debugI18n() in console to check i18n status.');
|
|
1372
|
-
}
|
|
1373
|
-
|
|
1374
|
-
/**
|
|
1375
|
-
* seeder-st2110-components 组件库国际化 Hook
|
|
1376
|
-
*
|
|
1377
|
-
* 设计目标:
|
|
1378
|
-
* 1. 不依赖特定的国际化库(react-intl, i18next 等)
|
|
1379
|
-
* 2. 可以与主项目(Umi)的国际化集成
|
|
1380
|
-
* 3. 支持简单的变量替换
|
|
1381
|
-
* 4. 降级处理:如果没有翻译,显示 key 本身
|
|
1382
|
-
*/
|
|
1383
|
-
|
|
1384
|
-
/**
|
|
1385
|
-
* 获取当前语言环境
|
|
1386
|
-
* 优先从 Umi 全局变量读取,其次使用默认值
|
|
1387
|
-
*/
|
|
1388
|
-
const getLocale = () => {
|
|
1389
|
-
// 尝试从 Umi 获取语言设置
|
|
1390
|
-
if (typeof window !== 'undefined') {
|
|
1391
|
-
var _window$g_initialProp, _window$g_initialProp2;
|
|
1392
|
-
// 方式 1:Umi 的 g_initialProps
|
|
1393
|
-
if ((_window$g_initialProp = window.g_initialProps) !== null && _window$g_initialProp !== void 0 && _window$g_initialProp.locale) {
|
|
1394
|
-
return window.g_initialProps.locale;
|
|
1395
|
-
}
|
|
1396
|
-
// 方式 2:Umi 的全局语言标记
|
|
1397
|
-
if ((_window$g_initialProp2 = window.g_initialProps) !== null && _window$g_initialProp2 !== void 0 && (_window$g_initialProp2 = _window$g_initialProp2.___g_initialPropsFromServer) !== null && _window$g_initialProp2 !== void 0 && _window$g_initialProp2.locale) {
|
|
1398
|
-
return window.g_initialProps.___g_initialPropsFromServer.locale;
|
|
1399
|
-
}
|
|
1400
|
-
// 方式 3:从 localStorage 读取(Umi 默认行为)
|
|
1401
|
-
try {
|
|
1402
|
-
const storedLocale = localStorage.getItem('umi-locale');
|
|
1403
|
-
if (storedLocale) {
|
|
1404
|
-
return storedLocale;
|
|
1405
|
-
}
|
|
1406
|
-
} catch (e) {
|
|
1407
|
-
// localStorage 不可用时忽略
|
|
1408
|
-
}
|
|
1409
|
-
// 方式 4:组件库自定义语言标记
|
|
1410
|
-
if (window.__COMPONENT_LOCALE__) {
|
|
1411
|
-
return window.__COMPONENT_LOCALE__;
|
|
1412
|
-
}
|
|
1413
|
-
}
|
|
1414
|
-
// 默认语言
|
|
1415
|
-
return 'zh-CN';
|
|
1416
|
-
};
|
|
1417
|
-
|
|
1418
|
-
/**
|
|
1419
|
-
* 获取语言包
|
|
1420
|
-
* 优先从主项目读取,其次使用组件库自带的语言包
|
|
1421
|
-
*/
|
|
1422
|
-
const getMessages = () => {
|
|
1423
|
-
if (typeof window !== 'undefined') {
|
|
1424
|
-
var _window$g_initialProp3;
|
|
1425
|
-
// 尝试从多个来源读取语言包
|
|
1426
|
-
const messages = {};
|
|
1427
|
-
|
|
1428
|
-
// 1. 组件库注册的语言包
|
|
1429
|
-
const componentMessages = window.__COMPONENT_I18N_MESSAGES__ || {};
|
|
1430
|
-
|
|
1431
|
-
// 2. 主项目的语言包
|
|
1432
|
-
const projectMessages = window.__PROJECT_I18N_MESSAGES__ || {};
|
|
1433
|
-
|
|
1434
|
-
// 3. Umi 的语言包
|
|
1435
|
-
const umiMessages = ((_window$g_initialProp3 = window.g_initialProps) === null || _window$g_initialProp3 === void 0 ? void 0 : _window$g_initialProp3.messages) || {};
|
|
1436
|
-
|
|
1437
|
-
// 合并语言包(组件库的优先级最高,其次是主项目,最后是 Umi)
|
|
1438
|
-
const allLocales = new Set([...Object.keys(componentMessages), ...Object.keys(projectMessages), ...Object.keys(umiMessages)]);
|
|
1439
|
-
allLocales.forEach(locale => {
|
|
1440
|
-
messages[locale] = _objectSpread2$1(_objectSpread2$1(_objectSpread2$1({}, umiMessages[locale] || {}), projectMessages[locale] || {}), componentMessages[locale] || {});
|
|
1441
|
-
});
|
|
1442
|
-
return messages;
|
|
1443
|
-
}
|
|
1444
|
-
return {};
|
|
1445
|
-
};
|
|
1446
|
-
|
|
1447
|
-
/**
|
|
1448
|
-
* 格式化消息
|
|
1449
|
-
* @param {string} id - 国际化 key
|
|
1450
|
-
* @param {object} values - 变量替换值
|
|
1451
|
-
* @param {string} locale - 语言环境
|
|
1452
|
-
* @param {object} messages - 语言包
|
|
1453
|
-
*/
|
|
1454
|
-
const formatMessage = function (_ref) {
|
|
1455
|
-
var _messages$locale, _messages$enUS;
|
|
1456
|
-
let {
|
|
1457
|
-
id
|
|
1458
|
-
} = _ref;
|
|
1459
|
-
let values = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
1460
|
-
let locale = arguments.length > 2 ? arguments[2] : undefined;
|
|
1461
|
-
let messages = arguments.length > 3 ? arguments[3] : undefined;
|
|
1462
|
-
const message = ((_messages$locale = messages[locale]) === null || _messages$locale === void 0 ? void 0 : _messages$locale[id]) || ((_messages$enUS = messages['en-US']) === null || _messages$enUS === void 0 ? void 0 : _messages$enUS[id]) || id;
|
|
1463
|
-
|
|
1464
|
-
// 支持变量替换 {min}, {max}, {value} 等
|
|
1465
|
-
return message.replace(/\{(\w+)\}/g, (match, key) => {
|
|
1466
|
-
return values[key] !== undefined ? values[key] : match;
|
|
1467
|
-
});
|
|
1468
|
-
};
|
|
1469
|
-
|
|
1470
|
-
/**
|
|
1471
|
-
* 国际化 Hook
|
|
1472
|
-
*
|
|
1473
|
-
* @returns {{
|
|
1474
|
-
* locale: string,
|
|
1475
|
-
* formatMessage: function,
|
|
1476
|
-
* messages: object
|
|
1477
|
-
* }}
|
|
1478
|
-
*
|
|
1479
|
-
* @example
|
|
1480
|
-
* const intl = useIntl();
|
|
1481
|
-
* const title = intl.formatMessage({ id: 'networkSettings.title' });
|
|
1482
|
-
* const message = intl.formatMessage({ id: 'validation.minLength' }, { min: 3 });
|
|
1483
|
-
*/
|
|
1484
|
-
const useIntl = () => {
|
|
1485
|
-
const locale = getLocale();
|
|
1486
|
-
const messages = getMessages();
|
|
1487
|
-
const formatMessageFn = function (_ref2) {
|
|
1488
|
-
let {
|
|
1489
|
-
id
|
|
1490
|
-
} = _ref2;
|
|
1491
|
-
let values = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
1492
|
-
return formatMessage({
|
|
1493
|
-
id
|
|
1494
|
-
}, values, locale, messages);
|
|
1495
|
-
};
|
|
1496
|
-
return {
|
|
1497
|
-
locale,
|
|
1498
|
-
formatMessage: formatMessageFn,
|
|
1499
|
-
messages
|
|
1500
|
-
};
|
|
1501
|
-
};
|
|
1502
|
-
|
|
1503
|
-
/**
|
|
1504
|
-
* 设置语言环境(可选)
|
|
1505
|
-
* 如果需要在运行时切换语言,可以调用此函数
|
|
1506
|
-
*
|
|
1507
|
-
* @param {string} locale - 语言代码,如 'zh-CN' 或 'en-US'
|
|
1508
|
-
*/
|
|
1509
|
-
const setLocale = locale => {
|
|
1510
|
-
if (typeof window !== 'undefined') {
|
|
1511
|
-
window.__COMPONENT_LOCALE__ = locale;
|
|
1512
|
-
}
|
|
1513
|
-
};
|
|
1534
|
+
}, [stopHeartbeat, logger]);
|
|
1514
1535
|
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1536
|
+
// 自动管理心跳
|
|
1537
|
+
useEffect(() => {
|
|
1538
|
+
const currentState = stateRef.current;
|
|
1539
|
+
if (currentState.enabled) {
|
|
1540
|
+
if (currentState.readyState === 1) {
|
|
1541
|
+
startHeartbeat();
|
|
1542
|
+
} else {
|
|
1543
|
+
stopHeartbeat();
|
|
1544
|
+
}
|
|
1545
|
+
} else {
|
|
1546
|
+
stopHeartbeat();
|
|
1526
1547
|
}
|
|
1527
|
-
|
|
1528
|
-
|
|
1548
|
+
return () => {
|
|
1549
|
+
if (heartbeatTimerRef.current) {
|
|
1550
|
+
clearInterval(heartbeatTimerRef.current);
|
|
1551
|
+
heartbeatTimerRef.current = null;
|
|
1552
|
+
}
|
|
1553
|
+
};
|
|
1554
|
+
}, [readyState, enabled, startHeartbeat, stopHeartbeat]);
|
|
1555
|
+
const heartbeatImpl = useMemo(() => {
|
|
1556
|
+
if (!enabled) {
|
|
1557
|
+
return {
|
|
1558
|
+
startHeartbeat: () => {},
|
|
1559
|
+
stopHeartbeat: () => {},
|
|
1560
|
+
getLastHeartbeatTime: () => null,
|
|
1561
|
+
isEnabled: false
|
|
1562
|
+
};
|
|
1563
|
+
}
|
|
1564
|
+
return {
|
|
1565
|
+
startHeartbeat,
|
|
1566
|
+
stopHeartbeat,
|
|
1567
|
+
getLastHeartbeatTime: () => lastHeartbeatTimeRef.current,
|
|
1568
|
+
isEnabled: true
|
|
1569
|
+
};
|
|
1570
|
+
}, [enabled, startHeartbeat, stopHeartbeat]);
|
|
1571
|
+
return heartbeatImpl;
|
|
1529
1572
|
};
|
|
1573
|
+
const useWebSocketWithFeatures = config => {
|
|
1574
|
+
const {
|
|
1575
|
+
url,
|
|
1576
|
+
options = {},
|
|
1577
|
+
heartbeat: heartbeatConfig = false,
|
|
1578
|
+
enableLog = true
|
|
1579
|
+
} = config;
|
|
1580
|
+
const [isConnected, setIsConnected] = useState(false);
|
|
1530
1581
|
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1582
|
+
// 创建 logger 实例
|
|
1583
|
+
const logger = useMemo(() => {
|
|
1584
|
+
if (enableLog) {
|
|
1585
|
+
return createGlobalLogger(url);
|
|
1586
|
+
}
|
|
1587
|
+
return createDummyLogger();
|
|
1588
|
+
}, [url, enableLog]);
|
|
1589
|
+
const websocketOptions = useMemo(() => _objectSpread2$1(_objectSpread2$1({}, options), {}, {
|
|
1590
|
+
onOpen: event => {
|
|
1591
|
+
var _options$onOpen;
|
|
1592
|
+
logger.log('INFO', 'WebSocket 连接成功', {
|
|
1593
|
+
url,
|
|
1594
|
+
readyState: getReadyStateText(1),
|
|
1595
|
+
// 连接成功时 readyState 为 1
|
|
1596
|
+
eventCode: event === null || event === void 0 ? void 0 : event.code
|
|
1597
|
+
});
|
|
1598
|
+
setIsConnected(true);
|
|
1599
|
+
(_options$onOpen = options.onOpen) === null || _options$onOpen === void 0 || _options$onOpen.call(options, event);
|
|
1600
|
+
},
|
|
1601
|
+
onError: error => {
|
|
1602
|
+
var _options$onError;
|
|
1603
|
+
logger.log('ERROR', 'WebSocket 连接错误', {
|
|
1604
|
+
url,
|
|
1605
|
+
error: error.message,
|
|
1606
|
+
errorType: error.type,
|
|
1607
|
+
readyState: getReadyStateText(3) // 错误时 readyState 为 3
|
|
1608
|
+
});
|
|
1609
|
+
setIsConnected(false);
|
|
1610
|
+
(_options$onError = options.onError) === null || _options$onError === void 0 || _options$onError.call(options, error);
|
|
1611
|
+
},
|
|
1612
|
+
onClose: event => {
|
|
1613
|
+
var _options$onClose;
|
|
1614
|
+
logger.log('WARN', 'WebSocket 连接断开', {
|
|
1615
|
+
url,
|
|
1616
|
+
code: event.code,
|
|
1617
|
+
reason: event.reason,
|
|
1618
|
+
wasClean: event.wasClean,
|
|
1619
|
+
readyState: getReadyStateText(3) // 关闭时 readyState 为 3
|
|
1620
|
+
});
|
|
1621
|
+
setIsConnected(false);
|
|
1622
|
+
(_options$onClose = options.onClose) === null || _options$onClose === void 0 || _options$onClose.call(options, event);
|
|
1623
|
+
},
|
|
1624
|
+
onReconnect: count => {
|
|
1625
|
+
var _options$onReconnect;
|
|
1626
|
+
logger.log('INFO', '尝试重新连接', {
|
|
1627
|
+
url,
|
|
1628
|
+
attempt: count,
|
|
1629
|
+
maxAttempts: options.reconnectLimit || 10
|
|
1630
|
+
});
|
|
1631
|
+
(_options$onReconnect = options.onReconnect) === null || _options$onReconnect === void 0 || _options$onReconnect.call(options, count);
|
|
1632
|
+
}
|
|
1633
|
+
}), [url, options, logger]);
|
|
1634
|
+
const {
|
|
1635
|
+
latestMessage,
|
|
1636
|
+
readyState,
|
|
1637
|
+
sendMessage,
|
|
1638
|
+
connect,
|
|
1639
|
+
disconnect
|
|
1640
|
+
} = useWebSocket(url, websocketOptions);
|
|
1641
|
+
const heartbeatOptions = useMemo(() => heartbeatConfig === true ? {} : heartbeatConfig, [heartbeatConfig]);
|
|
1642
|
+
const heartbeatEnabled = useMemo(() => heartbeatConfig !== false, [heartbeatConfig]);
|
|
1643
|
+
const heartbeat = useHeartbeat(sendMessage, readyState, heartbeatOptions, logger, heartbeatEnabled);
|
|
1554
1644
|
|
|
1555
|
-
//
|
|
1556
|
-
|
|
1557
|
-
'
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1645
|
+
// 在全局暴露日志方法
|
|
1646
|
+
useEffect(() => {
|
|
1647
|
+
if (typeof window !== 'undefined' && enableLog) {
|
|
1648
|
+
// 生成唯一的键名:基于URL进行base64编码
|
|
1649
|
+
const key = "exportWebSocketLogs_".concat(btoa(url));
|
|
1650
|
+
// 在window对象上添加方法
|
|
1651
|
+
window[key] = () => logger.exportLogs();
|
|
1652
|
+
}
|
|
1653
|
+
return () => {
|
|
1654
|
+
if (typeof window !== 'undefined' && enableLog) {
|
|
1655
|
+
const key = "exportWebSocketLogs_".concat(btoa(url));
|
|
1656
|
+
delete window[key];
|
|
1657
|
+
}
|
|
1658
|
+
};
|
|
1659
|
+
}, [url, enableLog, logger]);
|
|
1660
|
+
const loggerMethods = useMemo(() => ({
|
|
1661
|
+
log: (level, message, data) => logger.log(level, message, data),
|
|
1662
|
+
exportLogs: () => logger.exportLogs(),
|
|
1663
|
+
getLogStats: () => logger.getLogStats(),
|
|
1664
|
+
clearLogs: () => logger.clearLogs()
|
|
1665
|
+
}), [logger]);
|
|
1666
|
+
return {
|
|
1667
|
+
latestMessage,
|
|
1668
|
+
readyState,
|
|
1669
|
+
sendMessage,
|
|
1670
|
+
connect,
|
|
1671
|
+
disconnect,
|
|
1672
|
+
isConnected,
|
|
1673
|
+
readyStateText: getReadyStateText(readyState),
|
|
1674
|
+
// 心跳功能
|
|
1675
|
+
heartbeat,
|
|
1676
|
+
// 日志功能
|
|
1677
|
+
logger: enableLog ? loggerMethods : null
|
|
1678
|
+
};
|
|
1573
1679
|
};
|
|
1680
|
+
var useWebSocketWithFeatures$1 = useWebSocketWithFeatures;
|
|
1681
|
+
|
|
1682
|
+
// 在控制台中直接查看所有可用的导出方法 Object.keys(window).filter(key => key.startsWith('exportWebSocketLogs_'))
|
|
1683
|
+
// 导出特定连接的日志 window['exportWebSocketLogs_d3M6Ly8xOTIuMTY4LjEyMy4yMDQvd3MvZHZyL3ZpZGVvX3N0YXR1c19jaGFuZ2U=']();
|
|
1574
1684
|
|
|
1575
1685
|
// seeder-st2110-components 组件库中文语言包
|
|
1576
1686
|
var zhCN = {
|
|
1577
1687
|
// 通用按钮
|
|
1578
|
-
'button.ok': '确定',
|
|
1579
|
-
'button.cancel': '取消',
|
|
1580
|
-
'button.save': '保存',
|
|
1581
|
-
'button.delete': '删除',
|
|
1582
|
-
'button.edit': '编辑',
|
|
1583
|
-
'button.add': '添加',
|
|
1584
|
-
'button.confirm': '确认',
|
|
1585
1688
|
'button.close': '关闭',
|
|
1586
1689
|
'button.apply': '应用',
|
|
1587
|
-
|
|
1588
|
-
'
|
|
1589
|
-
'
|
|
1590
|
-
'
|
|
1591
|
-
|
|
1690
|
+
// 输入框占位符
|
|
1691
|
+
'input.placeholder.enterInteger': '请输入整数',
|
|
1692
|
+
'input.placeholder.enterPort': '请输入端口 (0-65535)',
|
|
1693
|
+
'input.placeholder.enterPayload': '请输入 Payload (96-127)',
|
|
1694
|
+
// 使用率显示
|
|
1695
|
+
'usage.memory': '内存使用率',
|
|
1696
|
+
'usage.totalMemory': '内存总量',
|
|
1697
|
+
'usage.cpu': 'CPU 使用率',
|
|
1698
|
+
'usage.disk': '磁盘使用率',
|
|
1699
|
+
'usage.cpuTemp': 'CPU 温度',
|
|
1700
|
+
'usage.memTemp': '内存温度',
|
|
1701
|
+
'usage.nicTemp': '网卡温度',
|
|
1702
|
+
'usage.diskTemp': '硬盘温度',
|
|
1703
|
+
'usage.gpu': 'GPU 使用率',
|
|
1704
|
+
'usage.gpuTemp': 'GPU 温度',
|
|
1592
1705
|
// 菜单
|
|
1593
1706
|
'menu.networkSettings': '网络设置',
|
|
1594
1707
|
'menu.ptp': 'PTP',
|
|
@@ -1599,6 +1712,7 @@ var zhCN = {
|
|
|
1599
1712
|
'menu.system': '系统',
|
|
1600
1713
|
// Network Settings Modal
|
|
1601
1714
|
'networkSettings.title': '网络设置',
|
|
1715
|
+
'networkSettings.name': '名称',
|
|
1602
1716
|
'networkSettings.ipAddress': 'IP 地址',
|
|
1603
1717
|
'networkSettings.subnetMask': '子网掩码',
|
|
1604
1718
|
'networkSettings.restartRequired': '配置已修改。是否重启以应用更改?',
|
|
@@ -1607,176 +1721,131 @@ var zhCN = {
|
|
|
1607
1721
|
'networkSettings.saveSuccess': '保存成功',
|
|
1608
1722
|
// PTP Modal
|
|
1609
1723
|
'ptp.title': 'PTP 设置',
|
|
1610
|
-
'ptp.enable': '启用 PTP',
|
|
1611
|
-
'ptp.status': 'PTP 状态',
|
|
1612
1724
|
'ptp.domainNumber': '域编号',
|
|
1613
1725
|
'ptp.priority1': '优先级 1',
|
|
1614
1726
|
'ptp.priority2': '优先级 2',
|
|
1615
1727
|
'ptp.clockClass': '时钟等级',
|
|
1728
|
+
'ptp.clockClass.atomic': '原子钟 ({value})',
|
|
1729
|
+
'ptp.clockClass.gps': 'GPS ({value})',
|
|
1730
|
+
'ptp.clockClass.slaveOnly': '仅从时钟 ({value})',
|
|
1616
1731
|
'ptp.clockAccuracy': '时钟精度',
|
|
1617
|
-
'ptp.offsetScaledLogVariance': '
|
|
1618
|
-
'ptp.
|
|
1619
|
-
'ptp.
|
|
1620
|
-
'ptp.
|
|
1621
|
-
'ptp.
|
|
1732
|
+
'ptp.offsetScaledLogVariance': '时钟偏移方差',
|
|
1733
|
+
'ptp.portIdentity': '端口标识',
|
|
1734
|
+
'ptp.grandmasterIdentity': '主时钟 ID',
|
|
1735
|
+
'ptp.utcOffset': 'UTC 偏移量',
|
|
1736
|
+
'ptp.connected': '已连接',
|
|
1737
|
+
'ptp.disconnected': '未连接',
|
|
1622
1738
|
'ptp.locked': '已锁定',
|
|
1623
1739
|
'ptp.unlocked': '未锁定',
|
|
1624
|
-
'ptp.saveSuccess': '
|
|
1625
|
-
'ptp.saveFailed': 'PTP 设置保存失败',
|
|
1740
|
+
'ptp.saveSuccess': '保存成功',
|
|
1626
1741
|
// NMOS Modal
|
|
1627
1742
|
'nmos.title': 'NMOS 设置',
|
|
1628
|
-
'nmos.enable': '启用 NMOS',
|
|
1629
1743
|
'nmos.hostAddress': '主机地址',
|
|
1630
|
-
'nmos.
|
|
1631
|
-
'nmos.
|
|
1632
|
-
'nmos.
|
|
1633
|
-
'nmos.
|
|
1634
|
-
'nmos.
|
|
1635
|
-
'nmos.
|
|
1636
|
-
'nmos.
|
|
1744
|
+
'nmos.domain': '域',
|
|
1745
|
+
'nmos.registrationPort': '注册端口',
|
|
1746
|
+
'nmos.registryAddress': '注册服务器地址',
|
|
1747
|
+
'nmos.registryVersion': '注册版本',
|
|
1748
|
+
'nmos.loggingLevel': '日志级别',
|
|
1749
|
+
'nmos.placeholder.selectHostAddress': '选择主机地址',
|
|
1750
|
+
'nmos.placeholder.selectVersion': '选择版本',
|
|
1751
|
+
'nmos.saveSuccess': '保存成功',
|
|
1637
1752
|
// Preset Modal
|
|
1638
1753
|
'preset.title': '预设管理',
|
|
1639
1754
|
'preset.name': '名称',
|
|
1640
1755
|
'preset.categories': '分类',
|
|
1641
1756
|
'preset.description': '描述',
|
|
1642
|
-
'preset.
|
|
1643
|
-
'preset.
|
|
1644
|
-
'preset.
|
|
1645
|
-
'preset.
|
|
1646
|
-
'preset.
|
|
1647
|
-
'preset.
|
|
1648
|
-
'preset.
|
|
1649
|
-
'preset.
|
|
1650
|
-
'preset.
|
|
1651
|
-
'preset.
|
|
1652
|
-
'preset.
|
|
1653
|
-
'preset.
|
|
1654
|
-
'preset.
|
|
1655
|
-
'preset.
|
|
1656
|
-
'preset.
|
|
1657
|
-
'preset.
|
|
1757
|
+
'preset.placeholder.enterName': '请输入名称',
|
|
1758
|
+
'preset.placeholder.enterDescription': '请输入描述',
|
|
1759
|
+
'preset.header.name': '名称',
|
|
1760
|
+
'preset.header.createTime': '创建时间',
|
|
1761
|
+
'preset.header.description': '描述',
|
|
1762
|
+
'preset.button.new': '新建预设',
|
|
1763
|
+
'preset.button.delete': '删除',
|
|
1764
|
+
'preset.button.load': '加载',
|
|
1765
|
+
'preset.button.save': '保存',
|
|
1766
|
+
'preset.button.edit': '编辑',
|
|
1767
|
+
'preset.button.cancel': '取消',
|
|
1768
|
+
'preset.empty.noData': '从列表中选择一个预设查看详情',
|
|
1769
|
+
'preset.empty.create': '创建新预设',
|
|
1770
|
+
'preset.untitled': '未命名',
|
|
1771
|
+
'preset.delete.title': '删除预设',
|
|
1772
|
+
'preset.delete.confirmMessage': '确定要删除预设',
|
|
1773
|
+
'preset.load.title': '加载预设',
|
|
1774
|
+
'preset.load.confirmMessage': '确定要加载预设',
|
|
1775
|
+
'preset.load.loading': '加载中...',
|
|
1776
|
+
'preset.success': '成功',
|
|
1777
|
+
'preset.validation.nameRequired': '名称是必填项',
|
|
1778
|
+
'preset.validation.categoryRequired': '请选择分类',
|
|
1779
|
+
'preset.error.noSelectionOrIdMissing': '未选择预设或预设 ID 缺失',
|
|
1658
1780
|
// License/Auth Modal
|
|
1659
|
-
'license.title': '
|
|
1660
|
-
'license.
|
|
1661
|
-
'license.
|
|
1662
|
-
'license.
|
|
1663
|
-
'license.
|
|
1664
|
-
'license.
|
|
1665
|
-
'license.
|
|
1666
|
-
'license.
|
|
1667
|
-
'license.
|
|
1668
|
-
'license.
|
|
1669
|
-
'license.
|
|
1670
|
-
'license.
|
|
1671
|
-
'license.
|
|
1672
|
-
'license.
|
|
1673
|
-
'license.features': '功能特性',
|
|
1781
|
+
'license.title': '注册许可证',
|
|
1782
|
+
'license.machineCode': '机器码',
|
|
1783
|
+
'license.key': '许可证密钥',
|
|
1784
|
+
'license.placeholder.enterKey': '请输入许可证密钥',
|
|
1785
|
+
'license.button.activate': '立即激活',
|
|
1786
|
+
'license.button.reactivate': '重新激活',
|
|
1787
|
+
'license.button.ignore': '忽略',
|
|
1788
|
+
'license.status.unactivated': '未激活',
|
|
1789
|
+
'license.status.activated': '已激活',
|
|
1790
|
+
'license.status.expired': '已过期',
|
|
1791
|
+
'license.status.invalid': '无效',
|
|
1792
|
+
'license.status.expiresOn': '到期时间',
|
|
1793
|
+
'license.validation.keyRequired': '许可证密钥不能为空',
|
|
1794
|
+
'license.error.authorizationFailed': '授权失败',
|
|
1674
1795
|
// 升级相关
|
|
1675
|
-
'upgrade.
|
|
1676
|
-
'upgrade.
|
|
1677
|
-
'upgrade.
|
|
1678
|
-
'upgrade.
|
|
1679
|
-
'upgrade.
|
|
1680
|
-
'upgrade.
|
|
1681
|
-
'upgrade.
|
|
1682
|
-
'upgrade.
|
|
1683
|
-
'upgrade.
|
|
1684
|
-
'upgrade.
|
|
1685
|
-
'upgrade.
|
|
1686
|
-
'upgrade.releaseNotes': '更新说明',
|
|
1687
|
-
'upgrade.download': '下载',
|
|
1688
|
-
'upgrade.install': '安装',
|
|
1689
|
-
'upgrade.cancel': '取消',
|
|
1796
|
+
'upgrade.menu.download': '导出配置',
|
|
1797
|
+
'upgrade.menu.softwareUpdate': '软件升级',
|
|
1798
|
+
'upgrade.status.idle': '空闲',
|
|
1799
|
+
'upgrade.status.uploading': '上传中',
|
|
1800
|
+
'upgrade.status.uploadComplete': '上传完成,开始升级...',
|
|
1801
|
+
'upgrade.status.upgrading': '升级中...',
|
|
1802
|
+
'upgrade.error.downloadNotConfigured': '下载功能未配置',
|
|
1803
|
+
'upgrade.error.downloadFailed': '下载失败',
|
|
1804
|
+
'upgrade.error.uploadFailed': '上传失败',
|
|
1805
|
+
'upgrade.error.invalidFileFormat': '上传失败:文件格式无效',
|
|
1806
|
+
'upgrade.error.upgradeFailed': '升级失败',
|
|
1690
1807
|
// 系统操作
|
|
1808
|
+
'system.poweroff': '关机',
|
|
1691
1809
|
'system.restart': '重启',
|
|
1692
|
-
'system.
|
|
1693
|
-
'system.
|
|
1694
|
-
'system.
|
|
1695
|
-
'system.
|
|
1696
|
-
'system.
|
|
1697
|
-
'system.
|
|
1698
|
-
|
|
1699
|
-
'
|
|
1700
|
-
'
|
|
1701
|
-
|
|
1702
|
-
'maintenance.
|
|
1703
|
-
'maintenance.
|
|
1704
|
-
'maintenance.
|
|
1705
|
-
'maintenance.
|
|
1706
|
-
|
|
1707
|
-
'
|
|
1708
|
-
|
|
1709
|
-
'validation.required': '此项为必填项',
|
|
1710
|
-
'validation.invalidIP': 'IP 地址格式不正确',
|
|
1711
|
-
'validation.invalidPort': '端口号范围应为 1-65535',
|
|
1712
|
-
'validation.invalidEmail': '邮箱格式不正确',
|
|
1713
|
-
'validation.minLength': '最少需要 {min} 个字符',
|
|
1714
|
-
'validation.maxLength': '最多只能有 {max} 个字符',
|
|
1715
|
-
'validation.min': '最小值为 {min}',
|
|
1716
|
-
'validation.max': '最大值为 {max}',
|
|
1717
|
-
'validation.pattern': '格式不正确',
|
|
1718
|
-
'validation.unique': '该值已存在',
|
|
1719
|
-
// 状态消息
|
|
1720
|
-
'status.loading': '加载中...',
|
|
1721
|
-
'status.saving': '保存中...',
|
|
1722
|
-
'status.deleting': '删除中...',
|
|
1723
|
-
'status.updating': '更新中...',
|
|
1724
|
-
'status.submitting': '提交中...',
|
|
1725
|
-
'status.success': '成功',
|
|
1726
|
-
'status.failed': '失败',
|
|
1727
|
-
'status.error': '错误',
|
|
1728
|
-
'status.pending': '等待中',
|
|
1729
|
-
'status.processing': '处理中',
|
|
1730
|
-
'status.completed': '已完成',
|
|
1731
|
-
'status.cancelled': '已取消',
|
|
1732
|
-
// 确认对话框
|
|
1733
|
-
'confirm.title': '确认操作',
|
|
1734
|
-
'confirm.message': '确定要执行此操作吗?',
|
|
1735
|
-
'confirm.cancel': '取消',
|
|
1736
|
-
'confirm.ok': '确定',
|
|
1737
|
-
// 空状态
|
|
1738
|
-
'empty.noData': '暂无数据',
|
|
1739
|
-
'empty.noResults': '暂无结果',
|
|
1740
|
-
'empty.noItems': '暂无项目',
|
|
1741
|
-
// 通用标签
|
|
1742
|
-
'label.name': '名称',
|
|
1743
|
-
'label.description': '描述',
|
|
1744
|
-
'label.status': '状态',
|
|
1745
|
-
'label.type': '类型',
|
|
1746
|
-
'label.action': '操作',
|
|
1747
|
-
'label.actions': '操作',
|
|
1748
|
-
'label.settings': '设置',
|
|
1749
|
-
'label.configuration': '配置',
|
|
1750
|
-
'label.information': '信息',
|
|
1751
|
-
'label.version': '版本',
|
|
1752
|
-
'label.time': '时间',
|
|
1753
|
-
'label.date': '日期',
|
|
1754
|
-
'label.enable': '启用',
|
|
1755
|
-
'label.disable': '禁用',
|
|
1756
|
-
// 占位符
|
|
1757
|
-
'placeholder.select': '请选择',
|
|
1758
|
-
'placeholder.enter': '请输入',
|
|
1759
|
-
'placeholder.search': '搜索',
|
|
1760
|
-
'placeholder.filter': '筛选'
|
|
1810
|
+
'system.action.powerOff': '关机',
|
|
1811
|
+
'system.action.restart': '重启',
|
|
1812
|
+
'system.confirm.title': '确认操作',
|
|
1813
|
+
'system.confirm.message': '确定要{action}系统吗?此操作无法撤销。',
|
|
1814
|
+
'system.button.cancel': '取消',
|
|
1815
|
+
'system.button.confirm': '确认',
|
|
1816
|
+
// Maintenance page
|
|
1817
|
+
'maintenance.restarting': '系统正在重启...',
|
|
1818
|
+
'maintenance.poweredOff': '系统已关闭',
|
|
1819
|
+
'maintenance.waiting': '请等待系统启动...',
|
|
1820
|
+
'maintenance.redirecting.countdown': '将在 {countdown} 秒后自动跳转',
|
|
1821
|
+
'maintenance.waiting.long': '系统仍在启动中,这可能需要一些时间...',
|
|
1822
|
+
'maintenance.retry': '重试连接',
|
|
1823
|
+
'maintenance.offline.description': '系统当前处于离线状态,请联系管理员开启设备。',
|
|
1824
|
+
// LSM Label
|
|
1825
|
+
'lsm.label': '标签',
|
|
1826
|
+
'lsm.placeholder.select': '请选择标签'
|
|
1761
1827
|
};
|
|
1762
1828
|
|
|
1763
1829
|
// seeder-st2110-components component library English language pack
|
|
1764
1830
|
var enUS = {
|
|
1765
1831
|
// General buttons
|
|
1766
|
-
'button.ok': 'OK',
|
|
1767
|
-
'button.cancel': 'Cancel',
|
|
1768
|
-
'button.save': 'Save',
|
|
1769
|
-
'button.delete': 'Delete',
|
|
1770
|
-
'button.edit': 'Edit',
|
|
1771
|
-
'button.add': 'Add',
|
|
1772
|
-
'button.confirm': 'Confirm',
|
|
1773
1832
|
'button.close': 'Close',
|
|
1774
1833
|
'button.apply': 'Apply',
|
|
1775
|
-
|
|
1776
|
-
'
|
|
1777
|
-
'
|
|
1778
|
-
'
|
|
1779
|
-
|
|
1834
|
+
// Input placeholders
|
|
1835
|
+
'input.placeholder.enterInteger': 'Enter an integer',
|
|
1836
|
+
'input.placeholder.enterPort': ' Enter port (0-65535)',
|
|
1837
|
+
'input.placeholder.enterPayload': 'Enter payload (96-127)',
|
|
1838
|
+
// Usage display
|
|
1839
|
+
'usage.memory': 'Memory Usage',
|
|
1840
|
+
'usage.totalMemory': 'Total Memory',
|
|
1841
|
+
'usage.cpu': 'CPU Usage',
|
|
1842
|
+
'usage.disk': 'Disk Usage',
|
|
1843
|
+
'usage.cpuTemp': 'CPU Temperature',
|
|
1844
|
+
'usage.memTemp': 'Memory Temperature',
|
|
1845
|
+
'usage.nicTemp': 'NIC Temperature',
|
|
1846
|
+
'usage.diskTemp': 'Disk Temperature',
|
|
1847
|
+
'usage.gpu': 'GPU Usage',
|
|
1848
|
+
'usage.gpuTemp': 'GPU Temperature',
|
|
1780
1849
|
// Menu
|
|
1781
1850
|
'menu.networkSettings': 'Network Settings',
|
|
1782
1851
|
'menu.ptp': 'PTP',
|
|
@@ -1787,165 +1856,118 @@ var enUS = {
|
|
|
1787
1856
|
'menu.system': 'System',
|
|
1788
1857
|
// Network Settings Modal
|
|
1789
1858
|
'networkSettings.title': 'Network Settings',
|
|
1859
|
+
'networkSettings.name': 'Name',
|
|
1790
1860
|
'networkSettings.ipAddress': 'IP Address',
|
|
1791
1861
|
'networkSettings.subnetMask': 'Netmask',
|
|
1792
1862
|
'networkSettings.restartRequired': 'Configuration modified. Restart to apply changes?',
|
|
1793
1863
|
'networkSettings.restartNow': 'Restart Now',
|
|
1794
1864
|
'networkSettings.restartLater': 'Restart Later',
|
|
1795
|
-
'networkSettings.saveSuccess': '
|
|
1865
|
+
'networkSettings.saveSuccess': 'Success',
|
|
1796
1866
|
// PTP Modal
|
|
1797
1867
|
'ptp.title': 'PTP Settings',
|
|
1798
|
-
'ptp.enable': 'Enable PTP',
|
|
1799
|
-
'ptp.status': 'PTP Status',
|
|
1800
1868
|
'ptp.domainNumber': 'Domain Number',
|
|
1801
1869
|
'ptp.priority1': 'Priority 1',
|
|
1802
1870
|
'ptp.priority2': 'Priority 2',
|
|
1803
1871
|
'ptp.clockClass': 'Clock Class',
|
|
1872
|
+
'ptp.clockClass.atomic': 'Atomic Clock ({value})',
|
|
1873
|
+
'ptp.clockClass.gps': 'GPS ({value})',
|
|
1874
|
+
'ptp.clockClass.slaveOnly': 'Slave-Only ({value})',
|
|
1804
1875
|
'ptp.clockAccuracy': 'Clock Accuracy',
|
|
1805
1876
|
'ptp.offsetScaledLogVariance': 'Offset Scaled Log Variance',
|
|
1806
|
-
'ptp.
|
|
1807
|
-
'ptp.
|
|
1808
|
-
'ptp.
|
|
1809
|
-
'ptp.
|
|
1877
|
+
'ptp.portIdentity': 'Port Identity',
|
|
1878
|
+
'ptp.grandmasterIdentity': 'Grandmaster Identity',
|
|
1879
|
+
'ptp.utcOffset': 'UTC Offset',
|
|
1880
|
+
'ptp.connected': 'Connected',
|
|
1881
|
+
'ptp.disconnected': 'Disconnected',
|
|
1810
1882
|
'ptp.locked': 'Locked',
|
|
1811
1883
|
'ptp.unlocked': 'Unlocked',
|
|
1812
|
-
'ptp.saveSuccess': '
|
|
1813
|
-
'ptp.saveFailed': 'Failed to save PTP settings',
|
|
1884
|
+
'ptp.saveSuccess': 'Success',
|
|
1814
1885
|
// NMOS Modal
|
|
1815
1886
|
'nmos.title': 'NMOS Settings',
|
|
1816
|
-
'nmos.enable': 'Enable NMOS',
|
|
1817
1887
|
'nmos.hostAddress': 'Host Address',
|
|
1818
|
-
'nmos.
|
|
1819
|
-
'nmos.
|
|
1820
|
-
'nmos.
|
|
1821
|
-
'nmos.
|
|
1822
|
-
'nmos.
|
|
1823
|
-
'nmos.
|
|
1824
|
-
'nmos.
|
|
1888
|
+
'nmos.domain': 'Domain',
|
|
1889
|
+
'nmos.registryAddress': 'Registry Address',
|
|
1890
|
+
'nmos.registrationPort': 'Registry Port',
|
|
1891
|
+
'nmos.registryVersion': 'Registry Version',
|
|
1892
|
+
'nmos.loggingLevel': 'Logging Level',
|
|
1893
|
+
'nmos.placeholder.selectHostAddress': 'Select IP address',
|
|
1894
|
+
'nmos.placeholder.selectVersion': 'Select version',
|
|
1895
|
+
'nmos.saveSuccess': 'Success',
|
|
1825
1896
|
// Preset Modal
|
|
1826
1897
|
'preset.title': 'Preset Management',
|
|
1827
1898
|
'preset.name': 'Name',
|
|
1828
1899
|
'preset.categories': 'Categories',
|
|
1829
1900
|
'preset.description': 'Description',
|
|
1830
|
-
'preset.
|
|
1831
|
-
'preset.
|
|
1832
|
-
'preset.
|
|
1833
|
-
'preset.
|
|
1834
|
-
'preset.
|
|
1835
|
-
'preset.
|
|
1836
|
-
'preset.
|
|
1837
|
-
'preset.
|
|
1838
|
-
'preset.
|
|
1839
|
-
'preset.
|
|
1840
|
-
'preset.
|
|
1841
|
-
'preset.
|
|
1842
|
-
'preset.
|
|
1843
|
-
'preset.
|
|
1844
|
-
'preset.
|
|
1845
|
-
'preset.
|
|
1901
|
+
'preset.placeholder.enterName': 'Enter name',
|
|
1902
|
+
'preset.placeholder.enterDescription': 'Enter description',
|
|
1903
|
+
'preset.header.name': 'Name',
|
|
1904
|
+
'preset.header.createTime': 'Create Time',
|
|
1905
|
+
'preset.header.description': 'Description',
|
|
1906
|
+
'preset.button.new': 'New Preset',
|
|
1907
|
+
'preset.button.delete': 'Delete',
|
|
1908
|
+
'preset.button.load': 'Load',
|
|
1909
|
+
'preset.button.save': 'Save',
|
|
1910
|
+
'preset.button.edit': 'Edit',
|
|
1911
|
+
'preset.button.cancel': 'Cancel',
|
|
1912
|
+
'preset.empty.noData': 'Select a preset from the list to view details',
|
|
1913
|
+
'preset.empty.create': 'Create New Preset',
|
|
1914
|
+
'preset.untitled': 'Untitled',
|
|
1915
|
+
'preset.delete.title': 'Delete Preset',
|
|
1916
|
+
'preset.delete.confirmMessage': 'Are you sure you want to delete preset',
|
|
1917
|
+
'preset.load.title': 'Load Preset',
|
|
1918
|
+
'preset.load.confirmMessage': 'Are you sure you want to load preset',
|
|
1919
|
+
'preset.load.loading': 'Loading...',
|
|
1920
|
+
'preset.success': 'Success',
|
|
1921
|
+
'preset.validation.nameRequired': 'Name is required',
|
|
1922
|
+
'preset.validation.categoryRequired': 'No category selected',
|
|
1923
|
+
'preset.error.noSelectionOrIdMissing': 'No preset selected or preset ID is missing',
|
|
1846
1924
|
// License/Auth Modal
|
|
1847
|
-
'license.title': 'License
|
|
1848
|
-
'license.
|
|
1849
|
-
'license.
|
|
1850
|
-
'license.
|
|
1851
|
-
'license.
|
|
1852
|
-
'license.
|
|
1853
|
-
'license.
|
|
1854
|
-
'license.
|
|
1855
|
-
'license.
|
|
1856
|
-
'license.
|
|
1857
|
-
'license.
|
|
1858
|
-
'license.
|
|
1859
|
-
'license.
|
|
1860
|
-
'license.
|
|
1861
|
-
'license.features': 'Features',
|
|
1925
|
+
'license.title': 'Register License',
|
|
1926
|
+
'license.machineCode': 'Machine Code',
|
|
1927
|
+
'license.key': 'License Key',
|
|
1928
|
+
'license.placeholder.enterKey': 'Enter your license key',
|
|
1929
|
+
'license.button.activate': 'Activate Now',
|
|
1930
|
+
'license.button.reactivate': 'Reactivate',
|
|
1931
|
+
'license.button.ignore': 'Ignore',
|
|
1932
|
+
'license.status.unactivated': 'Unactivated',
|
|
1933
|
+
'license.status.activated': 'Already activated',
|
|
1934
|
+
'license.status.expired': 'Expired',
|
|
1935
|
+
'license.status.invalid': 'Invalid',
|
|
1936
|
+
'license.status.expiresOn': 'Expires on',
|
|
1937
|
+
'license.validation.keyRequired': 'License key cannot be empty',
|
|
1938
|
+
'license.error.authorizationFailed': 'Authorization failed',
|
|
1862
1939
|
// Upgrade related
|
|
1863
|
-
'upgrade.
|
|
1864
|
-
'upgrade.
|
|
1865
|
-
'upgrade.
|
|
1866
|
-
'upgrade.
|
|
1867
|
-
'upgrade.
|
|
1868
|
-
'upgrade.
|
|
1869
|
-
'upgrade.
|
|
1870
|
-
'upgrade.
|
|
1871
|
-
'upgrade.
|
|
1872
|
-
'upgrade.
|
|
1873
|
-
'upgrade.
|
|
1874
|
-
'upgrade.releaseNotes': 'Release Notes',
|
|
1875
|
-
'upgrade.download': 'Download',
|
|
1876
|
-
'upgrade.install': 'Install',
|
|
1877
|
-
'upgrade.cancel': 'Cancel',
|
|
1940
|
+
'upgrade.menu.download': 'Download Config File',
|
|
1941
|
+
'upgrade.menu.softwareUpdate': 'Software Update',
|
|
1942
|
+
'upgrade.status.idle': 'Idle',
|
|
1943
|
+
'upgrade.status.uploading': 'Uploading...',
|
|
1944
|
+
'upgrade.status.uploadComplete': 'Upload complete, starting upgrade...',
|
|
1945
|
+
'upgrade.status.upgrading': 'Upgrading...',
|
|
1946
|
+
'upgrade.error.downloadNotConfigured': 'Download functionality not configured',
|
|
1947
|
+
'upgrade.error.downloadFailed': 'Download failed',
|
|
1948
|
+
'upgrade.error.uploadFailed': 'Upload failed',
|
|
1949
|
+
'upgrade.error.invalidFileFormat': 'Upload failed: Invalid file format',
|
|
1950
|
+
'upgrade.error.upgradeFailed': 'Upgrade failed',
|
|
1878
1951
|
// System operations
|
|
1879
|
-
'system.restart': 'Restart',
|
|
1880
|
-
'system.shutdown': 'Shutdown',
|
|
1881
1952
|
'system.poweroff': 'Power Off',
|
|
1882
|
-
'system.
|
|
1883
|
-
'system.
|
|
1884
|
-
'system.
|
|
1885
|
-
'system.
|
|
1886
|
-
'system.
|
|
1887
|
-
'system.
|
|
1888
|
-
'system.
|
|
1953
|
+
'system.restart': 'Restart',
|
|
1954
|
+
'system.action.powerOff': 'power off',
|
|
1955
|
+
'system.action.restart': 'restart',
|
|
1956
|
+
'system.confirm.title': 'Confirmation Required',
|
|
1957
|
+
'system.confirm.message': 'Are you sure you want to {action} the system? This action cannot be undone.',
|
|
1958
|
+
'system.button.cancel': 'Cancel',
|
|
1959
|
+
'system.button.confirm': 'Confirm',
|
|
1889
1960
|
// Maintenance page
|
|
1890
|
-
'maintenance.
|
|
1891
|
-
'maintenance.
|
|
1892
|
-
'maintenance.
|
|
1893
|
-
'maintenance.
|
|
1894
|
-
'maintenance.
|
|
1895
|
-
'maintenance.
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
'
|
|
1899
|
-
'
|
|
1900
|
-
'validation.invalidEmail': 'Invalid email format',
|
|
1901
|
-
'validation.minLength': 'Minimum {min} characters required',
|
|
1902
|
-
'validation.maxLength': 'Maximum {max} characters allowed',
|
|
1903
|
-
'validation.min': 'Minimum value is {min}',
|
|
1904
|
-
'validation.max': 'Maximum value is {max}',
|
|
1905
|
-
'validation.pattern': 'Invalid format',
|
|
1906
|
-
'validation.unique': 'This value already exists',
|
|
1907
|
-
// Status messages
|
|
1908
|
-
'status.loading': 'Loading...',
|
|
1909
|
-
'status.saving': 'Saving...',
|
|
1910
|
-
'status.deleting': 'Deleting...',
|
|
1911
|
-
'status.updating': 'Updating...',
|
|
1912
|
-
'status.submitting': 'Submitting...',
|
|
1913
|
-
'status.success': 'Success',
|
|
1914
|
-
'status.failed': 'Failed',
|
|
1915
|
-
'status.error': 'Error',
|
|
1916
|
-
'status.pending': 'Pending',
|
|
1917
|
-
'status.processing': 'Processing',
|
|
1918
|
-
'status.completed': 'Completed',
|
|
1919
|
-
'status.cancelled': 'Cancelled',
|
|
1920
|
-
// Confirmation dialogs
|
|
1921
|
-
'confirm.title': 'Confirm Action',
|
|
1922
|
-
'confirm.message': 'Are you sure you want to proceed?',
|
|
1923
|
-
'confirm.cancel': 'Cancel',
|
|
1924
|
-
'confirm.ok': 'OK',
|
|
1925
|
-
// Empty states
|
|
1926
|
-
'empty.noData': 'No Data',
|
|
1927
|
-
'empty.noResults': 'No Results',
|
|
1928
|
-
'empty.noItems': 'No Items',
|
|
1929
|
-
// General labels
|
|
1930
|
-
'label.name': 'Name',
|
|
1931
|
-
'label.description': 'Description',
|
|
1932
|
-
'label.status': 'Status',
|
|
1933
|
-
'label.type': 'Type',
|
|
1934
|
-
'label.action': 'Action',
|
|
1935
|
-
'label.actions': 'Actions',
|
|
1936
|
-
'label.settings': 'Settings',
|
|
1937
|
-
'label.configuration': 'Configuration',
|
|
1938
|
-
'label.information': 'Information',
|
|
1939
|
-
'label.version': 'Version',
|
|
1940
|
-
'label.time': 'Time',
|
|
1941
|
-
'label.date': 'Date',
|
|
1942
|
-
'label.enable': 'Enable',
|
|
1943
|
-
'label.disable': 'Disable',
|
|
1944
|
-
// Placeholders
|
|
1945
|
-
'placeholder.select': 'Please select',
|
|
1946
|
-
'placeholder.enter': 'Please enter',
|
|
1947
|
-
'placeholder.search': 'Search',
|
|
1948
|
-
'placeholder.filter': 'Filter'
|
|
1961
|
+
'maintenance.restarting': 'System is restarting...',
|
|
1962
|
+
'maintenance.poweredOff': 'System is powered off',
|
|
1963
|
+
'maintenance.waiting': 'Please wait while the system is starting up...',
|
|
1964
|
+
'maintenance.redirecting.countdown': 'Redirecting automatically in {countdown} second{countdown, plural, one {} other {s}}',
|
|
1965
|
+
'maintenance.waiting.long': 'Still starting up... This may take a moment.',
|
|
1966
|
+
'maintenance.retry': 'Retry connection',
|
|
1967
|
+
'maintenance.offline.description': 'The system is currently offline. Please contact your administrator to power it on.',
|
|
1968
|
+
// LSM Label
|
|
1969
|
+
'lsm.label': 'Label',
|
|
1970
|
+
'lsm.placeholder.select': 'Select label'
|
|
1949
1971
|
};
|
|
1950
1972
|
|
|
1951
1973
|
const NetworkFieldGroup = _ref => {
|
|
@@ -1961,7 +1983,7 @@ const NetworkFieldGroup = _ref => {
|
|
|
1961
1983
|
const defaultFieldConfig = {
|
|
1962
1984
|
name: {
|
|
1963
1985
|
label: intl.formatMessage({
|
|
1964
|
-
id: '
|
|
1986
|
+
id: 'networkSettings.name'
|
|
1965
1987
|
}),
|
|
1966
1988
|
enabled: true
|
|
1967
1989
|
},
|
|
@@ -1980,8 +2002,8 @@ const NetworkFieldGroup = _ref => {
|
|
|
1980
2002
|
};
|
|
1981
2003
|
const mergedFieldConfig = _objectSpread2$1(_objectSpread2$1(_objectSpread2$1({}, defaultFieldConfig), fieldConfig), {}, {
|
|
1982
2004
|
netmask: {
|
|
1983
|
-
label:
|
|
1984
|
-
enabled: (_fieldConfig$netmask$ = (_fieldConfig$netmask = fieldConfig.netmask) === null || _fieldConfig$netmask === void 0 ? void 0 : _fieldConfig$netmask.enabled) !== null && _fieldConfig$netmask$ !== void 0 ? _fieldConfig$netmask$ : defaultFieldConfig.netmask.enabled
|
|
2005
|
+
label: defaultFieldConfig.netmask.label,
|
|
2006
|
+
enabled: (_fieldConfig$netmask$ = (_fieldConfig$netmask = fieldConfig.netmask) === null || _fieldConfig$netmask === void 0 ? void 0 : _fieldConfig$netmask.enabled) !== null && _fieldConfig$netmask$ !== void 0 ? _fieldConfig$netmask$ : defaultFieldConfig.netmask.enabled
|
|
1985
2007
|
}
|
|
1986
2008
|
});
|
|
1987
2009
|
return /*#__PURE__*/jsxs(Fragment, {
|
|
@@ -2383,86 +2405,86 @@ var NetworkSettingsModal$1 = /*#__PURE__*/memo(NetworkSettingsModal);
|
|
|
2383
2405
|
|
|
2384
2406
|
const defaultFieldConfigs = {
|
|
2385
2407
|
clock_class: {
|
|
2386
|
-
label: '
|
|
2408
|
+
label: 'ptp.clockClass',
|
|
2387
2409
|
formType: 'select',
|
|
2388
2410
|
options: [{
|
|
2389
2411
|
value: 6,
|
|
2390
|
-
label: '
|
|
2412
|
+
label: 'ptp.clockClass.atomic'
|
|
2391
2413
|
}, {
|
|
2392
2414
|
value: 7,
|
|
2393
|
-
label: '
|
|
2415
|
+
label: 'ptp.clockClass.gps'
|
|
2394
2416
|
}, {
|
|
2395
2417
|
value: 248,
|
|
2396
|
-
label: '
|
|
2418
|
+
label: 'ptp.clockClass.slaveOnly'
|
|
2397
2419
|
}],
|
|
2398
2420
|
readOnly: true
|
|
2399
2421
|
},
|
|
2400
2422
|
clock_accuracy: {
|
|
2401
|
-
label: '
|
|
2423
|
+
label: 'ptp.clockAccuracy',
|
|
2402
2424
|
formType: 'number',
|
|
2403
2425
|
readOnly: true
|
|
2404
2426
|
},
|
|
2405
2427
|
offset_scaled_log_variance: {
|
|
2406
|
-
label: '
|
|
2428
|
+
label: 'ptp.offsetScaledLogVariance',
|
|
2407
2429
|
formType: 'number',
|
|
2408
2430
|
readOnly: true
|
|
2409
2431
|
},
|
|
2410
2432
|
grandmaster_priority1: {
|
|
2411
|
-
label: '
|
|
2433
|
+
label: 'ptp.priority1',
|
|
2412
2434
|
formType: 'number',
|
|
2413
2435
|
readOnly: true
|
|
2414
2436
|
},
|
|
2415
2437
|
grandmaster_priority2: {
|
|
2416
|
-
label: '
|
|
2438
|
+
label: 'ptp.priority2',
|
|
2417
2439
|
formType: 'number',
|
|
2418
2440
|
readOnly: true
|
|
2419
2441
|
},
|
|
2420
2442
|
grandmaster_identity: {
|
|
2421
|
-
label: '
|
|
2443
|
+
label: 'ptp.grandmasterIdentity',
|
|
2422
2444
|
formType: 'text',
|
|
2423
2445
|
readOnly: true
|
|
2424
2446
|
},
|
|
2425
2447
|
master_port_id: {
|
|
2426
|
-
label: '
|
|
2448
|
+
label: 'ptp.portIdentity',
|
|
2427
2449
|
formType: 'text',
|
|
2428
2450
|
readOnly: true
|
|
2429
2451
|
},
|
|
2430
2452
|
t1_domain_number: {
|
|
2431
|
-
label: '
|
|
2453
|
+
label: 'ptp.domainNumber',
|
|
2432
2454
|
formType: 'number',
|
|
2433
2455
|
min: 0,
|
|
2434
2456
|
max: 127,
|
|
2435
2457
|
readOnly: false
|
|
2436
2458
|
},
|
|
2437
2459
|
master_utc_offset: {
|
|
2438
|
-
label: '
|
|
2460
|
+
label: 'ptp.utcOffset',
|
|
2439
2461
|
formType: 'number',
|
|
2440
2462
|
readOnly: true
|
|
2441
2463
|
},
|
|
2442
2464
|
is_connected: {
|
|
2443
|
-
label: '
|
|
2465
|
+
label: 'ptp.connected',
|
|
2444
2466
|
formType: 'badge',
|
|
2445
2467
|
statusMap: {
|
|
2446
2468
|
0: {
|
|
2447
|
-
text: '
|
|
2469
|
+
text: 'ptp.disconnected',
|
|
2448
2470
|
color: 'red'
|
|
2449
2471
|
},
|
|
2450
2472
|
1: {
|
|
2451
|
-
text: '
|
|
2473
|
+
text: 'ptp.connected',
|
|
2452
2474
|
color: 'green'
|
|
2453
2475
|
}
|
|
2454
2476
|
}
|
|
2455
2477
|
},
|
|
2456
2478
|
is_locked: {
|
|
2457
|
-
label: '
|
|
2479
|
+
label: 'ptp.locked',
|
|
2458
2480
|
formType: 'badge',
|
|
2459
2481
|
statusMap: {
|
|
2460
2482
|
0: {
|
|
2461
|
-
text: '
|
|
2483
|
+
text: 'ptp.unlocked',
|
|
2462
2484
|
color: 'red'
|
|
2463
2485
|
},
|
|
2464
2486
|
1: {
|
|
2465
|
-
text: '
|
|
2487
|
+
text: 'ptp.locked',
|
|
2466
2488
|
color: 'green'
|
|
2467
2489
|
}
|
|
2468
2490
|
}
|
|
@@ -2505,6 +2527,7 @@ const PtpModal = _ref => {
|
|
|
2505
2527
|
modalProps = {},
|
|
2506
2528
|
formProps = {}
|
|
2507
2529
|
} = _ref;
|
|
2530
|
+
const intl = useIntl();
|
|
2508
2531
|
const [ptpStatus, setPtpStatus] = useState(null);
|
|
2509
2532
|
const [loading, setLoading] = useState(false);
|
|
2510
2533
|
const [form] = Form.useForm();
|
|
@@ -2535,13 +2558,26 @@ const PtpModal = _ref => {
|
|
|
2535
2558
|
if (!ptpStatus) return [];
|
|
2536
2559
|
return convertPtpStatusToArray(ptpStatus, fieldConfigs, fieldOrder);
|
|
2537
2560
|
}, [ptpStatus, fieldConfigs, fieldOrder]);
|
|
2561
|
+
|
|
2562
|
+
// 渲染 Form.Item 的 label
|
|
2563
|
+
const renderLabel = item => {
|
|
2564
|
+
// 如果 label 是国际化 key(包含点号),则使用 formatMessage
|
|
2565
|
+
if (item.label && typeof item.label === 'string' && item.label.includes('.')) {
|
|
2566
|
+
return intl.formatMessage({
|
|
2567
|
+
id: item.label
|
|
2568
|
+
});
|
|
2569
|
+
}
|
|
2570
|
+
return item.label;
|
|
2571
|
+
};
|
|
2538
2572
|
const handleSubmit = async () => {
|
|
2539
2573
|
const values = await form.getFieldsValue();
|
|
2540
2574
|
setLoading(true);
|
|
2541
2575
|
try {
|
|
2542
2576
|
const response = await updatePtpInfo(values);
|
|
2543
2577
|
if (response) {
|
|
2544
|
-
message.success(
|
|
2578
|
+
message.success(intl.formatMessage({
|
|
2579
|
+
id: 'ptp.saveSuccess'
|
|
2580
|
+
}));
|
|
2545
2581
|
setTimeout(() => {
|
|
2546
2582
|
onClose();
|
|
2547
2583
|
}, 1500);
|
|
@@ -2553,11 +2589,18 @@ const PtpModal = _ref => {
|
|
|
2553
2589
|
}
|
|
2554
2590
|
};
|
|
2555
2591
|
const renderFormItem = item => {
|
|
2556
|
-
var _item$statusMap, _item$min, _item$max;
|
|
2592
|
+
var _item$options, _item$statusMap, _item$min, _item$max;
|
|
2557
2593
|
switch (item.formType) {
|
|
2558
2594
|
case 'select':
|
|
2595
|
+
const selectOptions = (_item$options = item.options) === null || _item$options === void 0 ? void 0 : _item$options.map(opt => _objectSpread2$1(_objectSpread2$1({}, opt), {}, {
|
|
2596
|
+
label: intl.formatMessage({
|
|
2597
|
+
id: opt.label
|
|
2598
|
+
}, {
|
|
2599
|
+
value: opt.value
|
|
2600
|
+
})
|
|
2601
|
+
}));
|
|
2559
2602
|
return /*#__PURE__*/jsx(Select, {
|
|
2560
|
-
options:
|
|
2603
|
+
options: selectOptions,
|
|
2561
2604
|
disabled: item.readOnly
|
|
2562
2605
|
});
|
|
2563
2606
|
case 'switch':
|
|
@@ -2578,7 +2621,9 @@ const PtpModal = _ref => {
|
|
|
2578
2621
|
},
|
|
2579
2622
|
children: /*#__PURE__*/jsx(Badge, {
|
|
2580
2623
|
color: status.color,
|
|
2581
|
-
text:
|
|
2624
|
+
text: intl.formatMessage({
|
|
2625
|
+
id: status.text
|
|
2626
|
+
})
|
|
2582
2627
|
})
|
|
2583
2628
|
});
|
|
2584
2629
|
case 'number':
|
|
@@ -2599,11 +2644,17 @@ const PtpModal = _ref => {
|
|
|
2599
2644
|
|
|
2600
2645
|
// 合并默认模态框属性和传入的属性
|
|
2601
2646
|
const mergedModalProps = _objectSpread2$1({
|
|
2602
|
-
title:
|
|
2647
|
+
title: intl.formatMessage({
|
|
2648
|
+
id: 'ptp.title'
|
|
2649
|
+
}),
|
|
2603
2650
|
width: 650,
|
|
2604
2651
|
open,
|
|
2605
|
-
okText:
|
|
2606
|
-
|
|
2652
|
+
okText: intl.formatMessage({
|
|
2653
|
+
id: 'button.apply'
|
|
2654
|
+
}),
|
|
2655
|
+
cancelText: intl.formatMessage({
|
|
2656
|
+
id: 'button.close'
|
|
2657
|
+
}),
|
|
2607
2658
|
onCancel: onClose,
|
|
2608
2659
|
onOk: handleSubmit,
|
|
2609
2660
|
confirmLoading: loading
|
|
@@ -2624,7 +2675,7 @@ const PtpModal = _ref => {
|
|
|
2624
2675
|
return /*#__PURE__*/jsx(StyledModal$3, _objectSpread2$1(_objectSpread2$1({}, mergedModalProps), {}, {
|
|
2625
2676
|
children: /*#__PURE__*/jsx(Form, _objectSpread2$1(_objectSpread2$1({}, mergedFormProps), {}, {
|
|
2626
2677
|
children: ptpStatusArray.map(item => /*#__PURE__*/jsx(Form.Item, {
|
|
2627
|
-
label: item
|
|
2678
|
+
label: renderLabel(item),
|
|
2628
2679
|
name: item.key,
|
|
2629
2680
|
initialValue: item.value,
|
|
2630
2681
|
children: renderFormItem(item)
|
|
@@ -2643,10 +2694,21 @@ const LeftList = /*#__PURE__*/memo(_ref => {
|
|
|
2643
2694
|
onRemove,
|
|
2644
2695
|
hasPresets = dataSource.length > 0,
|
|
2645
2696
|
texts = {
|
|
2646
|
-
newButton: "
|
|
2647
|
-
removeButton: "
|
|
2697
|
+
newButton: "preset.button.new",
|
|
2698
|
+
removeButton: "preset.button.delete"
|
|
2648
2699
|
}
|
|
2649
2700
|
} = _ref;
|
|
2701
|
+
const intl = useIntl();
|
|
2702
|
+
|
|
2703
|
+
// 格式化文本的辅助函数
|
|
2704
|
+
const fmt = key => {
|
|
2705
|
+
if (typeof key === 'string' && key.includes('.')) {
|
|
2706
|
+
return intl.formatMessage({
|
|
2707
|
+
id: key
|
|
2708
|
+
});
|
|
2709
|
+
}
|
|
2710
|
+
return key;
|
|
2711
|
+
};
|
|
2650
2712
|
return /*#__PURE__*/jsxs("div", {
|
|
2651
2713
|
className: "h-full left-list-wrapper",
|
|
2652
2714
|
children: [/*#__PURE__*/jsx("div", {
|
|
@@ -2656,13 +2718,13 @@ const LeftList = /*#__PURE__*/memo(_ref => {
|
|
|
2656
2718
|
className: "grid grid-cols-3 gap-2 w-full list-header",
|
|
2657
2719
|
children: [/*#__PURE__*/jsx("div", {
|
|
2658
2720
|
className: "min-w-0",
|
|
2659
|
-
children:
|
|
2721
|
+
children: fmt('preset.header.name')
|
|
2660
2722
|
}), /*#__PURE__*/jsx("div", {
|
|
2661
2723
|
className: "min-w-0",
|
|
2662
|
-
children:
|
|
2724
|
+
children: fmt('preset.header.createTime')
|
|
2663
2725
|
}), /*#__PURE__*/jsx("div", {
|
|
2664
2726
|
className: "min-w-0",
|
|
2665
|
-
children:
|
|
2727
|
+
children: fmt('preset.header.description')
|
|
2666
2728
|
})]
|
|
2667
2729
|
}),
|
|
2668
2730
|
dataSource: dataSource,
|
|
@@ -2680,7 +2742,7 @@ const LeftList = /*#__PURE__*/memo(_ref => {
|
|
|
2680
2742
|
children: /*#__PURE__*/jsx(Typography.Text, {
|
|
2681
2743
|
ellipsis: true,
|
|
2682
2744
|
title: item.name,
|
|
2683
|
-
children: item.name ||
|
|
2745
|
+
children: item.name || fmt('preset.untitled')
|
|
2684
2746
|
})
|
|
2685
2747
|
}), /*#__PURE__*/jsx("div", {
|
|
2686
2748
|
className: "min-w-0",
|
|
@@ -2710,7 +2772,7 @@ const LeftList = /*#__PURE__*/memo(_ref => {
|
|
|
2710
2772
|
onClick: onAddNew,
|
|
2711
2773
|
className: "p-0 h-auto",
|
|
2712
2774
|
icon: /*#__PURE__*/jsx(PlusOutlined, {}),
|
|
2713
|
-
children:
|
|
2775
|
+
children: fmt('preset.empty.create')
|
|
2714
2776
|
})
|
|
2715
2777
|
})
|
|
2716
2778
|
})
|
|
@@ -2776,26 +2838,44 @@ const RightDetailForm = /*#__PURE__*/memo(_ref3 => {
|
|
|
2776
2838
|
originalPresetData,
|
|
2777
2839
|
fields = {
|
|
2778
2840
|
name: {
|
|
2779
|
-
label: "
|
|
2780
|
-
placeholder: "
|
|
2841
|
+
label: "preset.name",
|
|
2842
|
+
placeholder: "preset.placeholder.enterName",
|
|
2781
2843
|
required: true
|
|
2844
|
+
},
|
|
2845
|
+
category_list: {
|
|
2846
|
+
label: "preset.categories"
|
|
2847
|
+
},
|
|
2848
|
+
description: {
|
|
2849
|
+
label: "preset.description",
|
|
2850
|
+
placeholder: "preset.placeholder.enterDescription"
|
|
2782
2851
|
}
|
|
2783
2852
|
},
|
|
2784
2853
|
texts = {
|
|
2785
|
-
loadButton: "
|
|
2786
|
-
saveButton: "
|
|
2787
|
-
editButton: "
|
|
2788
|
-
cancelButton: "
|
|
2854
|
+
loadButton: "preset.button.load",
|
|
2855
|
+
saveButton: "preset.button.save",
|
|
2856
|
+
editButton: "preset.button.edit",
|
|
2857
|
+
cancelButton: "preset.button.cancel"
|
|
2789
2858
|
},
|
|
2790
2859
|
presetChanged,
|
|
2791
2860
|
// 作用:在切换选中预设时强制触发 Checkbox 的重新初始化
|
|
2792
2861
|
enableEdit = true
|
|
2793
2862
|
} = _ref3;
|
|
2863
|
+
const intl = useIntl();
|
|
2794
2864
|
const [initialSelected, setInitialSelected] = useState([]);
|
|
2795
2865
|
const [isEditMode, setIsEditMode] = useState(false); // 是否进入编辑模式
|
|
2796
2866
|
const currentSelected = Form.useWatch('category_list', form) || [];
|
|
2797
2867
|
|
|
2798
|
-
//
|
|
2868
|
+
// 格式化文本的辅助函数
|
|
2869
|
+
const fmt = key => {
|
|
2870
|
+
if (typeof key === 'string' && key.includes('.')) {
|
|
2871
|
+
return intl.formatMessage({
|
|
2872
|
+
id: key
|
|
2873
|
+
});
|
|
2874
|
+
}
|
|
2875
|
+
return key;
|
|
2876
|
+
};
|
|
2877
|
+
|
|
2878
|
+
// 检查是否包含 category_list 字段
|
|
2799
2879
|
const hasCategoryList = fields.category_list !== null && fields.category_list !== undefined;
|
|
2800
2880
|
|
|
2801
2881
|
// 初始化 category_list 的选择状态
|
|
@@ -2888,39 +2968,15 @@ const RightDetailForm = /*#__PURE__*/memo(_ref3 => {
|
|
|
2888
2968
|
},
|
|
2889
2969
|
children: [/*#__PURE__*/jsx(Form.Item, {
|
|
2890
2970
|
name: "name",
|
|
2891
|
-
label: fields.name.label
|
|
2892
|
-
// rules={[
|
|
2893
|
-
// {
|
|
2894
|
-
// required: fields.name.required,
|
|
2895
|
-
// validator: async (_, value) => {
|
|
2896
|
-
// if (!value || value.trim() === '') {
|
|
2897
|
-
// return Promise.reject(new Error('Preset name cannot be empty or spaces only'));
|
|
2898
|
-
// }
|
|
2899
|
-
// }
|
|
2900
|
-
// }
|
|
2901
|
-
// ]}
|
|
2902
|
-
,
|
|
2971
|
+
label: fmt(fields.name.label),
|
|
2903
2972
|
required: true,
|
|
2904
2973
|
children: /*#__PURE__*/jsx(Input, {
|
|
2905
|
-
placeholder: fields.name.placeholder,
|
|
2974
|
+
placeholder: fmt(fields.name.placeholder),
|
|
2906
2975
|
disabled: shouldDisableNameAndDesc
|
|
2907
2976
|
})
|
|
2908
2977
|
}), hasCategoryList && /*#__PURE__*/jsx(Form.Item, {
|
|
2909
2978
|
name: "category_list",
|
|
2910
|
-
label: fields.category_list.label
|
|
2911
|
-
// rules={[
|
|
2912
|
-
// {
|
|
2913
|
-
// required: fields.category_list.required,
|
|
2914
|
-
// message: 'Please select at least one category',
|
|
2915
|
-
// validator: (_, value) => {
|
|
2916
|
-
// if (value && value.length > 0) {
|
|
2917
|
-
// return Promise.resolve();
|
|
2918
|
-
// }
|
|
2919
|
-
// return Promise.reject(new Error('Please select at least one category'));
|
|
2920
|
-
// }
|
|
2921
|
-
// }
|
|
2922
|
-
// ]}
|
|
2923
|
-
,
|
|
2979
|
+
label: fmt(fields.category_list.label),
|
|
2924
2980
|
required: true,
|
|
2925
2981
|
children: /*#__PURE__*/jsx(Checkbox.Group, {
|
|
2926
2982
|
className: "grid grid-cols-2 gap-2",
|
|
@@ -2934,10 +2990,10 @@ const RightDetailForm = /*#__PURE__*/memo(_ref3 => {
|
|
|
2934
2990
|
})
|
|
2935
2991
|
}), fields.description && /*#__PURE__*/jsx(Form.Item, {
|
|
2936
2992
|
name: "description",
|
|
2937
|
-
label: fields.description.label,
|
|
2993
|
+
label: fmt(fields.description.label),
|
|
2938
2994
|
children: /*#__PURE__*/jsx(Input.TextArea, {
|
|
2939
2995
|
rows: 4,
|
|
2940
|
-
placeholder: fields.description.placeholder,
|
|
2996
|
+
placeholder: fmt(fields.description.placeholder),
|
|
2941
2997
|
disabled: shouldDisableNameAndDesc,
|
|
2942
2998
|
style: {
|
|
2943
2999
|
resize: 'none'
|
|
@@ -3005,24 +3061,24 @@ const Preset = _ref => {
|
|
|
3005
3061
|
// 字段配置
|
|
3006
3062
|
fields = {
|
|
3007
3063
|
name: {
|
|
3008
|
-
label: "
|
|
3009
|
-
placeholder: "
|
|
3064
|
+
label: "preset.name",
|
|
3065
|
+
placeholder: "preset.placeholder.enterName",
|
|
3010
3066
|
required: true
|
|
3011
3067
|
}
|
|
3012
3068
|
},
|
|
3013
3069
|
texts = {
|
|
3014
|
-
title: "
|
|
3015
|
-
emptyText: "
|
|
3016
|
-
deleteConfirm: "
|
|
3017
|
-
loadConfirm: "
|
|
3018
|
-
loadText: "
|
|
3019
|
-
successText: "
|
|
3020
|
-
newButton: "
|
|
3021
|
-
removeButton: "
|
|
3022
|
-
loadButton: "
|
|
3023
|
-
saveButton: "
|
|
3024
|
-
editButton: "
|
|
3025
|
-
cancelButton: "
|
|
3070
|
+
title: "preset.title",
|
|
3071
|
+
emptyText: "preset.empty.noData",
|
|
3072
|
+
deleteConfirm: "preset.delete.confirmMessage",
|
|
3073
|
+
loadConfirm: "preset.load.confirmMessage",
|
|
3074
|
+
loadText: "preset.load.loading",
|
|
3075
|
+
successText: "preset.success",
|
|
3076
|
+
newButton: "preset.button.new",
|
|
3077
|
+
removeButton: "preset.button.delete",
|
|
3078
|
+
loadButton: "preset.button.load",
|
|
3079
|
+
saveButton: "preset.button.save",
|
|
3080
|
+
editButton: "preset.button.edit",
|
|
3081
|
+
cancelButton: "preset.button.cancel"
|
|
3026
3082
|
},
|
|
3027
3083
|
// 样式定制
|
|
3028
3084
|
width = 1000,
|
|
@@ -3031,6 +3087,7 @@ const Preset = _ref => {
|
|
|
3031
3087
|
// 功能配置
|
|
3032
3088
|
enableEdit = true
|
|
3033
3089
|
} = _ref;
|
|
3090
|
+
const intl = useIntl();
|
|
3034
3091
|
const {
|
|
3035
3092
|
message,
|
|
3036
3093
|
modal
|
|
@@ -3040,6 +3097,16 @@ const Preset = _ref => {
|
|
|
3040
3097
|
const [loading, setLoading] = useState(false);
|
|
3041
3098
|
const [presetChanged, setPresetChanged] = useState(0);
|
|
3042
3099
|
const [form] = Form.useForm();
|
|
3100
|
+
|
|
3101
|
+
// 格式化文本的辅助函数
|
|
3102
|
+
const fmt = useCallback(key => {
|
|
3103
|
+
if (typeof key === 'string' && key.includes('.')) {
|
|
3104
|
+
return intl.formatMessage({
|
|
3105
|
+
id: key
|
|
3106
|
+
});
|
|
3107
|
+
}
|
|
3108
|
+
return key;
|
|
3109
|
+
}, [intl]);
|
|
3043
3110
|
const fetchPresetList = useCallback(async () => {
|
|
3044
3111
|
try {
|
|
3045
3112
|
const data = await getPresetList();
|
|
@@ -3087,16 +3154,16 @@ const Preset = _ref => {
|
|
|
3087
3154
|
const handleRemove = useCallback(async () => {
|
|
3088
3155
|
if (!selectedPreset) return;
|
|
3089
3156
|
|
|
3090
|
-
// 检查是否为新建的未保存数据(无id)
|
|
3157
|
+
// 检查是否为新建的未保存数据(无 id)
|
|
3091
3158
|
const isUnsavedPreset = !selectedPreset.id;
|
|
3092
|
-
const presetName = selectedPreset.name || '
|
|
3159
|
+
const presetName = selectedPreset.name || fmt('preset.untitled');
|
|
3093
3160
|
try {
|
|
3094
3161
|
modal.confirm({
|
|
3095
3162
|
icon: /*#__PURE__*/jsx(ExclamationCircleFilled, {}),
|
|
3096
|
-
title: '
|
|
3097
|
-
content: "".concat(
|
|
3098
|
-
cancelText: '
|
|
3099
|
-
okText: '
|
|
3163
|
+
title: fmt('preset.delete.title'),
|
|
3164
|
+
content: "".concat(fmt('preset.delete.confirmMessage'), " \"").concat(presetName, "\"?"),
|
|
3165
|
+
cancelText: fmt('button.cancel'),
|
|
3166
|
+
okText: fmt('button.delete'),
|
|
3100
3167
|
onOk: async () => {
|
|
3101
3168
|
// 在删除前记录当前选中项的位置
|
|
3102
3169
|
const currentIndex = presetList.findIndex(item => isUnsavedPreset ? !item.id : item.id === selectedPreset.id);
|
|
@@ -3104,7 +3171,7 @@ const Preset = _ref => {
|
|
|
3104
3171
|
await removePreset({
|
|
3105
3172
|
id: selectedPreset.id
|
|
3106
3173
|
});
|
|
3107
|
-
message.success(
|
|
3174
|
+
message.success(fmt('preset.success'));
|
|
3108
3175
|
} else {
|
|
3109
3176
|
// 移除未保存的预设
|
|
3110
3177
|
setPresetList(prev => prev.filter(item => !!item.id));
|
|
@@ -3143,17 +3210,17 @@ const Preset = _ref => {
|
|
|
3143
3210
|
} catch (error) {
|
|
3144
3211
|
console.error('Failed to delete preset:', error);
|
|
3145
3212
|
}
|
|
3146
|
-
}, [selectedPreset, form, modal, message,
|
|
3213
|
+
}, [selectedPreset, form, modal, message, removePreset, getPresetList, fmt]);
|
|
3147
3214
|
const handleLoadPreset = useCallback(async loadData => {
|
|
3148
3215
|
if (!loadData) return;
|
|
3149
3216
|
let modalInstance = null;
|
|
3150
3217
|
let resolveOk = null; // 用于控制 confirm 关闭时机
|
|
3151
3218
|
|
|
3152
3219
|
modalInstance = modal.confirm({
|
|
3153
|
-
title: '
|
|
3154
|
-
content: "".concat(
|
|
3155
|
-
cancelText: '
|
|
3156
|
-
okText: '
|
|
3220
|
+
title: fmt('preset.load.title'),
|
|
3221
|
+
content: "".concat(fmt('preset.load.confirmMessage'), " \"").concat(loadData.name, "\"?"),
|
|
3222
|
+
cancelText: fmt('button.cancel'),
|
|
3223
|
+
okText: fmt('preset.button.load'),
|
|
3157
3224
|
// onOk 返回一个 pending Promise
|
|
3158
3225
|
onOk: () => {
|
|
3159
3226
|
return new Promise((resolve, reject) => {
|
|
@@ -3161,7 +3228,7 @@ const Preset = _ref => {
|
|
|
3161
3228
|
|
|
3162
3229
|
// 立即切换为 loading 状态
|
|
3163
3230
|
modalInstance.update({
|
|
3164
|
-
title:
|
|
3231
|
+
title: fmt('preset.load.loading'),
|
|
3165
3232
|
content: /*#__PURE__*/jsx(Spin, {
|
|
3166
3233
|
size: "large",
|
|
3167
3234
|
className: "block mx-auto"
|
|
@@ -3187,11 +3254,11 @@ const Preset = _ref => {
|
|
|
3187
3254
|
category_list: loadData.category_list
|
|
3188
3255
|
}));
|
|
3189
3256
|
|
|
3190
|
-
// 成功:1秒后自动关闭
|
|
3257
|
+
// 成功:1 秒后自动关闭
|
|
3191
3258
|
setTimeout(() => {
|
|
3192
3259
|
var _resolveOk;
|
|
3193
3260
|
(_resolveOk = resolveOk) === null || _resolveOk === void 0 || _resolveOk();
|
|
3194
|
-
message.success(
|
|
3261
|
+
message.success(fmt('preset.success'));
|
|
3195
3262
|
// 加载成功的外部回调
|
|
3196
3263
|
if (onLoadSuccess) {
|
|
3197
3264
|
onLoadSuccess(loadData);
|
|
@@ -3213,7 +3280,7 @@ const Preset = _ref => {
|
|
|
3213
3280
|
// 用户取消
|
|
3214
3281
|
}
|
|
3215
3282
|
});
|
|
3216
|
-
}, [loadPreset,
|
|
3283
|
+
}, [loadPreset, message, modal, onLoadSuccess, onLoadError, fmt]);
|
|
3217
3284
|
const handleSave = useCallback(async () => {
|
|
3218
3285
|
setLoading(true);
|
|
3219
3286
|
try {
|
|
@@ -3223,7 +3290,7 @@ const Preset = _ref => {
|
|
|
3223
3290
|
// 验证预设名称
|
|
3224
3291
|
if ((_fields$name = fields.name) !== null && _fields$name !== void 0 && _fields$name.required) {
|
|
3225
3292
|
if (!values.name || values.name.trim() === '') {
|
|
3226
|
-
message.error('
|
|
3293
|
+
message.error(fmt('preset.validation.nameRequired'));
|
|
3227
3294
|
return; // 直接返回 不执行
|
|
3228
3295
|
}
|
|
3229
3296
|
}
|
|
@@ -3231,12 +3298,12 @@ const Preset = _ref => {
|
|
|
3231
3298
|
// 验证分类列表
|
|
3232
3299
|
if ((_fields$category_list2 = fields.category_list) !== null && _fields$category_list2 !== void 0 && _fields$category_list2.required) {
|
|
3233
3300
|
if (!values.category_list || values.category_list.length === 0) {
|
|
3234
|
-
message.error('
|
|
3301
|
+
message.error(fmt('preset.validation.categoryRequired'));
|
|
3235
3302
|
return;
|
|
3236
3303
|
}
|
|
3237
3304
|
}
|
|
3238
3305
|
await savePreset(values);
|
|
3239
|
-
message.success(
|
|
3306
|
+
message.success(fmt('preset.success'));
|
|
3240
3307
|
const savedPresetName = values.name;
|
|
3241
3308
|
|
|
3242
3309
|
// 刷新列表
|
|
@@ -3258,10 +3325,10 @@ const Preset = _ref => {
|
|
|
3258
3325
|
} finally {
|
|
3259
3326
|
setLoading(false);
|
|
3260
3327
|
}
|
|
3261
|
-
}, [form, message,
|
|
3328
|
+
}, [form, message, fields, savePreset, getPresetList, fmt]);
|
|
3262
3329
|
const handleUpdate = useCallback(async () => {
|
|
3263
3330
|
if (!selectedPreset || !selectedPreset.id) {
|
|
3264
|
-
message.error('
|
|
3331
|
+
message.error(fmt('preset.error.noSelectionOrIdMissing'));
|
|
3265
3332
|
return;
|
|
3266
3333
|
}
|
|
3267
3334
|
setLoading(true);
|
|
@@ -3272,7 +3339,7 @@ const Preset = _ref => {
|
|
|
3272
3339
|
// 验证预设名称
|
|
3273
3340
|
if ((_fields$name2 = fields.name) !== null && _fields$name2 !== void 0 && _fields$name2.required) {
|
|
3274
3341
|
if (!values.name || values.name.trim() === '') {
|
|
3275
|
-
message.error('
|
|
3342
|
+
message.error(fmt('preset.validation.nameRequired'));
|
|
3276
3343
|
return; // 直接返回 不执行
|
|
3277
3344
|
}
|
|
3278
3345
|
}
|
|
@@ -3292,21 +3359,21 @@ const Preset = _ref => {
|
|
|
3292
3359
|
if (updatedPreset) {
|
|
3293
3360
|
setSelectedPreset(updatedPreset);
|
|
3294
3361
|
}
|
|
3295
|
-
message.success(
|
|
3362
|
+
message.success(fmt('preset.success'));
|
|
3296
3363
|
} catch (error) {
|
|
3297
3364
|
console.error('Failed to update preset:', error);
|
|
3298
3365
|
throw error;
|
|
3299
3366
|
} finally {
|
|
3300
3367
|
setLoading(false);
|
|
3301
3368
|
}
|
|
3302
|
-
}, [form, message,
|
|
3369
|
+
}, [form, message, fields, updatePreset, selectedPreset, fmt]);
|
|
3303
3370
|
|
|
3304
3371
|
// 初始化数据
|
|
3305
3372
|
useEffect(() => {
|
|
3306
3373
|
fetchPresetList();
|
|
3307
3374
|
}, [fetchPresetList]);
|
|
3308
3375
|
return /*#__PURE__*/jsx(StyledModal$3, {
|
|
3309
|
-
title: texts.title,
|
|
3376
|
+
title: fmt(texts.title),
|
|
3310
3377
|
width: width,
|
|
3311
3378
|
open: open,
|
|
3312
3379
|
wrapClassName: "preset-management ".concat(className),
|
|
@@ -3332,8 +3399,8 @@ const Preset = _ref => {
|
|
|
3332
3399
|
onAddNew: handleAddNew,
|
|
3333
3400
|
onRemove: handleRemove,
|
|
3334
3401
|
texts: {
|
|
3335
|
-
newButton: texts.newButton,
|
|
3336
|
-
removeButton: texts.removeButton
|
|
3402
|
+
newButton: fmt(texts.newButton),
|
|
3403
|
+
removeButton: fmt(texts.removeButton)
|
|
3337
3404
|
}
|
|
3338
3405
|
})
|
|
3339
3406
|
}), /*#__PURE__*/jsx(Col, {
|
|
@@ -3350,10 +3417,10 @@ const Preset = _ref => {
|
|
|
3350
3417
|
,
|
|
3351
3418
|
fields: fields,
|
|
3352
3419
|
texts: {
|
|
3353
|
-
loadButton: texts.loadButton,
|
|
3354
|
-
saveButton: texts.saveButton,
|
|
3355
|
-
editButton: texts.editButton,
|
|
3356
|
-
cancelButton: texts.cancelButton
|
|
3420
|
+
loadButton: fmt(texts.loadButton),
|
|
3421
|
+
saveButton: fmt(texts.saveButton),
|
|
3422
|
+
editButton: fmt(texts.editButton),
|
|
3423
|
+
cancelButton: fmt(texts.cancelButton)
|
|
3357
3424
|
},
|
|
3358
3425
|
presetChanged: presetChanged,
|
|
3359
3426
|
enableEdit: enableEdit
|
|
@@ -3364,7 +3431,7 @@ const Preset = _ref => {
|
|
|
3364
3431
|
className: "h-full text-gray-400",
|
|
3365
3432
|
children: /*#__PURE__*/jsx(Empty, {
|
|
3366
3433
|
image: Empty.PRESENTED_IMAGE_SIMPLE,
|
|
3367
|
-
description: texts.emptyText
|
|
3434
|
+
description: fmt(texts.emptyText)
|
|
3368
3435
|
})
|
|
3369
3436
|
})
|
|
3370
3437
|
})]
|
|
@@ -4619,43 +4686,64 @@ const SystemOperations = _ref => {
|
|
|
4619
4686
|
onRestartSuccess,
|
|
4620
4687
|
beforeAction,
|
|
4621
4688
|
// 在执行关机/重启前调用
|
|
4622
|
-
powerOffLabel = "
|
|
4623
|
-
restartLabel = "
|
|
4689
|
+
powerOffLabel = "system.poweroff",
|
|
4690
|
+
restartLabel = "system.restart",
|
|
4624
4691
|
iconClassName = "seeder-iconfont seeder-icon-guanji1 text-xl text-neutral-400",
|
|
4625
|
-
confirmMessage = "
|
|
4626
|
-
confirmTitle = "
|
|
4627
|
-
cancelText = "
|
|
4628
|
-
okText = "
|
|
4692
|
+
confirmMessage = "system.confirm.message",
|
|
4693
|
+
confirmTitle = "system.confirm.title",
|
|
4694
|
+
cancelText = "system.button.cancel",
|
|
4695
|
+
okText = "system.button.confirm"
|
|
4629
4696
|
} = _ref;
|
|
4697
|
+
const intl = useIntl();
|
|
4630
4698
|
const {
|
|
4631
4699
|
modal
|
|
4632
4700
|
} = App.useApp();
|
|
4633
4701
|
const menuItems = [{
|
|
4634
4702
|
key: "poweroff",
|
|
4635
|
-
label: powerOffLabel
|
|
4636
|
-
|
|
4637
|
-
|
|
4638
|
-
|
|
4639
|
-
// label: rebootLabel, // 硬重启 物理重启
|
|
4640
|
-
// },
|
|
4641
|
-
{
|
|
4703
|
+
label: typeof powerOffLabel === 'string' && powerOffLabel.includes('.') ? intl.formatMessage({
|
|
4704
|
+
id: powerOffLabel
|
|
4705
|
+
}) : powerOffLabel
|
|
4706
|
+
}, {
|
|
4642
4707
|
key: "restart",
|
|
4643
|
-
label: restartLabel
|
|
4708
|
+
label: typeof restartLabel === 'string' && restartLabel.includes('.') ? intl.formatMessage({
|
|
4709
|
+
id: restartLabel
|
|
4710
|
+
}) : restartLabel
|
|
4644
4711
|
}];
|
|
4645
4712
|
const doAction = action => {
|
|
4646
4713
|
try {
|
|
4647
|
-
// 根据action决定显示的确认信息
|
|
4714
|
+
// 根据 action 决定显示的确认信息
|
|
4648
4715
|
const actionLabels = {
|
|
4649
|
-
poweroff:
|
|
4650
|
-
|
|
4716
|
+
poweroff: intl.formatMessage({
|
|
4717
|
+
id: 'system.action.powerOff'
|
|
4718
|
+
}),
|
|
4719
|
+
restart: intl.formatMessage({
|
|
4720
|
+
id: 'system.action.restart'
|
|
4721
|
+
})
|
|
4651
4722
|
};
|
|
4652
4723
|
const actionText = actionLabels[action] || action;
|
|
4724
|
+
|
|
4725
|
+
// 处理标题和消息的国际化
|
|
4726
|
+
const titleText = typeof confirmTitle === 'string' && confirmTitle.includes('.') ? intl.formatMessage({
|
|
4727
|
+
id: confirmTitle
|
|
4728
|
+
}) : confirmTitle;
|
|
4729
|
+
|
|
4730
|
+
// 如果是国际化 key,使用 intl.formatMessage 处理参数
|
|
4731
|
+
// 如果是普通文本,使用 replace 替换占位符
|
|
4732
|
+
const messageText = typeof confirmMessage === 'string' && confirmMessage.includes('.') ? intl.formatMessage({
|
|
4733
|
+
id: confirmMessage
|
|
4734
|
+
}, {
|
|
4735
|
+
action: actionText
|
|
4736
|
+
}) : typeof confirmMessage === 'string' ? confirmMessage.replace('{action}', actionText) : confirmMessage;
|
|
4653
4737
|
modal.confirm({
|
|
4654
4738
|
icon: /*#__PURE__*/jsx(ExclamationCircleFilled, {}),
|
|
4655
|
-
title:
|
|
4656
|
-
content:
|
|
4657
|
-
cancelText
|
|
4658
|
-
|
|
4739
|
+
title: titleText,
|
|
4740
|
+
content: messageText,
|
|
4741
|
+
cancelText: typeof cancelText === 'string' && cancelText.includes('.') ? intl.formatMessage({
|
|
4742
|
+
id: cancelText
|
|
4743
|
+
}) : cancelText,
|
|
4744
|
+
okText: typeof okText === 'string' && okText.includes('.') ? intl.formatMessage({
|
|
4745
|
+
id: okText
|
|
4746
|
+
}) : okText,
|
|
4659
4747
|
onOk: async () => {
|
|
4660
4748
|
// 先执行 beforeAction(用于 enterMaintenanceMode)
|
|
4661
4749
|
if (typeof beforeAction === 'function') {
|
|
@@ -4841,9 +4929,10 @@ const CommonHeader = _ref => {
|
|
|
4841
4929
|
var CommonHeader$1 = CommonHeader;
|
|
4842
4930
|
|
|
4843
4931
|
const LSMLabelField = props => {
|
|
4932
|
+
const intl = useIntl();
|
|
4844
4933
|
const [lsmList, setLsmList] = useState([]);
|
|
4845
4934
|
const {
|
|
4846
|
-
label = "
|
|
4935
|
+
label = "lsm.label",
|
|
4847
4936
|
onLsmSelect,
|
|
4848
4937
|
fetchLsmData,
|
|
4849
4938
|
formItemProps = {},
|
|
@@ -4867,7 +4956,9 @@ const LSMLabelField = props => {
|
|
|
4867
4956
|
loadLsmData();
|
|
4868
4957
|
}, [fetchLsmData]);
|
|
4869
4958
|
return /*#__PURE__*/jsx(Form.Item, _objectSpread2$1(_objectSpread2$1({
|
|
4870
|
-
label: label
|
|
4959
|
+
label: typeof label === 'string' && label.includes('.') ? intl.formatMessage({
|
|
4960
|
+
id: label
|
|
4961
|
+
}) : label
|
|
4871
4962
|
}, formItemProps), {}, {
|
|
4872
4963
|
children: /*#__PURE__*/jsx(Select, _objectSpread2$1(_objectSpread2$1(_objectSpread2$1({}, field), selectProps), {}, {
|
|
4873
4964
|
options: lsmList,
|
|
@@ -4879,7 +4970,9 @@ const LSMLabelField = props => {
|
|
|
4879
4970
|
field.onChange(value);
|
|
4880
4971
|
onLsmSelect === null || onLsmSelect === void 0 || onLsmSelect(value === undefined ? undefined : option);
|
|
4881
4972
|
},
|
|
4882
|
-
placeholder: selectProps.placeholder ||
|
|
4973
|
+
placeholder: selectProps.placeholder || intl.formatMessage({
|
|
4974
|
+
id: 'lsm.placeholder.select'
|
|
4975
|
+
})
|
|
4883
4976
|
}))
|
|
4884
4977
|
}));
|
|
4885
4978
|
};
|
|
@@ -13354,6 +13447,7 @@ const NmosModal = _ref => {
|
|
|
13354
13447
|
modalProps = {},
|
|
13355
13448
|
formProps = {}
|
|
13356
13449
|
} = _ref;
|
|
13450
|
+
const intl = useIntl();
|
|
13357
13451
|
const [nmosSettings, setNmosSettings] = useState(null);
|
|
13358
13452
|
const [loading, setLoading] = useState(false);
|
|
13359
13453
|
const [form] = Form.useForm();
|
|
@@ -13394,7 +13488,9 @@ const NmosModal = _ref => {
|
|
|
13394
13488
|
try {
|
|
13395
13489
|
const response = await updateNmosSettings(_objectSpread2$1(_objectSpread2$1({}, nmosSettings), values));
|
|
13396
13490
|
if (response) {
|
|
13397
|
-
message.success(
|
|
13491
|
+
message.success(intl.formatMessage({
|
|
13492
|
+
id: 'nmos.saveSuccess'
|
|
13493
|
+
}));
|
|
13398
13494
|
setTimeout(() => {
|
|
13399
13495
|
onClose();
|
|
13400
13496
|
}, 1500);
|
|
@@ -13406,9 +13502,17 @@ const NmosModal = _ref => {
|
|
|
13406
13502
|
}
|
|
13407
13503
|
};
|
|
13408
13504
|
return /*#__PURE__*/jsx(StyledModal$1, _objectSpread2$1(_objectSpread2$1({
|
|
13409
|
-
title:
|
|
13505
|
+
title: intl.formatMessage({
|
|
13506
|
+
id: 'nmos.title'
|
|
13507
|
+
}),
|
|
13410
13508
|
width: 650,
|
|
13411
13509
|
open: open,
|
|
13510
|
+
okText: intl.formatMessage({
|
|
13511
|
+
id: 'button.apply'
|
|
13512
|
+
}),
|
|
13513
|
+
cancelText: intl.formatMessage({
|
|
13514
|
+
id: 'button.close'
|
|
13515
|
+
}),
|
|
13412
13516
|
onOk: handleSubmit,
|
|
13413
13517
|
onCancel: onClose,
|
|
13414
13518
|
confirmLoading: loading,
|
|
@@ -13427,7 +13531,9 @@ const NmosModal = _ref => {
|
|
|
13427
13531
|
disabled: loading
|
|
13428
13532
|
}, formProps), {}, {
|
|
13429
13533
|
children: [/*#__PURE__*/jsx(Form.Item, {
|
|
13430
|
-
label:
|
|
13534
|
+
label: intl.formatMessage({
|
|
13535
|
+
id: 'nmos.hostAddress'
|
|
13536
|
+
}),
|
|
13431
13537
|
name: "host_addresses",
|
|
13432
13538
|
children: /*#__PURE__*/jsx(Select, {
|
|
13433
13539
|
mode: "multiple",
|
|
@@ -13436,19 +13542,27 @@ const NmosModal = _ref => {
|
|
|
13436
13542
|
label: "display_name",
|
|
13437
13543
|
value: "ip_address"
|
|
13438
13544
|
},
|
|
13439
|
-
placeholder:
|
|
13545
|
+
placeholder: intl.formatMessage({
|
|
13546
|
+
id: 'nmos.placeholder.selectHostAddress'
|
|
13547
|
+
}),
|
|
13440
13548
|
allowClear: true
|
|
13441
13549
|
})
|
|
13442
13550
|
}), /*#__PURE__*/jsx(Form.Item, {
|
|
13443
|
-
label:
|
|
13551
|
+
label: intl.formatMessage({
|
|
13552
|
+
id: 'nmos.domain'
|
|
13553
|
+
}),
|
|
13444
13554
|
name: "domain",
|
|
13445
13555
|
children: /*#__PURE__*/jsx(Input, {})
|
|
13446
13556
|
}), /*#__PURE__*/jsx(Form.Item, {
|
|
13447
|
-
label:
|
|
13557
|
+
label: intl.formatMessage({
|
|
13558
|
+
id: 'nmos.registryAddress'
|
|
13559
|
+
}),
|
|
13448
13560
|
name: "registry_address",
|
|
13449
13561
|
children: /*#__PURE__*/jsx(Input, {})
|
|
13450
13562
|
}), /*#__PURE__*/jsx(Form.Item, {
|
|
13451
|
-
label:
|
|
13563
|
+
label: intl.formatMessage({
|
|
13564
|
+
id: 'nmos.registrationPort'
|
|
13565
|
+
}),
|
|
13452
13566
|
name: "registration_port",
|
|
13453
13567
|
children: /*#__PURE__*/jsx(InputNumber, _objectSpread2$1(_objectSpread2$1({}, numberProps), {}, {
|
|
13454
13568
|
min: 0,
|
|
@@ -13458,7 +13572,9 @@ const NmosModal = _ref => {
|
|
|
13458
13572
|
}
|
|
13459
13573
|
}))
|
|
13460
13574
|
}), /*#__PURE__*/jsx(Form.Item, {
|
|
13461
|
-
label:
|
|
13575
|
+
label: intl.formatMessage({
|
|
13576
|
+
id: 'nmos.registryVersion'
|
|
13577
|
+
}),
|
|
13462
13578
|
name: "registry_version",
|
|
13463
13579
|
children: /*#__PURE__*/jsx(Select, {
|
|
13464
13580
|
options: [{
|
|
@@ -13474,10 +13590,14 @@ const NmosModal = _ref => {
|
|
|
13474
13590
|
label: "v1.3",
|
|
13475
13591
|
value: "v1.3"
|
|
13476
13592
|
}],
|
|
13477
|
-
placeholder:
|
|
13593
|
+
placeholder: intl.formatMessage({
|
|
13594
|
+
id: 'nmos.placeholder.selectVersion'
|
|
13595
|
+
})
|
|
13478
13596
|
})
|
|
13479
13597
|
}), /*#__PURE__*/jsx(Form.Item, {
|
|
13480
|
-
label:
|
|
13598
|
+
label: intl.formatMessage({
|
|
13599
|
+
id: 'nmos.loggingLevel'
|
|
13600
|
+
}),
|
|
13481
13601
|
name: "logging_level",
|
|
13482
13602
|
children: /*#__PURE__*/jsx(InputNumber, _objectSpread2$1(_objectSpread2$1({}, numberProps), {}, {
|
|
13483
13603
|
min: -40,
|
|
@@ -13585,11 +13705,12 @@ const MaintenancePage = _ref => {
|
|
|
13585
13705
|
redirectPath = '/',
|
|
13586
13706
|
onRedirect,
|
|
13587
13707
|
maxRetries = 90,
|
|
13588
|
-
// 最多重试90次(约180秒)
|
|
13708
|
+
// 最多重试 90 次(约 180 秒)
|
|
13589
13709
|
checkInterval = 2000,
|
|
13590
|
-
// 每2秒重试
|
|
13710
|
+
// 每 2 秒重试
|
|
13591
13711
|
countdownSeconds = 30 // 倒计时初始值,单位秒
|
|
13592
13712
|
} = _ref;
|
|
13713
|
+
const intl = useIntl();
|
|
13593
13714
|
const [countdown, setCountdown] = useState(countdownSeconds);
|
|
13594
13715
|
const {
|
|
13595
13716
|
error,
|
|
@@ -13628,7 +13749,11 @@ const MaintenancePage = _ref => {
|
|
|
13628
13749
|
cleanup();
|
|
13629
13750
|
};
|
|
13630
13751
|
}, [isRestart, healthCheckUrl, startPolling, cleanup]);
|
|
13631
|
-
const title = isRestart ?
|
|
13752
|
+
const title = isRestart ? intl.formatMessage({
|
|
13753
|
+
id: 'maintenance.restarting'
|
|
13754
|
+
}) : intl.formatMessage({
|
|
13755
|
+
id: 'maintenance.poweredOff'
|
|
13756
|
+
});
|
|
13632
13757
|
const subTitle = isRestart ? /*#__PURE__*/jsxs(Space, {
|
|
13633
13758
|
direction: "vertical",
|
|
13634
13759
|
size: 8,
|
|
@@ -13636,13 +13761,21 @@ const MaintenancePage = _ref => {
|
|
|
13636
13761
|
alignItems: 'center'
|
|
13637
13762
|
},
|
|
13638
13763
|
children: [/*#__PURE__*/jsx(Typography.Text, {
|
|
13639
|
-
children:
|
|
13640
|
-
|
|
13764
|
+
children: intl.formatMessage({
|
|
13765
|
+
id: 'maintenance.waiting'
|
|
13766
|
+
})
|
|
13767
|
+
}), countdown > 0 && /*#__PURE__*/jsx(Typography.Text, {
|
|
13641
13768
|
type: "secondary",
|
|
13642
|
-
children:
|
|
13769
|
+
children: intl.formatMessage({
|
|
13770
|
+
id: 'maintenance.redirecting.countdown'
|
|
13771
|
+
}, {
|
|
13772
|
+
countdown
|
|
13773
|
+
})
|
|
13643
13774
|
}), countdown <= 0 && !error && /*#__PURE__*/jsx(Typography.Text, {
|
|
13644
13775
|
type: "secondary",
|
|
13645
|
-
children:
|
|
13776
|
+
children: intl.formatMessage({
|
|
13777
|
+
id: 'maintenance.waiting.long'
|
|
13778
|
+
})
|
|
13646
13779
|
}), error && /*#__PURE__*/jsxs(Fragment, {
|
|
13647
13780
|
children: [/*#__PURE__*/jsx(Alert, {
|
|
13648
13781
|
type: "error",
|
|
@@ -13654,11 +13787,15 @@ const MaintenancePage = _ref => {
|
|
|
13654
13787
|
}), /*#__PURE__*/jsx(Button, {
|
|
13655
13788
|
type: "link",
|
|
13656
13789
|
onClick: manualRetry,
|
|
13657
|
-
children:
|
|
13790
|
+
children: intl.formatMessage({
|
|
13791
|
+
id: 'maintenance.retry'
|
|
13792
|
+
})
|
|
13658
13793
|
})]
|
|
13659
13794
|
})]
|
|
13660
13795
|
}) : /*#__PURE__*/jsx(Typography.Text, {
|
|
13661
|
-
children:
|
|
13796
|
+
children: intl.formatMessage({
|
|
13797
|
+
id: 'maintenance.offline.description'
|
|
13798
|
+
})
|
|
13662
13799
|
});
|
|
13663
13800
|
return /*#__PURE__*/jsx("div", {
|
|
13664
13801
|
className: "maintenance-page",
|
|
@@ -14022,10 +14159,17 @@ const BoundedInput = _ref => {
|
|
|
14022
14159
|
min = 0,
|
|
14023
14160
|
max = 100,
|
|
14024
14161
|
autoCorrect = false,
|
|
14025
|
-
placeholder = '
|
|
14162
|
+
placeholder = 'input.placeholder.enterInteger',
|
|
14026
14163
|
disabled = false
|
|
14027
14164
|
} = _ref,
|
|
14028
14165
|
props = _objectWithoutProperties$1(_ref, _excluded);
|
|
14166
|
+
const intl = useIntl();
|
|
14167
|
+
|
|
14168
|
+
// 处理国际化文本
|
|
14169
|
+
const placeholderText = typeof placeholder === 'string' && placeholder.includes('.') ? intl.formatMessage({
|
|
14170
|
+
id: placeholder
|
|
14171
|
+
}) : placeholder;
|
|
14172
|
+
|
|
14029
14173
|
// 1. 处理输入变更:只管记录,不修正,不打断
|
|
14030
14174
|
const handleChange = val => {
|
|
14031
14175
|
if (val === null || val === undefined) {
|
|
@@ -14061,7 +14205,7 @@ const BoundedInput = _ref => {
|
|
|
14061
14205
|
value: value,
|
|
14062
14206
|
onChange: handleChange,
|
|
14063
14207
|
onBlur: handleBlur,
|
|
14064
|
-
placeholder:
|
|
14208
|
+
placeholder: placeholderText
|
|
14065
14209
|
// 只有开启自动修正时,才把 min/max 传给组件
|
|
14066
14210
|
,
|
|
14067
14211
|
min: autoCorrect ? min : undefined,
|
|
@@ -14087,7 +14231,7 @@ const BoundedInput = _ref => {
|
|
|
14087
14231
|
const PortInput = props => /*#__PURE__*/jsx(BoundedInput, _objectSpread2$1({
|
|
14088
14232
|
min: 0,
|
|
14089
14233
|
max: 65535,
|
|
14090
|
-
placeholder: "
|
|
14234
|
+
placeholder: "input.placeholder.enterPort"
|
|
14091
14235
|
}, props));
|
|
14092
14236
|
|
|
14093
14237
|
/**
|
|
@@ -14096,7 +14240,7 @@ const PortInput = props => /*#__PURE__*/jsx(BoundedInput, _objectSpread2$1({
|
|
|
14096
14240
|
const PayloadInput = props => /*#__PURE__*/jsx(BoundedInput, _objectSpread2$1({
|
|
14097
14241
|
min: 96,
|
|
14098
14242
|
max: 127,
|
|
14099
|
-
placeholder: "
|
|
14243
|
+
placeholder: "input.placeholder.enterPayload"
|
|
14100
14244
|
}, props));
|
|
14101
14245
|
|
|
14102
14246
|
export { AuthorizationModal$1 as AuthorizationModal, CommonHeader$1 as CommonHeader, DraggableNumberInput, LSMLabelField$1 as LSMLabelField, MaintenancePage, NetworkSettingsModal$1 as NetworkSettingsModal, NmosModal$1 as NmosModal, PayloadInput, PortInput, PresetModal, PtpModal$1 as PtpModal, StyledModal$3 as StyledModal, SystemOperations$1 as SystemOperations, UpgradeManager$1 as UpgradeManager, addMessages, debugI18n, initI18n, enUS as localesEnUS, zhCN as localesZhCN, setLocale, useAuth, useHardwareUsage$1 as useHardwareUsage, useIntl, usePageReload$1 as usePageReload, useSystemOperations$1 as useSystemOperations, useUpgrade$1 as useUpgrade, useWebSocketWithFeatures$1 as useWebSocketWithFeatures };
|