Skip to content

Commit 7c3841c

Browse files
committed
fix: standardize date formatting across components using useDateTimeFormatter
1 parent 627962e commit 7c3841c

File tree

16 files changed

+640
-26
lines changed

16 files changed

+640
-26
lines changed

spring-boot-admin-server-ui/src/main/frontend/components/sba-pagination-nav.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
<sba-button :disabled="modelValue >= pageCount" @click="goNext">
5454
<span class="sr-only" v-text="$t('term.go_to_next_page')" />
5555
<font-awesome-icon
56-
class="h-5 w-10"
56+
class="h-5 w-5"
5757
:icon="['fas', 'angle-double-right']"
5858
/>
5959
</sba-button>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
type DateFormatterOptions = {
2+
dateTimeFormat?: Intl.DateTimeFormatOptions;
3+
timeFormat?: Intl.DateTimeFormatOptions;
4+
};
5+
6+
export const useDateTimeFormatter = (options?: DateFormatterOptions) => {
7+
const userLocale = navigator.languages
8+
? navigator.languages[0]
9+
: navigator.language;
10+
11+
const dateTimeFormat = new Intl.DateTimeFormat(userLocale, {
12+
...{ dateStyle: 'medium', timeStyle: 'medium' },
13+
...(options?.dateTimeFormat ?? {}),
14+
});
15+
16+
return {
17+
formatDateTime: (date: Date) => {
18+
return dateTimeFormat.format(date);
19+
},
20+
};
21+
};

spring-boot-admin-server-ui/src/main/frontend/mocks/browser.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,20 @@ import { setupWorker } from 'msw/browser';
22

33
import auditEventsEndpoint from './instance/auditevents/index.js';
44
import flywayEndpoints from './instance/flyway/index.js';
5+
import httpTraceEndpoints from './instance/httptrace/index.js';
56
import liquibaseEndpoints from './instance/liquibase/index.js';
67
import mappingsEndpoint from './instance/mappings/index.js';
78
import metricsEndpoint from './instance/metrics/index.js';
9+
import sessionEndpoints from './instance/sessions/index.js';
810

911
const handler = [
1012
...mappingsEndpoint,
1113
...liquibaseEndpoints,
1214
...flywayEndpoints,
1315
...auditEventsEndpoint,
1416
...metricsEndpoint,
17+
...httpTraceEndpoints,
18+
...sessionEndpoints,
1519
];
1620

1721
export const worker = setupWorker(...handler);

spring-boot-admin-server-ui/src/main/frontend/mocks/instance/auditevents/data.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
const now = new Date();
2-
const today =
3-
now.getFullYear() + '-' + (now.getMonth() + 1) + '-' + now.getDate();
2+
const today = [
3+
now.getFullYear(),
4+
String(now.getMonth() + 1).padStart(2, '0'),
5+
String(now.getDate()).padStart(2, '0'),
6+
].join('-');
47

58
export const auditeventsresponse = {
69
events: [
Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
const now = new Date();
2+
const today = [
3+
now.getFullYear(),
4+
String(now.getMonth() + 1).padStart(2, '0'),
5+
String(now.getDate()).padStart(2, '0'),
6+
].join('-');
7+
8+
export const httptraceresponse = {
9+
traces: [
10+
{
11+
timestamp: today + 'T09:12:34.567Z',
12+
principal: 'admin',
13+
session: 'D43F6A32C1E34A7B',
14+
request: {
15+
method: 'GET',
16+
uri: 'http://localhost:8080/api/users',
17+
headers: {
18+
accept: ['application/json'],
19+
'user-agent': [
20+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
21+
],
22+
authorization: ['Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'],
23+
},
24+
remoteAddress: '192.168.1.105',
25+
},
26+
response: {
27+
status: 200,
28+
headers: {
29+
'content-type': ['application/json'],
30+
'content-length': ['1024'],
31+
'cache-control': ['no-cache, no-store, max-age=0, must-revalidate'],
32+
},
33+
timeTaken: 125,
34+
},
35+
},
36+
{
37+
timestamp: today + 'T09:13:45.678Z',
38+
principal: 'user123',
39+
session: 'E54G7B43D2F45B8C',
40+
request: {
41+
method: 'POST',
42+
uri: 'http://localhost:8080/api/orders',
43+
headers: {
44+
'content-type': ['application/json'],
45+
'user-agent': ['PostmanRuntime/7.29.2'],
46+
authorization: ['Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'],
47+
},
48+
remoteAddress: '192.168.1.110',
49+
},
50+
response: {
51+
status: 201,
52+
headers: {
53+
'content-type': ['application/json'],
54+
location: ['/api/orders/12345'],
55+
'content-length': ['256'],
56+
},
57+
timeTaken: 187,
58+
},
59+
},
60+
{
61+
timestamp: today + today + 'T09:14:56.789Z',
62+
principal: null,
63+
session: null,
64+
request: {
65+
method: 'GET',
66+
uri: 'http://localhost:8080/api/products',
67+
headers: {
68+
accept: ['application/json'],
69+
'user-agent': ['curl/7.68.0'],
70+
},
71+
remoteAddress: '192.168.1.115',
72+
},
73+
response: {
74+
status: 200,
75+
headers: {
76+
'content-type': ['application/json'],
77+
'content-length': ['2048'],
78+
'cache-control': ['max-age=3600'],
79+
},
80+
timeTaken: 95,
81+
},
82+
},
83+
{
84+
timestamp: today + 'T09:15:23.456Z',
85+
principal: 'user456',
86+
session: 'F65H8C54E3G56D9E',
87+
request: {
88+
method: 'PUT',
89+
uri: 'http://localhost:8080/api/users/profile',
90+
headers: {
91+
'content-type': ['application/json'],
92+
'user-agent': ['Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)'],
93+
authorization: ['Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'],
94+
},
95+
remoteAddress: '192.168.1.120',
96+
},
97+
response: {
98+
status: 200,
99+
headers: {
100+
'content-type': ['application/json'],
101+
'content-length': ['512'],
102+
},
103+
timeTaken: 143,
104+
},
105+
},
106+
{
107+
timestamp: today + 'T09:16:34.567Z',
108+
principal: null,
109+
session: null,
110+
request: {
111+
method: 'GET',
112+
uri: 'http://localhost:8080/actuator/health',
113+
headers: {
114+
accept: ['application/json'],
115+
'user-agent': ['Prometheus/2.40.0'],
116+
},
117+
remoteAddress: '192.168.1.200',
118+
},
119+
response: {
120+
status: 200,
121+
headers: {
122+
'content-type': ['application/json'],
123+
'content-length': ['15'],
124+
},
125+
timeTaken: 12,
126+
},
127+
},
128+
{
129+
timestamp: today + 'T09:17:45.678Z',
130+
principal: 'admin',
131+
session: 'D43F6A32C1E34A7B',
132+
request: {
133+
method: 'DELETE',
134+
uri: 'http://localhost:8080/api/products/54321',
135+
headers: {
136+
'user-agent': [
137+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
138+
],
139+
authorization: ['Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'],
140+
},
141+
remoteAddress: '192.168.1.105',
142+
},
143+
response: {
144+
status: 204,
145+
headers: {
146+
'cache-control': ['no-cache, no-store, max-age=0, must-revalidate'],
147+
},
148+
timeTaken: 78,
149+
},
150+
},
151+
{
152+
timestamp: today + 'T09:18:56.789Z',
153+
principal: null,
154+
session: null,
155+
request: {
156+
method: 'OPTIONS',
157+
uri: 'http://localhost:8080/api/users',
158+
headers: {
159+
origin: ['https://example.com'],
160+
'access-control-request-method': ['GET'],
161+
'user-agent': [
162+
'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X)',
163+
],
164+
},
165+
remoteAddress: '192.168.1.130',
166+
},
167+
response: {
168+
status: 200,
169+
headers: {
170+
'access-control-allow-origin': ['https://example.com'],
171+
'access-control-allow-methods': ['GET, POST, PUT, DELETE'],
172+
'access-control-allow-headers': ['Authorization, Content-Type'],
173+
'access-control-max-age': ['3600'],
174+
},
175+
timeTaken: 5,
176+
},
177+
},
178+
{
179+
timestamp: today + 'T09:19:23.456Z',
180+
principal: 'user789',
181+
session: 'G76I9D65F4H67E0F',
182+
request: {
183+
method: 'GET',
184+
uri: 'http://localhost:8080/api/orders/history?page=0&size=10',
185+
headers: {
186+
accept: ['application/json'],
187+
'user-agent': ['Mozilla/5.0 (Android 12; Mobile)'],
188+
authorization: ['Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'],
189+
},
190+
remoteAddress: '192.168.1.140',
191+
},
192+
response: {
193+
status: 200,
194+
headers: {
195+
'content-type': ['application/json'],
196+
'content-length': ['1536'],
197+
'x-total-count': ['45'],
198+
},
199+
timeTaken: 167,
200+
},
201+
},
202+
{
203+
timestamp: today + 'T09:20:34.567Z',
204+
principal: null,
205+
session: null,
206+
request: {
207+
method: 'GET',
208+
uri: 'http://localhost:8080/api/nonexistent',
209+
headers: {
210+
accept: ['application/json'],
211+
'user-agent': ['curl/7.68.0'],
212+
},
213+
remoteAddress: '192.168.1.150',
214+
},
215+
response: {
216+
status: 404,
217+
headers: {
218+
'content-type': ['application/json'],
219+
'content-length': ['64'],
220+
},
221+
timeTaken: 23,
222+
},
223+
},
224+
{
225+
timestamp: today + 'T09:21:45.678Z',
226+
principal: 'user123',
227+
session: 'E54G7B43D2F45B8C',
228+
request: {
229+
method: 'POST',
230+
uri: 'http://localhost:8080/api/checkout',
231+
headers: {
232+
'content-type': ['application/json'],
233+
'user-agent': ['PostmanRuntime/7.29.2'],
234+
authorization: ['Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'],
235+
},
236+
remoteAddress: '192.168.1.110',
237+
},
238+
response: {
239+
status: 400,
240+
headers: {
241+
'content-type': ['application/json'],
242+
'content-length': ['128'],
243+
},
244+
timeTaken: 45,
245+
},
246+
},
247+
],
248+
};
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { HttpResponse, http } from 'msw';
2+
3+
import { httptraceresponse } from '@/mocks/instance/httptrace/data';
4+
5+
const endpoints = [
6+
http.get('/instances/:instanceId/actuator/httptrace', () => {
7+
return HttpResponse.json(httptraceresponse);
8+
}),
9+
];
10+
11+
export default endpoints;
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
const now = new Date();
2+
const today = [
3+
now.getFullYear(),
4+
String(now.getMonth() + 1).padStart(2, '0'),
5+
String(now.getDate()).padStart(2, '0'),
6+
].join('-');
7+
8+
export const scheduledtasksResponse = {
9+
cron: [
10+
{
11+
runnable: {
12+
target: 'com.example.Processor.processOrders',
13+
},
14+
expression: '0 0 0/3 1/1 * ?',
15+
nextExecution: {
16+
time: '2025-05-22T20:59:59.999087966Z',
17+
},
18+
},
19+
],
20+
fixedDelay: [
21+
{
22+
runnable: {
23+
target: 'com.example.Processor.purge',
24+
},
25+
initialDelay: 0,
26+
interval: 5000,
27+
nextExecution: {
28+
time: '2025-05-22T20:03:39.767908889Z',
29+
},
30+
lastExecution: {
31+
time: '2025-05-22T20:03:34.761508282Z',
32+
status: 'SUCCESS',
33+
},
34+
},
35+
],
36+
fixedRate: [
37+
{
38+
runnable: {
39+
target: 'com.example.Processor.retrieveIssues',
40+
},
41+
initialDelay: 10000,
42+
interval: 3000,
43+
nextExecution: {
44+
time: '2025-05-22T20:03:44.755151650Z',
45+
},
46+
},
47+
],
48+
custom: [
49+
{
50+
runnable: {
51+
target: 'com.example.Processor$CustomTriggeredRunnable@6e5b7446',
52+
},
53+
trigger: 'com.example.Processor$CustomTrigger@513ad29e',
54+
lastExecution: {
55+
exception: {
56+
message: 'Failed while running custom task',
57+
type: 'java.lang.IllegalStateException',
58+
},
59+
time: '2025-05-22T20:03:34.807437342Z',
60+
status: 'ERROR',
61+
},
62+
},
63+
],
64+
};

0 commit comments

Comments
 (0)