@strapi-community/plugin-io 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +1308 -0
- package/dist/_chunks/MonitoringPage-DLZdTZpg.mjs +752 -0
- package/dist/_chunks/MonitoringPage-HxHK1nFr.js +754 -0
- package/dist/_chunks/SettingsPage-88RdJkLy.js +1411 -0
- package/dist/_chunks/SettingsPage-DBIu309c.mjs +1409 -0
- package/dist/_chunks/SocketStatsWidget--uGHcYvU.mjs +220 -0
- package/dist/_chunks/SocketStatsWidget-C1-1_VOB.js +222 -0
- package/dist/_chunks/de-BoFxKIL3.mjs +102 -0
- package/dist/_chunks/de-Crne_WJ-.js +102 -0
- package/dist/_chunks/en-B4_6Q0aQ.mjs +120 -0
- package/dist/_chunks/en-Bd2IKJzy.js +120 -0
- package/dist/_chunks/es-CCwv5Ulk.mjs +41 -0
- package/dist/_chunks/es-Xj8RgKuQ.js +41 -0
- package/dist/_chunks/fr-D_r96iuZ.js +41 -0
- package/dist/_chunks/fr-DtBI9vH_.mjs +41 -0
- package/dist/_chunks/index-BVQ20t1c.js +113 -0
- package/dist/_chunks/index-CEh8vkxY.mjs +411 -0
- package/dist/_chunks/index-DLXtrAtk.mjs +114 -0
- package/dist/_chunks/index-DkTxsEqL.js +428 -0
- package/dist/_chunks/pt-Bba2cd2e.js +41 -0
- package/dist/_chunks/pt-I9epJZpI.mjs +41 -0
- package/dist/admin/index.js +3 -0
- package/dist/admin/index.mjs +4 -0
- package/dist/server/index.js +30000 -0
- package/dist/server/index.mjs +29970 -0
- package/package.json +120 -0
- package/types.d.ts +362 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useCallback, useEffect } from "react";
|
|
3
|
+
import { Typography, Flex, Box } from "@strapi/design-system";
|
|
4
|
+
import { User, Message, Lightning, Check } from "@strapi/icons";
|
|
5
|
+
import { useFetchClient } from "@strapi/strapi/admin";
|
|
6
|
+
import styled from "styled-components";
|
|
7
|
+
const WidgetContainer = styled(Box)`
|
|
8
|
+
padding: 0;
|
|
9
|
+
position: relative;
|
|
10
|
+
`;
|
|
11
|
+
const HeaderContainer = styled(Flex)`
|
|
12
|
+
justify-content: space-between;
|
|
13
|
+
align-items: center;
|
|
14
|
+
margin-bottom: ${({ theme }) => theme.spaces[2]};
|
|
15
|
+
padding-bottom: ${({ theme }) => theme.spaces[2]};
|
|
16
|
+
border-bottom: 1px solid ${({ theme }) => theme.colors.neutral150};
|
|
17
|
+
`;
|
|
18
|
+
const LiveIndicator = styled.span`
|
|
19
|
+
display: inline-flex;
|
|
20
|
+
align-items: center;
|
|
21
|
+
gap: ${({ theme }) => theme.spaces[1]};
|
|
22
|
+
padding: ${({ theme }) => `${theme.spaces[1]} ${theme.spaces[2]}`};
|
|
23
|
+
background: ${({ theme, $isLive }) => $isLive ? theme.colors.success100 : theme.colors.danger100};
|
|
24
|
+
border-radius: ${({ theme }) => theme.borderRadius};
|
|
25
|
+
font-size: ${({ theme }) => theme.fontSizes[1]};
|
|
26
|
+
|
|
27
|
+
&::before {
|
|
28
|
+
content: '';
|
|
29
|
+
display: block;
|
|
30
|
+
width: 6px;
|
|
31
|
+
height: 6px;
|
|
32
|
+
border-radius: 50%;
|
|
33
|
+
background-color: ${({ theme, $isLive }) => $isLive ? theme.colors.success600 : theme.colors.danger600};
|
|
34
|
+
}
|
|
35
|
+
`;
|
|
36
|
+
const StatsGrid = styled.div`
|
|
37
|
+
display: grid;
|
|
38
|
+
grid-template-columns: repeat(2, 1fr);
|
|
39
|
+
gap: ${({ theme }) => theme.spaces[2]};
|
|
40
|
+
margin-bottom: ${({ theme }) => theme.spaces[3]};
|
|
41
|
+
|
|
42
|
+
@media (max-width: 768px) {
|
|
43
|
+
grid-template-columns: 1fr;
|
|
44
|
+
}
|
|
45
|
+
`;
|
|
46
|
+
const StatCard = styled.div`
|
|
47
|
+
background: ${({ theme, $color }) => {
|
|
48
|
+
const colorMap = {
|
|
49
|
+
primary: `linear-gradient(135deg, ${theme.colors.primary100} 0%, ${theme.colors.primary200} 100%)`,
|
|
50
|
+
success: `linear-gradient(135deg, ${theme.colors.success100} 0%, ${theme.colors.success200} 100%)`,
|
|
51
|
+
warning: `linear-gradient(135deg, ${theme.colors.warning100} 0%, ${theme.colors.warning200} 100%)`,
|
|
52
|
+
secondary: `linear-gradient(135deg, ${theme.colors.secondary100} 0%, ${theme.colors.secondary200} 100%)`
|
|
53
|
+
};
|
|
54
|
+
return colorMap[$color] || theme.colors.neutral100;
|
|
55
|
+
}};
|
|
56
|
+
border: 1px solid ${({ theme, $color }) => {
|
|
57
|
+
const colorMap = {
|
|
58
|
+
primary: theme.colors.primary300,
|
|
59
|
+
success: theme.colors.success300,
|
|
60
|
+
warning: theme.colors.warning300,
|
|
61
|
+
secondary: theme.colors.secondary300
|
|
62
|
+
};
|
|
63
|
+
return colorMap[$color] || theme.colors.neutral200;
|
|
64
|
+
}};
|
|
65
|
+
border-radius: ${({ theme }) => theme.borderRadius};
|
|
66
|
+
padding: ${({ theme }) => theme.spaces[3]};
|
|
67
|
+
transition: box-shadow 0.2s ease;
|
|
68
|
+
|
|
69
|
+
&:hover {
|
|
70
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
|
71
|
+
}
|
|
72
|
+
`;
|
|
73
|
+
const StatContent = styled.div`
|
|
74
|
+
display: flex;
|
|
75
|
+
align-items: center;
|
|
76
|
+
gap: ${({ theme }) => theme.spaces[2]};
|
|
77
|
+
`;
|
|
78
|
+
const IconWrapper = styled.div`
|
|
79
|
+
display: flex;
|
|
80
|
+
align-items: center;
|
|
81
|
+
justify-content: center;
|
|
82
|
+
width: 36px;
|
|
83
|
+
height: 36px;
|
|
84
|
+
min-width: 36px;
|
|
85
|
+
background: ${({ theme, $color }) => {
|
|
86
|
+
const colorMap = {
|
|
87
|
+
primary: theme.colors.primary600,
|
|
88
|
+
success: theme.colors.success600,
|
|
89
|
+
warning: theme.colors.warning600,
|
|
90
|
+
secondary: theme.colors.secondary600
|
|
91
|
+
};
|
|
92
|
+
return colorMap[$color] || theme.colors.neutral600;
|
|
93
|
+
}};
|
|
94
|
+
border-radius: ${({ theme }) => theme.borderRadius};
|
|
95
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
96
|
+
`;
|
|
97
|
+
const StatInfo = styled.div`
|
|
98
|
+
display: flex;
|
|
99
|
+
flex-direction: column;
|
|
100
|
+
gap: 2px;
|
|
101
|
+
flex: 1;
|
|
102
|
+
min-width: 0;
|
|
103
|
+
`;
|
|
104
|
+
const FooterLink = styled.a`
|
|
105
|
+
display: inline-flex;
|
|
106
|
+
align-items: center;
|
|
107
|
+
gap: ${({ theme }) => theme.spaces[1]};
|
|
108
|
+
padding: ${({ theme }) => `${theme.spaces[1]} ${theme.spaces[2]}`};
|
|
109
|
+
background: ${({ theme }) => theme.colors.primary100};
|
|
110
|
+
color: ${({ theme }) => theme.colors.primary700};
|
|
111
|
+
border: 1px solid ${({ theme }) => theme.colors.primary300};
|
|
112
|
+
border-radius: ${({ theme }) => theme.borderRadius};
|
|
113
|
+
text-decoration: none;
|
|
114
|
+
font-weight: 600;
|
|
115
|
+
font-size: ${({ theme }) => theme.fontSizes[1]};
|
|
116
|
+
transition: all 0.2s ease;
|
|
117
|
+
|
|
118
|
+
&:hover {
|
|
119
|
+
background: ${({ theme }) => theme.colors.primary600};
|
|
120
|
+
color: ${({ theme }) => theme.colors.neutral0};
|
|
121
|
+
border-color: ${({ theme }) => theme.colors.primary600};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
&::after {
|
|
125
|
+
content: '→';
|
|
126
|
+
}
|
|
127
|
+
`;
|
|
128
|
+
const LoadingContainer = styled(Box)`
|
|
129
|
+
display: flex;
|
|
130
|
+
align-items: center;
|
|
131
|
+
justify-content: center;
|
|
132
|
+
padding: ${({ theme }) => theme.spaces[4]};
|
|
133
|
+
min-height: 120px;
|
|
134
|
+
`;
|
|
135
|
+
const ErrorContainer = styled(Box)`
|
|
136
|
+
padding: ${({ theme }) => theme.spaces[3]};
|
|
137
|
+
background: ${({ theme }) => theme.colors.danger100};
|
|
138
|
+
border: 1px solid ${({ theme }) => theme.colors.danger300};
|
|
139
|
+
border-radius: ${({ theme }) => theme.borderRadius};
|
|
140
|
+
`;
|
|
141
|
+
const SocketStatsWidget = () => {
|
|
142
|
+
const { get } = useFetchClient();
|
|
143
|
+
const [stats, setStats] = useState(null);
|
|
144
|
+
const [isLive, setIsLive] = useState(false);
|
|
145
|
+
const [error, setError] = useState(null);
|
|
146
|
+
const [loading, setLoading] = useState(true);
|
|
147
|
+
const fetchStats = useCallback(async () => {
|
|
148
|
+
try {
|
|
149
|
+
const { data } = await get("/io/monitoring/stats");
|
|
150
|
+
setStats(data);
|
|
151
|
+
setIsLive(true);
|
|
152
|
+
setError(null);
|
|
153
|
+
setLoading(false);
|
|
154
|
+
} catch (err) {
|
|
155
|
+
console.error("Failed to fetch Socket.IO stats:", err);
|
|
156
|
+
setError(err.message);
|
|
157
|
+
setIsLive(false);
|
|
158
|
+
setLoading(false);
|
|
159
|
+
}
|
|
160
|
+
}, [get]);
|
|
161
|
+
useEffect(() => {
|
|
162
|
+
fetchStats();
|
|
163
|
+
const interval = setInterval(fetchStats, 6e4);
|
|
164
|
+
return () => clearInterval(interval);
|
|
165
|
+
}, [fetchStats]);
|
|
166
|
+
if (loading) {
|
|
167
|
+
return /* @__PURE__ */ jsx(LoadingContainer, { children: /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: "Loading stats..." }) });
|
|
168
|
+
}
|
|
169
|
+
if (error) {
|
|
170
|
+
return /* @__PURE__ */ jsx(ErrorContainer, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 1, children: [
|
|
171
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", textColor: "danger700", children: "Failed to load stats" }),
|
|
172
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "danger600", style: { fontSize: "12px" }, children: error })
|
|
173
|
+
] }) });
|
|
174
|
+
}
|
|
175
|
+
if (!stats) {
|
|
176
|
+
return /* @__PURE__ */ jsx(LoadingContainer, { children: /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: "No data available" }) });
|
|
177
|
+
}
|
|
178
|
+
const connectionStats = stats.connections || {};
|
|
179
|
+
const eventStats = stats.events || {};
|
|
180
|
+
return /* @__PURE__ */ jsxs(WidgetContainer, { children: [
|
|
181
|
+
/* @__PURE__ */ jsxs(HeaderContainer, { children: [
|
|
182
|
+
/* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "bold", textColor: "neutral800", children: "Socket.IO Statistics" }),
|
|
183
|
+
/* @__PURE__ */ jsx(LiveIndicator, { $isLive: isLive, children: /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", textColor: isLive ? "success700" : "danger700", children: isLive ? "Live" : "Offline" }) })
|
|
184
|
+
] }),
|
|
185
|
+
/* @__PURE__ */ jsxs(StatsGrid, { children: [
|
|
186
|
+
/* @__PURE__ */ jsx(StatCard, { $color: "primary", children: /* @__PURE__ */ jsxs(StatContent, { children: [
|
|
187
|
+
/* @__PURE__ */ jsx(IconWrapper, { $color: "primary", children: /* @__PURE__ */ jsx(User, { width: "18px", height: "18px", fill: "#ffffff" }) }),
|
|
188
|
+
/* @__PURE__ */ jsxs(StatInfo, { children: [
|
|
189
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral700", style: { fontSize: "12px" }, children: "Active Connections" }),
|
|
190
|
+
/* @__PURE__ */ jsx(Typography, { variant: "delta", fontWeight: "bold", textColor: "neutral900", children: connectionStats.connected || 0 })
|
|
191
|
+
] })
|
|
192
|
+
] }) }),
|
|
193
|
+
/* @__PURE__ */ jsx(StatCard, { $color: "success", children: /* @__PURE__ */ jsxs(StatContent, { children: [
|
|
194
|
+
/* @__PURE__ */ jsx(IconWrapper, { $color: "success", children: /* @__PURE__ */ jsx(Message, { width: "18px", height: "18px", fill: "#ffffff" }) }),
|
|
195
|
+
/* @__PURE__ */ jsxs(StatInfo, { children: [
|
|
196
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral700", style: { fontSize: "12px" }, children: "Active Rooms" }),
|
|
197
|
+
/* @__PURE__ */ jsx(Typography, { variant: "delta", fontWeight: "bold", textColor: "neutral900", children: connectionStats.rooms?.length || 0 })
|
|
198
|
+
] })
|
|
199
|
+
] }) }),
|
|
200
|
+
/* @__PURE__ */ jsx(StatCard, { $color: "warning", children: /* @__PURE__ */ jsxs(StatContent, { children: [
|
|
201
|
+
/* @__PURE__ */ jsx(IconWrapper, { $color: "warning", children: /* @__PURE__ */ jsx(Lightning, { width: "18px", height: "18px", fill: "#ffffff" }) }),
|
|
202
|
+
/* @__PURE__ */ jsxs(StatInfo, { children: [
|
|
203
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral700", style: { fontSize: "12px" }, children: "Events/sec" }),
|
|
204
|
+
/* @__PURE__ */ jsx(Typography, { variant: "delta", fontWeight: "bold", textColor: "neutral900", children: eventStats.eventsPerSecond || 0 })
|
|
205
|
+
] })
|
|
206
|
+
] }) }),
|
|
207
|
+
/* @__PURE__ */ jsx(StatCard, { $color: "secondary", children: /* @__PURE__ */ jsxs(StatContent, { children: [
|
|
208
|
+
/* @__PURE__ */ jsx(IconWrapper, { $color: "secondary", children: /* @__PURE__ */ jsx(Check, { width: "18px", height: "18px", fill: "#ffffff" }) }),
|
|
209
|
+
/* @__PURE__ */ jsxs(StatInfo, { children: [
|
|
210
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral700", style: { fontSize: "12px" }, children: "Total Events" }),
|
|
211
|
+
/* @__PURE__ */ jsx(Typography, { variant: "delta", fontWeight: "bold", textColor: "neutral900", children: (eventStats.totalEvents || 0).toLocaleString() })
|
|
212
|
+
] })
|
|
213
|
+
] }) })
|
|
214
|
+
] }),
|
|
215
|
+
/* @__PURE__ */ jsx(Flex, { justifyContent: "flex-end", children: /* @__PURE__ */ jsx(FooterLink, { href: "/admin/settings/io/monitoring", children: "View Monitoring" }) })
|
|
216
|
+
] });
|
|
217
|
+
};
|
|
218
|
+
export {
|
|
219
|
+
SocketStatsWidget
|
|
220
|
+
};
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
4
|
+
const React = require("react");
|
|
5
|
+
const designSystem = require("@strapi/design-system");
|
|
6
|
+
const icons = require("@strapi/icons");
|
|
7
|
+
const admin = require("@strapi/strapi/admin");
|
|
8
|
+
const styled = require("styled-components");
|
|
9
|
+
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
|
10
|
+
const styled__default = /* @__PURE__ */ _interopDefault(styled);
|
|
11
|
+
const WidgetContainer = styled__default.default(designSystem.Box)`
|
|
12
|
+
padding: 0;
|
|
13
|
+
position: relative;
|
|
14
|
+
`;
|
|
15
|
+
const HeaderContainer = styled__default.default(designSystem.Flex)`
|
|
16
|
+
justify-content: space-between;
|
|
17
|
+
align-items: center;
|
|
18
|
+
margin-bottom: ${({ theme }) => theme.spaces[2]};
|
|
19
|
+
padding-bottom: ${({ theme }) => theme.spaces[2]};
|
|
20
|
+
border-bottom: 1px solid ${({ theme }) => theme.colors.neutral150};
|
|
21
|
+
`;
|
|
22
|
+
const LiveIndicator = styled__default.default.span`
|
|
23
|
+
display: inline-flex;
|
|
24
|
+
align-items: center;
|
|
25
|
+
gap: ${({ theme }) => theme.spaces[1]};
|
|
26
|
+
padding: ${({ theme }) => `${theme.spaces[1]} ${theme.spaces[2]}`};
|
|
27
|
+
background: ${({ theme, $isLive }) => $isLive ? theme.colors.success100 : theme.colors.danger100};
|
|
28
|
+
border-radius: ${({ theme }) => theme.borderRadius};
|
|
29
|
+
font-size: ${({ theme }) => theme.fontSizes[1]};
|
|
30
|
+
|
|
31
|
+
&::before {
|
|
32
|
+
content: '';
|
|
33
|
+
display: block;
|
|
34
|
+
width: 6px;
|
|
35
|
+
height: 6px;
|
|
36
|
+
border-radius: 50%;
|
|
37
|
+
background-color: ${({ theme, $isLive }) => $isLive ? theme.colors.success600 : theme.colors.danger600};
|
|
38
|
+
}
|
|
39
|
+
`;
|
|
40
|
+
const StatsGrid = styled__default.default.div`
|
|
41
|
+
display: grid;
|
|
42
|
+
grid-template-columns: repeat(2, 1fr);
|
|
43
|
+
gap: ${({ theme }) => theme.spaces[2]};
|
|
44
|
+
margin-bottom: ${({ theme }) => theme.spaces[3]};
|
|
45
|
+
|
|
46
|
+
@media (max-width: 768px) {
|
|
47
|
+
grid-template-columns: 1fr;
|
|
48
|
+
}
|
|
49
|
+
`;
|
|
50
|
+
const StatCard = styled__default.default.div`
|
|
51
|
+
background: ${({ theme, $color }) => {
|
|
52
|
+
const colorMap = {
|
|
53
|
+
primary: `linear-gradient(135deg, ${theme.colors.primary100} 0%, ${theme.colors.primary200} 100%)`,
|
|
54
|
+
success: `linear-gradient(135deg, ${theme.colors.success100} 0%, ${theme.colors.success200} 100%)`,
|
|
55
|
+
warning: `linear-gradient(135deg, ${theme.colors.warning100} 0%, ${theme.colors.warning200} 100%)`,
|
|
56
|
+
secondary: `linear-gradient(135deg, ${theme.colors.secondary100} 0%, ${theme.colors.secondary200} 100%)`
|
|
57
|
+
};
|
|
58
|
+
return colorMap[$color] || theme.colors.neutral100;
|
|
59
|
+
}};
|
|
60
|
+
border: 1px solid ${({ theme, $color }) => {
|
|
61
|
+
const colorMap = {
|
|
62
|
+
primary: theme.colors.primary300,
|
|
63
|
+
success: theme.colors.success300,
|
|
64
|
+
warning: theme.colors.warning300,
|
|
65
|
+
secondary: theme.colors.secondary300
|
|
66
|
+
};
|
|
67
|
+
return colorMap[$color] || theme.colors.neutral200;
|
|
68
|
+
}};
|
|
69
|
+
border-radius: ${({ theme }) => theme.borderRadius};
|
|
70
|
+
padding: ${({ theme }) => theme.spaces[3]};
|
|
71
|
+
transition: box-shadow 0.2s ease;
|
|
72
|
+
|
|
73
|
+
&:hover {
|
|
74
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
|
75
|
+
}
|
|
76
|
+
`;
|
|
77
|
+
const StatContent = styled__default.default.div`
|
|
78
|
+
display: flex;
|
|
79
|
+
align-items: center;
|
|
80
|
+
gap: ${({ theme }) => theme.spaces[2]};
|
|
81
|
+
`;
|
|
82
|
+
const IconWrapper = styled__default.default.div`
|
|
83
|
+
display: flex;
|
|
84
|
+
align-items: center;
|
|
85
|
+
justify-content: center;
|
|
86
|
+
width: 36px;
|
|
87
|
+
height: 36px;
|
|
88
|
+
min-width: 36px;
|
|
89
|
+
background: ${({ theme, $color }) => {
|
|
90
|
+
const colorMap = {
|
|
91
|
+
primary: theme.colors.primary600,
|
|
92
|
+
success: theme.colors.success600,
|
|
93
|
+
warning: theme.colors.warning600,
|
|
94
|
+
secondary: theme.colors.secondary600
|
|
95
|
+
};
|
|
96
|
+
return colorMap[$color] || theme.colors.neutral600;
|
|
97
|
+
}};
|
|
98
|
+
border-radius: ${({ theme }) => theme.borderRadius};
|
|
99
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
100
|
+
`;
|
|
101
|
+
const StatInfo = styled__default.default.div`
|
|
102
|
+
display: flex;
|
|
103
|
+
flex-direction: column;
|
|
104
|
+
gap: 2px;
|
|
105
|
+
flex: 1;
|
|
106
|
+
min-width: 0;
|
|
107
|
+
`;
|
|
108
|
+
const FooterLink = styled__default.default.a`
|
|
109
|
+
display: inline-flex;
|
|
110
|
+
align-items: center;
|
|
111
|
+
gap: ${({ theme }) => theme.spaces[1]};
|
|
112
|
+
padding: ${({ theme }) => `${theme.spaces[1]} ${theme.spaces[2]}`};
|
|
113
|
+
background: ${({ theme }) => theme.colors.primary100};
|
|
114
|
+
color: ${({ theme }) => theme.colors.primary700};
|
|
115
|
+
border: 1px solid ${({ theme }) => theme.colors.primary300};
|
|
116
|
+
border-radius: ${({ theme }) => theme.borderRadius};
|
|
117
|
+
text-decoration: none;
|
|
118
|
+
font-weight: 600;
|
|
119
|
+
font-size: ${({ theme }) => theme.fontSizes[1]};
|
|
120
|
+
transition: all 0.2s ease;
|
|
121
|
+
|
|
122
|
+
&:hover {
|
|
123
|
+
background: ${({ theme }) => theme.colors.primary600};
|
|
124
|
+
color: ${({ theme }) => theme.colors.neutral0};
|
|
125
|
+
border-color: ${({ theme }) => theme.colors.primary600};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
&::after {
|
|
129
|
+
content: '→';
|
|
130
|
+
}
|
|
131
|
+
`;
|
|
132
|
+
const LoadingContainer = styled__default.default(designSystem.Box)`
|
|
133
|
+
display: flex;
|
|
134
|
+
align-items: center;
|
|
135
|
+
justify-content: center;
|
|
136
|
+
padding: ${({ theme }) => theme.spaces[4]};
|
|
137
|
+
min-height: 120px;
|
|
138
|
+
`;
|
|
139
|
+
const ErrorContainer = styled__default.default(designSystem.Box)`
|
|
140
|
+
padding: ${({ theme }) => theme.spaces[3]};
|
|
141
|
+
background: ${({ theme }) => theme.colors.danger100};
|
|
142
|
+
border: 1px solid ${({ theme }) => theme.colors.danger300};
|
|
143
|
+
border-radius: ${({ theme }) => theme.borderRadius};
|
|
144
|
+
`;
|
|
145
|
+
const SocketStatsWidget = () => {
|
|
146
|
+
const { get } = admin.useFetchClient();
|
|
147
|
+
const [stats, setStats] = React.useState(null);
|
|
148
|
+
const [isLive, setIsLive] = React.useState(false);
|
|
149
|
+
const [error, setError] = React.useState(null);
|
|
150
|
+
const [loading, setLoading] = React.useState(true);
|
|
151
|
+
const fetchStats = React.useCallback(async () => {
|
|
152
|
+
try {
|
|
153
|
+
const { data } = await get("/io/monitoring/stats");
|
|
154
|
+
setStats(data);
|
|
155
|
+
setIsLive(true);
|
|
156
|
+
setError(null);
|
|
157
|
+
setLoading(false);
|
|
158
|
+
} catch (err) {
|
|
159
|
+
console.error("Failed to fetch Socket.IO stats:", err);
|
|
160
|
+
setError(err.message);
|
|
161
|
+
setIsLive(false);
|
|
162
|
+
setLoading(false);
|
|
163
|
+
}
|
|
164
|
+
}, [get]);
|
|
165
|
+
React.useEffect(() => {
|
|
166
|
+
fetchStats();
|
|
167
|
+
const interval = setInterval(fetchStats, 6e4);
|
|
168
|
+
return () => clearInterval(interval);
|
|
169
|
+
}, [fetchStats]);
|
|
170
|
+
if (loading) {
|
|
171
|
+
return /* @__PURE__ */ jsxRuntime.jsx(LoadingContainer, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: "Loading stats..." }) });
|
|
172
|
+
}
|
|
173
|
+
if (error) {
|
|
174
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ErrorContainer, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 1, children: [
|
|
175
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", textColor: "danger700", children: "Failed to load stats" }),
|
|
176
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "danger600", style: { fontSize: "12px" }, children: error })
|
|
177
|
+
] }) });
|
|
178
|
+
}
|
|
179
|
+
if (!stats) {
|
|
180
|
+
return /* @__PURE__ */ jsxRuntime.jsx(LoadingContainer, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: "No data available" }) });
|
|
181
|
+
}
|
|
182
|
+
const connectionStats = stats.connections || {};
|
|
183
|
+
const eventStats = stats.events || {};
|
|
184
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(WidgetContainer, { children: [
|
|
185
|
+
/* @__PURE__ */ jsxRuntime.jsxs(HeaderContainer, { children: [
|
|
186
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "bold", textColor: "neutral800", children: "Socket.IO Statistics" }),
|
|
187
|
+
/* @__PURE__ */ jsxRuntime.jsx(LiveIndicator, { $isLive: isLive, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", textColor: isLive ? "success700" : "danger700", children: isLive ? "Live" : "Offline" }) })
|
|
188
|
+
] }),
|
|
189
|
+
/* @__PURE__ */ jsxRuntime.jsxs(StatsGrid, { children: [
|
|
190
|
+
/* @__PURE__ */ jsxRuntime.jsx(StatCard, { $color: "primary", children: /* @__PURE__ */ jsxRuntime.jsxs(StatContent, { children: [
|
|
191
|
+
/* @__PURE__ */ jsxRuntime.jsx(IconWrapper, { $color: "primary", children: /* @__PURE__ */ jsxRuntime.jsx(icons.User, { width: "18px", height: "18px", fill: "#ffffff" }) }),
|
|
192
|
+
/* @__PURE__ */ jsxRuntime.jsxs(StatInfo, { children: [
|
|
193
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral700", style: { fontSize: "12px" }, children: "Active Connections" }),
|
|
194
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", fontWeight: "bold", textColor: "neutral900", children: connectionStats.connected || 0 })
|
|
195
|
+
] })
|
|
196
|
+
] }) }),
|
|
197
|
+
/* @__PURE__ */ jsxRuntime.jsx(StatCard, { $color: "success", children: /* @__PURE__ */ jsxRuntime.jsxs(StatContent, { children: [
|
|
198
|
+
/* @__PURE__ */ jsxRuntime.jsx(IconWrapper, { $color: "success", children: /* @__PURE__ */ jsxRuntime.jsx(icons.Message, { width: "18px", height: "18px", fill: "#ffffff" }) }),
|
|
199
|
+
/* @__PURE__ */ jsxRuntime.jsxs(StatInfo, { children: [
|
|
200
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral700", style: { fontSize: "12px" }, children: "Active Rooms" }),
|
|
201
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", fontWeight: "bold", textColor: "neutral900", children: connectionStats.rooms?.length || 0 })
|
|
202
|
+
] })
|
|
203
|
+
] }) }),
|
|
204
|
+
/* @__PURE__ */ jsxRuntime.jsx(StatCard, { $color: "warning", children: /* @__PURE__ */ jsxRuntime.jsxs(StatContent, { children: [
|
|
205
|
+
/* @__PURE__ */ jsxRuntime.jsx(IconWrapper, { $color: "warning", children: /* @__PURE__ */ jsxRuntime.jsx(icons.Lightning, { width: "18px", height: "18px", fill: "#ffffff" }) }),
|
|
206
|
+
/* @__PURE__ */ jsxRuntime.jsxs(StatInfo, { children: [
|
|
207
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral700", style: { fontSize: "12px" }, children: "Events/sec" }),
|
|
208
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", fontWeight: "bold", textColor: "neutral900", children: eventStats.eventsPerSecond || 0 })
|
|
209
|
+
] })
|
|
210
|
+
] }) }),
|
|
211
|
+
/* @__PURE__ */ jsxRuntime.jsx(StatCard, { $color: "secondary", children: /* @__PURE__ */ jsxRuntime.jsxs(StatContent, { children: [
|
|
212
|
+
/* @__PURE__ */ jsxRuntime.jsx(IconWrapper, { $color: "secondary", children: /* @__PURE__ */ jsxRuntime.jsx(icons.Check, { width: "18px", height: "18px", fill: "#ffffff" }) }),
|
|
213
|
+
/* @__PURE__ */ jsxRuntime.jsxs(StatInfo, { children: [
|
|
214
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral700", style: { fontSize: "12px" }, children: "Total Events" }),
|
|
215
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", fontWeight: "bold", textColor: "neutral900", children: (eventStats.totalEvents || 0).toLocaleString() })
|
|
216
|
+
] })
|
|
217
|
+
] }) })
|
|
218
|
+
] }),
|
|
219
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "flex-end", children: /* @__PURE__ */ jsxRuntime.jsx(FooterLink, { href: "/admin/settings/io/monitoring", children: "View Monitoring" }) })
|
|
220
|
+
] });
|
|
221
|
+
};
|
|
222
|
+
exports.SocketStatsWidget = SocketStatsWidget;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
const de = {
|
|
2
|
+
"plugin.name": "Socket.IO",
|
|
3
|
+
"widget.socket-stats.title": "Socket.IO Stats",
|
|
4
|
+
"widget.connections": "Aktive Verbindungen",
|
|
5
|
+
"widget.rooms": "Aktive Räume",
|
|
6
|
+
"widget.eventsPerSec": "Events/Sek.",
|
|
7
|
+
"widget.totalEvents": "Gesamt-Events",
|
|
8
|
+
"widget.viewMonitoring": "Monitoring anzeigen",
|
|
9
|
+
"widget.live": "Live",
|
|
10
|
+
"widget.offline": "Offline",
|
|
11
|
+
"settings.title": "Einstellungen",
|
|
12
|
+
"settings.description": "Konfiguriere die Socket.IO Verbindung für Echtzeit-Events",
|
|
13
|
+
"settings.save": "Speichern",
|
|
14
|
+
"settings.saved": "Gespeichert",
|
|
15
|
+
"settings.saveAndApply": "Speichern & Anwenden",
|
|
16
|
+
"settings.success": "Einstellungen erfolgreich gespeichert!",
|
|
17
|
+
"settings.error": "Fehler beim Speichern der Einstellungen",
|
|
18
|
+
"settings.loadError": "Fehler beim Laden der Einstellungen",
|
|
19
|
+
"settings.noRestart": "Änderungen werden sofort übernommen – kein Neustart erforderlich!",
|
|
20
|
+
"cors.title": "CORS Einstellungen",
|
|
21
|
+
"cors.description": "Konfiguriere welche Frontends sich verbinden dürfen",
|
|
22
|
+
"cors.origins": "Erlaubte Origins",
|
|
23
|
+
"cors.originsHint": "Füge mehrere Frontend-URLs hinzu, die sich verbinden dürfen",
|
|
24
|
+
"cors.add": "Hinzufügen",
|
|
25
|
+
"cors.credentials": "Credentials erlauben",
|
|
26
|
+
"cors.methods": "Erlaubte HTTP Methoden",
|
|
27
|
+
"connection.title": "Verbindungseinstellungen",
|
|
28
|
+
"connection.description": "Konfiguriere Verbindungslimits und Timeouts",
|
|
29
|
+
"connection.maxConnections": "Max. Verbindungen",
|
|
30
|
+
"connection.pingTimeout": "Ping Timeout (ms)",
|
|
31
|
+
"connection.pingInterval": "Ping Intervall (ms)",
|
|
32
|
+
"connection.connectionTimeout": "Verbindungs-Timeout (ms)",
|
|
33
|
+
"security.title": "Sicherheitseinstellungen",
|
|
34
|
+
"security.description": "Konfiguriere Authentifizierung und Rate Limiting",
|
|
35
|
+
"security.requireAuth": "Authentifizierung erforderlich",
|
|
36
|
+
"security.rateLimiting": "Rate Limiting aktivieren",
|
|
37
|
+
"security.maxEventsPerSecond": "Max. Events/Sekunde",
|
|
38
|
+
"events.title": "Echtzeit-Events",
|
|
39
|
+
"events.description": "Konfiguriere welche Events für welche Content Types gesendet werden",
|
|
40
|
+
"events.enableAll": "Alle aktivieren",
|
|
41
|
+
"events.disableAll": "Alle deaktivieren",
|
|
42
|
+
"events.noContentTypes": "Keine API Content Types gefunden. Erstelle zuerst Content Types im Content-Type Builder.",
|
|
43
|
+
"events.contentType": "Content Type",
|
|
44
|
+
"events.create": "Erstellen",
|
|
45
|
+
"events.update": "Aktualisieren",
|
|
46
|
+
"events.delete": "Löschen",
|
|
47
|
+
"events.customNames": "Benutzerdefinierte Event-Namen verwenden",
|
|
48
|
+
"events.includeRelations": "Relationen einbeziehen",
|
|
49
|
+
"events.onlyPublished": "Nur veröffentlichte Inhalte",
|
|
50
|
+
"permissions.title": "Rollen-Berechtigungen",
|
|
51
|
+
"permissions.description": "Konfiguriere Socket.IO Berechtigungen pro Benutzerrolle",
|
|
52
|
+
"permissions.role": "Rolle",
|
|
53
|
+
"permissions.canConnect": "Kann verbinden",
|
|
54
|
+
"permissions.blocked": "Blockiert",
|
|
55
|
+
"permissions.contentTypesEnabled": "Content Types aktiviert",
|
|
56
|
+
"permissions.allowConnection": "Verbindung erlauben",
|
|
57
|
+
"permissions.allowConnectionHint": "Benutzer mit dieser Rolle können sich mit Socket.IO verbinden",
|
|
58
|
+
"permissions.allowCredentials": "Credentials erlauben",
|
|
59
|
+
"permissions.allowCredentialsHint": "Cookies und Auth-Header erlauben",
|
|
60
|
+
"permissions.allowedMethods": "Erlaubte HTTP Methoden",
|
|
61
|
+
"permissions.contentTypePermissions": "Content-Type-Berechtigungen",
|
|
62
|
+
"permissions.noRoles": "Keine Rollen gefunden",
|
|
63
|
+
"redis.title": "Redis Adapter",
|
|
64
|
+
"redis.description": "Redis für Multi-Server Skalierung aktivieren",
|
|
65
|
+
"redis.enable": "Redis Adapter aktivieren",
|
|
66
|
+
"redis.url": "Redis URL",
|
|
67
|
+
"namespaces.title": "Namespaces",
|
|
68
|
+
"namespaces.description": "Separate Socket.IO Endpunkte erstellen",
|
|
69
|
+
"namespaces.enable": "Namespaces aktivieren",
|
|
70
|
+
"namespaces.list": "Namespaces",
|
|
71
|
+
"namespaces.add": "Hinzufügen",
|
|
72
|
+
"namespaces.hint": "Beispiele: admin, chat, notifications",
|
|
73
|
+
"monitoring.title": "Monitoring & Logging",
|
|
74
|
+
"monitoring.description": "Echtzeit-Verbindungs- und Event-Statistiken",
|
|
75
|
+
"monitoring.connectionLogging": "Verbindungs-Logging",
|
|
76
|
+
"monitoring.connectionLoggingHint": "Client-Verbindungen protokollieren",
|
|
77
|
+
"monitoring.eventLogging": "Event-Logging",
|
|
78
|
+
"monitoring.eventLoggingHint": "Alle Events zum Debuggen protokollieren",
|
|
79
|
+
"monitoring.maxLogSize": "Max. Log-Größe",
|
|
80
|
+
"monitoring.refresh": "Aktualisieren",
|
|
81
|
+
"monitoring.reset": "Statistiken zurücksetzen",
|
|
82
|
+
"monitoring.connectedClients": "Verbundene Clients",
|
|
83
|
+
"monitoring.totalEvents": "Gesamt-Events",
|
|
84
|
+
"monitoring.eventsPerSecond": "Events/Sekunde",
|
|
85
|
+
"monitoring.rooms": "Aktive Räume",
|
|
86
|
+
"monitoring.testEvent": "Test-Event senden",
|
|
87
|
+
"monitoring.eventName": "Event-Name",
|
|
88
|
+
"monitoring.eventData": "Event-Daten (JSON)",
|
|
89
|
+
"monitoring.send": "Senden",
|
|
90
|
+
"monitoring.connectedClientsList": "Verbundene Clients",
|
|
91
|
+
"monitoring.noClients": "Keine Clients verbunden",
|
|
92
|
+
"monitoring.eventLog": "Letzte Events",
|
|
93
|
+
"monitoring.noEvents": "Noch keine Events protokolliert",
|
|
94
|
+
"monitoring.invalidJson": "Ungültige JSON-Daten",
|
|
95
|
+
"monitoring.testEventSent": "Test-Event erfolgreich gesendet!",
|
|
96
|
+
"monitoring.testEventError": "Fehler beim Senden des Test-Events",
|
|
97
|
+
"monitoring.statsReset": "Statistiken erfolgreich zurückgesetzt!",
|
|
98
|
+
"monitoring.resetError": "Fehler beim Zurücksetzen der Statistiken"
|
|
99
|
+
};
|
|
100
|
+
export {
|
|
101
|
+
de as default
|
|
102
|
+
};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const de = {
|
|
4
|
+
"plugin.name": "Socket.IO",
|
|
5
|
+
"widget.socket-stats.title": "Socket.IO Stats",
|
|
6
|
+
"widget.connections": "Aktive Verbindungen",
|
|
7
|
+
"widget.rooms": "Aktive Räume",
|
|
8
|
+
"widget.eventsPerSec": "Events/Sek.",
|
|
9
|
+
"widget.totalEvents": "Gesamt-Events",
|
|
10
|
+
"widget.viewMonitoring": "Monitoring anzeigen",
|
|
11
|
+
"widget.live": "Live",
|
|
12
|
+
"widget.offline": "Offline",
|
|
13
|
+
"settings.title": "Einstellungen",
|
|
14
|
+
"settings.description": "Konfiguriere die Socket.IO Verbindung für Echtzeit-Events",
|
|
15
|
+
"settings.save": "Speichern",
|
|
16
|
+
"settings.saved": "Gespeichert",
|
|
17
|
+
"settings.saveAndApply": "Speichern & Anwenden",
|
|
18
|
+
"settings.success": "Einstellungen erfolgreich gespeichert!",
|
|
19
|
+
"settings.error": "Fehler beim Speichern der Einstellungen",
|
|
20
|
+
"settings.loadError": "Fehler beim Laden der Einstellungen",
|
|
21
|
+
"settings.noRestart": "Änderungen werden sofort übernommen – kein Neustart erforderlich!",
|
|
22
|
+
"cors.title": "CORS Einstellungen",
|
|
23
|
+
"cors.description": "Konfiguriere welche Frontends sich verbinden dürfen",
|
|
24
|
+
"cors.origins": "Erlaubte Origins",
|
|
25
|
+
"cors.originsHint": "Füge mehrere Frontend-URLs hinzu, die sich verbinden dürfen",
|
|
26
|
+
"cors.add": "Hinzufügen",
|
|
27
|
+
"cors.credentials": "Credentials erlauben",
|
|
28
|
+
"cors.methods": "Erlaubte HTTP Methoden",
|
|
29
|
+
"connection.title": "Verbindungseinstellungen",
|
|
30
|
+
"connection.description": "Konfiguriere Verbindungslimits und Timeouts",
|
|
31
|
+
"connection.maxConnections": "Max. Verbindungen",
|
|
32
|
+
"connection.pingTimeout": "Ping Timeout (ms)",
|
|
33
|
+
"connection.pingInterval": "Ping Intervall (ms)",
|
|
34
|
+
"connection.connectionTimeout": "Verbindungs-Timeout (ms)",
|
|
35
|
+
"security.title": "Sicherheitseinstellungen",
|
|
36
|
+
"security.description": "Konfiguriere Authentifizierung und Rate Limiting",
|
|
37
|
+
"security.requireAuth": "Authentifizierung erforderlich",
|
|
38
|
+
"security.rateLimiting": "Rate Limiting aktivieren",
|
|
39
|
+
"security.maxEventsPerSecond": "Max. Events/Sekunde",
|
|
40
|
+
"events.title": "Echtzeit-Events",
|
|
41
|
+
"events.description": "Konfiguriere welche Events für welche Content Types gesendet werden",
|
|
42
|
+
"events.enableAll": "Alle aktivieren",
|
|
43
|
+
"events.disableAll": "Alle deaktivieren",
|
|
44
|
+
"events.noContentTypes": "Keine API Content Types gefunden. Erstelle zuerst Content Types im Content-Type Builder.",
|
|
45
|
+
"events.contentType": "Content Type",
|
|
46
|
+
"events.create": "Erstellen",
|
|
47
|
+
"events.update": "Aktualisieren",
|
|
48
|
+
"events.delete": "Löschen",
|
|
49
|
+
"events.customNames": "Benutzerdefinierte Event-Namen verwenden",
|
|
50
|
+
"events.includeRelations": "Relationen einbeziehen",
|
|
51
|
+
"events.onlyPublished": "Nur veröffentlichte Inhalte",
|
|
52
|
+
"permissions.title": "Rollen-Berechtigungen",
|
|
53
|
+
"permissions.description": "Konfiguriere Socket.IO Berechtigungen pro Benutzerrolle",
|
|
54
|
+
"permissions.role": "Rolle",
|
|
55
|
+
"permissions.canConnect": "Kann verbinden",
|
|
56
|
+
"permissions.blocked": "Blockiert",
|
|
57
|
+
"permissions.contentTypesEnabled": "Content Types aktiviert",
|
|
58
|
+
"permissions.allowConnection": "Verbindung erlauben",
|
|
59
|
+
"permissions.allowConnectionHint": "Benutzer mit dieser Rolle können sich mit Socket.IO verbinden",
|
|
60
|
+
"permissions.allowCredentials": "Credentials erlauben",
|
|
61
|
+
"permissions.allowCredentialsHint": "Cookies und Auth-Header erlauben",
|
|
62
|
+
"permissions.allowedMethods": "Erlaubte HTTP Methoden",
|
|
63
|
+
"permissions.contentTypePermissions": "Content-Type-Berechtigungen",
|
|
64
|
+
"permissions.noRoles": "Keine Rollen gefunden",
|
|
65
|
+
"redis.title": "Redis Adapter",
|
|
66
|
+
"redis.description": "Redis für Multi-Server Skalierung aktivieren",
|
|
67
|
+
"redis.enable": "Redis Adapter aktivieren",
|
|
68
|
+
"redis.url": "Redis URL",
|
|
69
|
+
"namespaces.title": "Namespaces",
|
|
70
|
+
"namespaces.description": "Separate Socket.IO Endpunkte erstellen",
|
|
71
|
+
"namespaces.enable": "Namespaces aktivieren",
|
|
72
|
+
"namespaces.list": "Namespaces",
|
|
73
|
+
"namespaces.add": "Hinzufügen",
|
|
74
|
+
"namespaces.hint": "Beispiele: admin, chat, notifications",
|
|
75
|
+
"monitoring.title": "Monitoring & Logging",
|
|
76
|
+
"monitoring.description": "Echtzeit-Verbindungs- und Event-Statistiken",
|
|
77
|
+
"monitoring.connectionLogging": "Verbindungs-Logging",
|
|
78
|
+
"monitoring.connectionLoggingHint": "Client-Verbindungen protokollieren",
|
|
79
|
+
"monitoring.eventLogging": "Event-Logging",
|
|
80
|
+
"monitoring.eventLoggingHint": "Alle Events zum Debuggen protokollieren",
|
|
81
|
+
"monitoring.maxLogSize": "Max. Log-Größe",
|
|
82
|
+
"monitoring.refresh": "Aktualisieren",
|
|
83
|
+
"monitoring.reset": "Statistiken zurücksetzen",
|
|
84
|
+
"monitoring.connectedClients": "Verbundene Clients",
|
|
85
|
+
"monitoring.totalEvents": "Gesamt-Events",
|
|
86
|
+
"monitoring.eventsPerSecond": "Events/Sekunde",
|
|
87
|
+
"monitoring.rooms": "Aktive Räume",
|
|
88
|
+
"monitoring.testEvent": "Test-Event senden",
|
|
89
|
+
"monitoring.eventName": "Event-Name",
|
|
90
|
+
"monitoring.eventData": "Event-Daten (JSON)",
|
|
91
|
+
"monitoring.send": "Senden",
|
|
92
|
+
"monitoring.connectedClientsList": "Verbundene Clients",
|
|
93
|
+
"monitoring.noClients": "Keine Clients verbunden",
|
|
94
|
+
"monitoring.eventLog": "Letzte Events",
|
|
95
|
+
"monitoring.noEvents": "Noch keine Events protokolliert",
|
|
96
|
+
"monitoring.invalidJson": "Ungültige JSON-Daten",
|
|
97
|
+
"monitoring.testEventSent": "Test-Event erfolgreich gesendet!",
|
|
98
|
+
"monitoring.testEventError": "Fehler beim Senden des Test-Events",
|
|
99
|
+
"monitoring.statsReset": "Statistiken erfolgreich zurückgesetzt!",
|
|
100
|
+
"monitoring.resetError": "Fehler beim Zurücksetzen der Statistiken"
|
|
101
|
+
};
|
|
102
|
+
exports.default = de;
|