seeder-st2110-components 1.0.1 → 1.0.3

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.js CHANGED
@@ -56,14 +56,15 @@ const UsageItem = /*#__PURE__*/react.memo(_ref => {
56
56
  iconClass,
57
57
  text,
58
58
  children,
59
- ram
59
+ showRam,
60
+ ramValue
60
61
  } = _ref;
61
62
  const tooltipContent = react.useMemo(() => /*#__PURE__*/jsxRuntime.jsx(antd.Tooltip, {
62
63
  title: /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
63
64
  children: [/*#__PURE__*/jsxRuntime.jsx("div", {
64
65
  children: text
65
- }), ram && /*#__PURE__*/jsxRuntime.jsxs("div", {
66
- children: ["Total Memory: ", ram, "GB"]
66
+ }), showRam && /*#__PURE__*/jsxRuntime.jsxs("div", {
67
+ children: ["Total Memory: ", ramValue, "GB"]
67
68
  })]
68
69
  }),
69
70
  destroyOnHidden: false,
@@ -88,7 +89,8 @@ const UsageItem = /*#__PURE__*/react.memo(_ref => {
88
89
  const getTemperature = (supermicro, sensors) => {
89
90
  return supermicro?.cpu_temperature ?? sensors?.temperatures?.coretemp?.[0]?.current;
90
91
  };
91
- const useHardwareUsage = ps_status => {
92
+ const useHardwareUsage = function (ps_status) {
93
+ let showRam = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
92
94
  return react.useMemo(() => {
93
95
  if (!ps_status || typeof ps_status !== 'object') return null;
94
96
  const {
@@ -111,7 +113,8 @@ const useHardwareUsage = ps_status => {
111
113
  }), mem && /*#__PURE__*/jsxRuntime.jsxs(UsageItem, {
112
114
  text: "Memory Usage",
113
115
  iconClass: "icon-shiyongshuai",
114
- ram: false,
116
+ showRam: showRam,
117
+ ramValue: (mem.total / (1024 * 1024 * 1024)).toFixed(1),
115
118
  children: [mem.percent, "%"]
116
119
  }), supermicro?.nic_temperature && /*#__PURE__*/jsxRuntime.jsxs(UsageItem, {
117
120
  text: "NIC Temperature",
@@ -1973,7 +1976,508 @@ SystemOperations.propTypes = {
1973
1976
  okText: PropTypes.string
1974
1977
  };
1975
1978
 
1979
+ const defaultFieldConfigs = {
1980
+ clock_class: {
1981
+ label: 'Clock Class',
1982
+ formType: 'select',
1983
+ options: [{
1984
+ value: 6,
1985
+ label: 'Atomic Clock (6)'
1986
+ }, {
1987
+ value: 7,
1988
+ label: 'GPS (7)'
1989
+ }, {
1990
+ value: 248,
1991
+ label: 'Slave-Only (248)'
1992
+ }],
1993
+ readOnly: true
1994
+ },
1995
+ clock_accuracy: {
1996
+ label: 'Clock Accuracy',
1997
+ formType: 'number',
1998
+ readOnly: true
1999
+ },
2000
+ offset_scaled_log_variance: {
2001
+ label: 'Offset Scaled Log Variance',
2002
+ formType: 'number',
2003
+ readOnly: true
2004
+ },
2005
+ grandmaster_priority1: {
2006
+ label: 'Priority 1',
2007
+ formType: 'number',
2008
+ readOnly: true
2009
+ },
2010
+ grandmaster_priority2: {
2011
+ label: 'Priority 2',
2012
+ formType: 'number',
2013
+ readOnly: true
2014
+ },
2015
+ grandmaster_identity: {
2016
+ label: 'Grandmaster Identity',
2017
+ formType: 'text',
2018
+ readOnly: true
2019
+ },
2020
+ master_port_id: {
2021
+ label: 'Port Identity',
2022
+ formType: 'text',
2023
+ readOnly: true
2024
+ },
2025
+ t1_domain_number: {
2026
+ label: 'Domain',
2027
+ formType: 'number',
2028
+ min: 0,
2029
+ max: 127,
2030
+ readOnly: false
2031
+ },
2032
+ master_utc_offset: {
2033
+ label: 'UTC Offset',
2034
+ formType: 'number',
2035
+ readOnly: true
2036
+ },
2037
+ is_connected: {
2038
+ label: 'Connected Status',
2039
+ formType: 'badge',
2040
+ statusMap: {
2041
+ 0: {
2042
+ text: 'Disconnected',
2043
+ color: 'red'
2044
+ },
2045
+ 1: {
2046
+ text: 'Connected',
2047
+ color: 'green'
2048
+ }
2049
+ }
2050
+ },
2051
+ is_locked: {
2052
+ label: 'Locked Status',
2053
+ formType: 'badge',
2054
+ statusMap: {
2055
+ 0: {
2056
+ text: 'Unlocked',
2057
+ color: 'red'
2058
+ },
2059
+ 1: {
2060
+ text: 'Locked',
2061
+ color: 'green'
2062
+ }
2063
+ }
2064
+ }
2065
+ };
2066
+
2067
+ // 默认字段顺序
2068
+ const defaultFieldOrder = ['t1_domain_number', 'grandmaster_priority1', 'grandmaster_priority2', 'grandmaster_identity', 'master_port_id', 'clock_class', 'clock_accuracy', 'offset_scaled_log_variance', 'master_utc_offset', 'is_connected', 'is_locked'];
2069
+
2070
+ /**
2071
+ * 转换PTP状态为表单字段数组
2072
+ * @param {Object} ptpStatus PTP状态对象
2073
+ * @param {Object} fieldConfigs 字段配置
2074
+ * @param {Array} fieldOrder 字段顺序
2075
+ * @returns {Array} 表单字段数组
2076
+ */
2077
+ function convertPtpStatusToArray(ptpStatus, fieldConfigs, fieldOrder) {
2078
+ return fieldOrder.filter(key => key in ptpStatus).map(key => {
2079
+ const config = fieldConfigs[key] || {
2080
+ label: key,
2081
+ formType: 'text'
2082
+ };
2083
+ const value = ptpStatus[key];
2084
+ return {
2085
+ key,
2086
+ value,
2087
+ ...config,
2088
+ rawData: ptpStatus
2089
+ };
2090
+ });
2091
+ }
2092
+ const PtpModal = _ref => {
2093
+ let {
2094
+ open,
2095
+ onClose,
2096
+ getPtpInfo,
2097
+ updatePtpInfo,
2098
+ fieldConfigs = defaultFieldConfigs,
2099
+ fieldOrder = defaultFieldOrder,
2100
+ modalProps = {},
2101
+ formProps = {}
2102
+ } = _ref;
2103
+ const [ptpStatus, setPtpStatus] = react.useState(null);
2104
+ const [form] = antd.Form.useForm();
2105
+ const {
2106
+ message
2107
+ } = antd.App.useApp();
2108
+ react.useEffect(() => {
2109
+ if (open) {
2110
+ getPtpInfo().then(data => {
2111
+ if (data?.[0]) {
2112
+ setPtpStatus(data[0]);
2113
+ form.setFieldsValue(data[0]);
2114
+ }
2115
+ });
2116
+ }
2117
+ }, [open, form, getPtpInfo]);
2118
+ const ptpStatusArray = react.useMemo(() => {
2119
+ if (!ptpStatus) return [];
2120
+ return convertPtpStatusToArray(ptpStatus, fieldConfigs, fieldOrder);
2121
+ }, [ptpStatus]);
2122
+ const handleValueChange = changedValues => {
2123
+ if ('t1_domain_number' in changedValues) {
2124
+ setPtpStatus(prev => ({
2125
+ ...prev,
2126
+ t1_domain_number: changedValues.t1_domain_number
2127
+ }));
2128
+ }
2129
+ };
2130
+ const handleSubmit = async () => {
2131
+ try {
2132
+ const values = await form.validateFields();
2133
+ const response = await updatePtpInfo(values);
2134
+ if (response) {
2135
+ message.success('Success');
2136
+ setTimeout(() => {
2137
+ onClose();
2138
+ }, 1500);
2139
+ }
2140
+ } catch (error) {
2141
+ console.error('Update failed:', error);
2142
+ }
2143
+ };
2144
+ const renderFormItem = item => {
2145
+ switch (item.formType) {
2146
+ case 'select':
2147
+ return /*#__PURE__*/jsxRuntime.jsx(antd.Select, {
2148
+ options: item.options,
2149
+ disabled: item.readOnly
2150
+ });
2151
+ case 'switch':
2152
+ return /*#__PURE__*/jsxRuntime.jsx(antd.Switch, {});
2153
+ case 'badge':
2154
+ const normalizedValue = typeof item.value === 'boolean' ? item.value ? 1 : 0 : item.value;
2155
+ const status = item.statusMap?.[normalizedValue] || {
2156
+ text: 'Unknown',
2157
+ color: 'gray'
2158
+ };
2159
+ return /*#__PURE__*/jsxRuntime.jsx(antd.ConfigProvider, {
2160
+ theme: {
2161
+ components: {
2162
+ Badge: {
2163
+ statusSize: 10
2164
+ }
2165
+ }
2166
+ },
2167
+ children: /*#__PURE__*/jsxRuntime.jsx(antd.Badge, {
2168
+ color: status.color,
2169
+ text: status.text
2170
+ })
2171
+ });
2172
+ case 'number':
2173
+ return /*#__PURE__*/jsxRuntime.jsx(antd.InputNumber, {
2174
+ disabled: item.readOnly,
2175
+ controls: false,
2176
+ keyboard: false,
2177
+ min: item.min ?? Number.MIN_SAFE_INTEGER,
2178
+ max: item.max ?? Number.MAX_SAFE_INTEGER
2179
+ });
2180
+ default:
2181
+ return /*#__PURE__*/jsxRuntime.jsx(antd.Input, {
2182
+ disabled: item.readOnly
2183
+ });
2184
+ }
2185
+ };
2186
+ if (!open || !ptpStatus) return null;
2187
+
2188
+ // 合并默认模态框属性和传入的属性
2189
+ const mergedModalProps = {
2190
+ title: "PTP",
2191
+ width: 650,
2192
+ open,
2193
+ okText: "Apply",
2194
+ cancelText: "Close",
2195
+ onCancel: onClose,
2196
+ onOk: handleSubmit,
2197
+ ...modalProps
2198
+ };
2199
+
2200
+ // 合并默认表单属性和传入的属性
2201
+ const mergedFormProps = {
2202
+ form: form,
2203
+ name: "ptpForm",
2204
+ labelCol: {
2205
+ span: 8
2206
+ },
2207
+ wrapperCol: {
2208
+ span: 16
2209
+ },
2210
+ autoComplete: "off",
2211
+ onValuesChange: handleValueChange,
2212
+ ...formProps
2213
+ };
2214
+ return /*#__PURE__*/jsxRuntime.jsx(antd.Modal, {
2215
+ ...mergedModalProps,
2216
+ children: /*#__PURE__*/jsxRuntime.jsx(antd.Form, {
2217
+ ...mergedFormProps,
2218
+ children: ptpStatusArray.map(item => /*#__PURE__*/jsxRuntime.jsx(antd.Form.Item, {
2219
+ label: item.label,
2220
+ name: item.key,
2221
+ initialValue: item.value,
2222
+ children: renderFormItem(item)
2223
+ }, item.key))
2224
+ })
2225
+ });
2226
+ };
2227
+ var PtpModal$1 = /*#__PURE__*/react.memo(PtpModal);
2228
+
2229
+ const NetworkFieldGroup = _ref => {
2230
+ let {
2231
+ prefix,
2232
+ interfaces,
2233
+ fieldConfig = {}
2234
+ } = _ref;
2235
+ const defaultFieldConfig = {
2236
+ name: {
2237
+ label: "Name",
2238
+ enabled: true
2239
+ },
2240
+ ip: {
2241
+ label: "IP Address",
2242
+ enabled: true
2243
+ },
2244
+ netmask: {
2245
+ label: "Netmask",
2246
+ enabled: prefix === "LAN"
2247
+ }
2248
+ };
2249
+ const mergedFieldConfig = {
2250
+ ...defaultFieldConfig,
2251
+ ...fieldConfig
2252
+ };
2253
+ return /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
2254
+ children: [/*#__PURE__*/jsxRuntime.jsx(antd.Typography.Title, {
2255
+ level: 5,
2256
+ style: {
2257
+ display: 'flex',
2258
+ justifyContent: 'space-between',
2259
+ alignItems: 'center',
2260
+ marginBottom: 16
2261
+ },
2262
+ children: prefix
2263
+ }), interfaces.map((iface, index) => /*#__PURE__*/jsxRuntime.jsxs("div", {
2264
+ children: [mergedFieldConfig.name.enabled && /*#__PURE__*/jsxRuntime.jsx(antd.Form.Item, {
2265
+ label: mergedFieldConfig.name.label,
2266
+ name: [prefix, index, "display_name"],
2267
+ children: /*#__PURE__*/jsxRuntime.jsx(antd.Input, {
2268
+ disabled: true
2269
+ })
2270
+ }), mergedFieldConfig.ip.enabled && /*#__PURE__*/jsxRuntime.jsx(antd.Form.Item, {
2271
+ label: mergedFieldConfig.ip.label,
2272
+ name: [prefix, index, "ip_address"],
2273
+ children: /*#__PURE__*/jsxRuntime.jsx(antd.Input, {})
2274
+ }), mergedFieldConfig.netmask.enabled && /*#__PURE__*/jsxRuntime.jsx(antd.Form.Item, {
2275
+ label: mergedFieldConfig.netmask.label,
2276
+ name: [prefix, index, "netmask"],
2277
+ children: /*#__PURE__*/jsxRuntime.jsx(antd.Input, {})
2278
+ }), index < interfaces.length - 1 && /*#__PURE__*/jsxRuntime.jsx(antd.Divider, {
2279
+ style: {
2280
+ marginBlock: 16
2281
+ }
2282
+ })]
2283
+ }, iface.id || index))]
2284
+ });
2285
+ };
2286
+ const NetworkSettingsModal = _ref2 => {
2287
+ let {
2288
+ open,
2289
+ onClose,
2290
+ getLanConfig,
2291
+ getSysConfig,
2292
+ updateLanConfig,
2293
+ updateSysConfig,
2294
+ restart,
2295
+ modalProps = {},
2296
+ formProps = {},
2297
+ fieldConfig = {},
2298
+ sections = ['LAN', 'QSFP']
2299
+ } = _ref2;
2300
+ const {
2301
+ message,
2302
+ modal
2303
+ } = antd.App.useApp();
2304
+ const [form] = antd.Form.useForm();
2305
+ const [st2110Interfaces, setSt2110Interfaces] = react.useState([]);
2306
+ const [lanConfigs, setLanConfigs] = react.useState([]);
2307
+ const [submitLoading, setSubmitLoading] = react.useState(false);
2308
+ react.useEffect(() => {
2309
+ const fetchInitialData = async () => {
2310
+ try {
2311
+ const promises = [];
2312
+ if (sections.includes('LAN')) {
2313
+ promises.push(getLanConfig());
2314
+ }
2315
+ if (sections.includes('QSFP')) {
2316
+ promises.push(getSysConfig());
2317
+ }
2318
+ const results = await Promise.allSettled(promises);
2319
+ if (sections.includes('LAN')) {
2320
+ const lanResult = results[sections.indexOf('LAN')];
2321
+ if (lanResult.status === 'fulfilled') {
2322
+ setLanConfigs(lanResult.value);
2323
+ }
2324
+ }
2325
+ if (sections.includes('QSFP')) {
2326
+ const sysResult = results[sections.indexOf('QSFP')];
2327
+ if (sysResult.status === 'fulfilled' && sysResult.value) {
2328
+ setSt2110Interfaces(sysResult.value.st2110_interfaces || []);
2329
+ }
2330
+ }
2331
+ } catch (error) {
2332
+ console.error('Failed to fetch data:', error);
2333
+ }
2334
+ };
2335
+ if (open) {
2336
+ fetchInitialData();
2337
+ }
2338
+ }, [open, getLanConfig, getSysConfig, sections]);
2339
+
2340
+ // 动态初始值配置
2341
+ const initialValues = react.useMemo(() => {
2342
+ const values = {};
2343
+ if (sections.includes('LAN')) {
2344
+ values.LAN = lanConfigs.map(config => ({
2345
+ connection_id: config.connection_id,
2346
+ display_name: config.display_name,
2347
+ ip_address: config.ip_address,
2348
+ netmask: config.netmask
2349
+ })) ?? [];
2350
+ }
2351
+ if (sections.includes('QSFP')) {
2352
+ values.QSFP = st2110Interfaces?.map(iface => ({
2353
+ id: iface.id,
2354
+ display_name: iface.display_name,
2355
+ ip_address: iface.ip_address
2356
+ })) ?? [];
2357
+ }
2358
+ return values;
2359
+ }, [lanConfigs, st2110Interfaces, sections]);
2360
+ const handleSuccess = async function () {
2361
+ let isPopup = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
2362
+ let messageText = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'Success';
2363
+ message.success(messageText);
2364
+ if (isPopup) {
2365
+ try {
2366
+ const updatedConfig = await getSysConfig();
2367
+ if (updatedConfig && updatedConfig.is_restart_required) {
2368
+ modal.confirm({
2369
+ icon: /*#__PURE__*/jsxRuntime.jsx(icons.ExclamationCircleFilled, {}),
2370
+ title: "Configuration modified. Restart to apply changes?",
2371
+ cancelText: "No",
2372
+ okText: "Yes",
2373
+ onOk: () => restart()
2374
+ });
2375
+ }
2376
+ } catch (error) {
2377
+ console.error('Failed to check restart status:', error);
2378
+ }
2379
+ }
2380
+ onClose();
2381
+ };
2382
+ const handleSubmit = async () => {
2383
+ setSubmitLoading(true);
2384
+ try {
2385
+ const values = await form.validateFields();
2386
+ const updatePromises = [];
2387
+
2388
+ // 更新LAN配置
2389
+ if (sections.includes('LAN') && values.LAN) {
2390
+ const lanData = values.LAN.map((item, index) => ({
2391
+ connection_id: lanConfigs[index]?.connection_id,
2392
+ ip_address: item.ip_address,
2393
+ netmask: item.netmask
2394
+ }));
2395
+ updatePromises.push(updateLanConfig(lanData));
2396
+ }
2397
+
2398
+ // 更新QSFP配置
2399
+ if (sections.includes('QSFP') && values.QSFP) {
2400
+ const st2110Data = {
2401
+ st2110_interfaces: values.QSFP.map((item, index) => ({
2402
+ id: st2110Interfaces?.[index]?.id,
2403
+ ip_address: item.ip_address,
2404
+ enable_rx_video_demand_start: st2110Interfaces?.[index]?.enable_rx_video_demand_start
2405
+ }))
2406
+ };
2407
+ updatePromises.push(updateSysConfig(st2110Data));
2408
+ }
2409
+ const results = await Promise.allSettled(updatePromises);
2410
+
2411
+ // 检查所有更新是否成功
2412
+ const allSucceeded = results.every(result => result.status === 'fulfilled');
2413
+ if (allSucceeded) {
2414
+ handleSuccess();
2415
+ } else {
2416
+ message.error('Some configurations failed to update');
2417
+ }
2418
+ } catch (error) {
2419
+ console.error('Failed to update configurations: ', error);
2420
+ message.error('Failed to update configurations');
2421
+ } finally {
2422
+ setSubmitLoading(false);
2423
+ }
2424
+ };
2425
+
2426
+ // 合并默认模态框属性和传入的属性
2427
+ const mergedModalProps = {
2428
+ title: "Network Settings",
2429
+ width: 650,
2430
+ open,
2431
+ confirmLoading: submitLoading,
2432
+ onOk: handleSubmit,
2433
+ onCancel: onClose,
2434
+ okText: "Apply",
2435
+ cancelText: "Close",
2436
+ centered: true,
2437
+ styles: {
2438
+ body: {
2439
+ padding: "16px 24px 8px 24px"
2440
+ }
2441
+ },
2442
+ ...modalProps
2443
+ };
2444
+
2445
+ // 合并默认表单属性和传入的属性
2446
+ const mergedFormProps = {
2447
+ form: form,
2448
+ initialValues: initialValues,
2449
+ labelCol: {
2450
+ span: 6
2451
+ },
2452
+ wrapperCol: {
2453
+ span: 18
2454
+ },
2455
+ autoComplete: "off",
2456
+ ...formProps
2457
+ };
2458
+ return /*#__PURE__*/jsxRuntime.jsx(antd.Modal, {
2459
+ ...mergedModalProps,
2460
+ children: /*#__PURE__*/jsxRuntime.jsxs(antd.Form, {
2461
+ ...mergedFormProps,
2462
+ children: [sections.includes('LAN') && initialValues.LAN && initialValues.LAN.length > 0 && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
2463
+ children: [/*#__PURE__*/jsxRuntime.jsx(NetworkFieldGroup, {
2464
+ prefix: "LAN",
2465
+ interfaces: initialValues.LAN,
2466
+ fieldConfig: fieldConfig.LAN
2467
+ }), sections.includes('QSFP') && /*#__PURE__*/jsxRuntime.jsx(antd.Divider, {})]
2468
+ }), sections.includes('QSFP') && initialValues.QSFP && initialValues.QSFP.length > 0 && /*#__PURE__*/jsxRuntime.jsx(NetworkFieldGroup, {
2469
+ prefix: "QSFP",
2470
+ interfaces: initialValues.QSFP,
2471
+ fieldConfig: fieldConfig.QSFP
2472
+ })]
2473
+ })
2474
+ });
2475
+ };
2476
+ var NetworkSettingsModal$1 = /*#__PURE__*/react.memo(NetworkSettingsModal);
2477
+
1976
2478
  exports.AuthorizationModal = AuthorizationModal;
2479
+ exports.NetworkSettingsModal = NetworkSettingsModal$1;
2480
+ exports.PtpModal = PtpModal$1;
1977
2481
  exports.SystemOperations = SystemOperations;
1978
2482
  exports.UpgradeManager = UpgradeManager;
1979
2483
  exports.useAuth = useAuth;