diff --git a/spring-boot-admin-server-ui/.storybook/preview.js b/spring-boot-admin-server-ui/.storybook/preview.js
index 04de9c96924..60460106dd3 100644
--- a/spring-boot-admin-server-ui/.storybook/preview.js
+++ b/spring-boot-admin-server-ui/.storybook/preview.js
@@ -5,10 +5,17 @@ import Vue from "vue/dist/vue.js";
import components from "@/components";
import i18n from "@/i18n";
import VueI18n from "vue-i18n";
+import mappingsEndpoint from '@/mocks/instance/mappings';
+
+import { initialize, mswDecorator } from 'msw-storybook-addon';
+
+// Initialize MSW
+initialize();
Vue.use(VueI18n);
Vue.use(components);
+
export const parameters = {
actions: {argTypesRegex: "^on[A-Z].*"},
controls: {
@@ -17,6 +24,12 @@ export const parameters = {
date: /Date$/,
},
},
+ msw: {
+ handlers: {
+ auth: null,
+ others: [...mappingsEndpoint]
+ }
+ }
}
export const decorators = [
@@ -25,7 +38,8 @@ export const decorators = [
return Vue.extend({
i18n,
components: {wrapped},
- template: ``
+ template: `
+ `
})
- },
+ }, mswDecorator
]
diff --git a/spring-boot-admin-server-ui/package-lock.json b/spring-boot-admin-server-ui/package-lock.json
index 42b1b6714c7..c0e858146e7 100644
--- a/spring-boot-admin-server-ui/package-lock.json
+++ b/spring-boot-admin-server-ui/package-lock.json
@@ -70,6 +70,7 @@
"jest-each": "26.6.2",
"jest-environment-jsdom-sixteen": "2.0.0",
"msw": "0.35.0",
+ "msw-storybook-addon": "1.5.0",
"node-sass": "6.0.1",
"sass-loader": "10.2.0",
"style-loader": "1.3.0",
@@ -24679,6 +24680,19 @@
"url": "https://opencollective.com/mswjs"
}
},
+ "node_modules/msw-storybook-addon": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/msw-storybook-addon/-/msw-storybook-addon-1.5.0.tgz",
+ "integrity": "sha512-2TmCREX+lVFlYwu+l9bwoxeI5+iXinJ7xOAahDKNRhgIrymaRTjAmCQx3h2NT7DJDvZKQcPstgCdhl03Q7ocHA==",
+ "dev": true,
+ "dependencies": {
+ "@storybook/addons": "^6.0.0",
+ "is-node-process": "^1.0.1"
+ },
+ "peerDependencies": {
+ "msw": "^0.35.0"
+ }
+ },
"node_modules/msw/node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
@@ -55515,6 +55529,16 @@
}
}
},
+ "msw-storybook-addon": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/msw-storybook-addon/-/msw-storybook-addon-1.5.0.tgz",
+ "integrity": "sha512-2TmCREX+lVFlYwu+l9bwoxeI5+iXinJ7xOAahDKNRhgIrymaRTjAmCQx3h2NT7DJDvZKQcPstgCdhl03Q7ocHA==",
+ "dev": true,
+ "requires": {
+ "@storybook/addons": "^6.0.0",
+ "is-node-process": "^1.0.1"
+ }
+ },
"multicast-dns": {
"version": "6.2.3",
"resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz",
diff --git a/spring-boot-admin-server-ui/package.json b/spring-boot-admin-server-ui/package.json
index b30c7896e6e..1e59c1c38a0 100644
--- a/spring-boot-admin-server-ui/package.json
+++ b/spring-boot-admin-server-ui/package.json
@@ -8,7 +8,7 @@
"lint": "vue-cli-service lint",
"lint:fix": "vue-cli-service lint --fix",
"watch": "vue-cli-service build --watch",
- "storybook": "start-storybook -p 6006",
+ "storybook": "start-storybook -p 6006 -s public",
"build-storybook": "build-storybook"
},
"engines": {
@@ -81,6 +81,7 @@
"jest-each": "26.6.2",
"jest-environment-jsdom-sixteen": "2.0.0",
"msw": "0.35.0",
+ "msw-storybook-addon": "1.5.0",
"node-sass": "6.0.1",
"sass-loader": "10.2.0",
"style-loader": "1.3.0",
@@ -168,5 +169,8 @@
"**/*.spec.js"
],
"testURL": "http://example.com"
+ },
+ "msw": {
+ "workerDirectory": "public"
}
}
diff --git a/spring-boot-admin-server-ui/public/mockServiceWorker.js b/spring-boot-admin-server-ui/public/mockServiceWorker.js
new file mode 100644
index 00000000000..86167669ad2
--- /dev/null
+++ b/spring-boot-admin-server-ui/public/mockServiceWorker.js
@@ -0,0 +1,338 @@
+/* eslint-disable */
+/* tslint:disable */
+
+/**
+ * Mock Service Worker (0.35.0).
+ * @see https://github.com/mswjs/msw
+ * - Please do NOT modify this file.
+ * - Please do NOT serve this file on production.
+ */
+
+const INTEGRITY_CHECKSUM = 'f0a916b13c8acc2b526a03a6d26df85f'
+const bypassHeaderName = 'x-msw-bypass'
+const activeClientIds = new Set()
+
+self.addEventListener('install', function () {
+ return self.skipWaiting()
+})
+
+self.addEventListener('activate', async function (event) {
+ return self.clients.claim()
+})
+
+self.addEventListener('message', async function (event) {
+ const clientId = event.source.id
+
+ if (!clientId || !self.clients) {
+ return
+ }
+
+ const client = await self.clients.get(clientId)
+
+ if (!client) {
+ return
+ }
+
+ const allClients = await self.clients.matchAll()
+
+ switch (event.data) {
+ case 'KEEPALIVE_REQUEST': {
+ sendToClient(client, {
+ type: 'KEEPALIVE_RESPONSE',
+ })
+ break
+ }
+
+ case 'INTEGRITY_CHECK_REQUEST': {
+ sendToClient(client, {
+ type: 'INTEGRITY_CHECK_RESPONSE',
+ payload: INTEGRITY_CHECKSUM,
+ })
+ break
+ }
+
+ case 'MOCK_ACTIVATE': {
+ activeClientIds.add(clientId)
+
+ sendToClient(client, {
+ type: 'MOCKING_ENABLED',
+ payload: true,
+ })
+ break
+ }
+
+ case 'MOCK_DEACTIVATE': {
+ activeClientIds.delete(clientId)
+ break
+ }
+
+ case 'CLIENT_CLOSED': {
+ activeClientIds.delete(clientId)
+
+ const remainingClients = allClients.filter((client) => {
+ return client.id !== clientId
+ })
+
+ // Unregister itself when there are no more clients
+ if (remainingClients.length === 0) {
+ self.registration.unregister()
+ }
+
+ break
+ }
+ }
+})
+
+// Resolve the "master" client for the given event.
+// Client that issues a request doesn't necessarily equal the client
+// that registered the worker. It's with the latter the worker should
+// communicate with during the response resolving phase.
+async function resolveMasterClient(event) {
+ const client = await self.clients.get(event.clientId)
+
+ if (client.frameType === 'top-level') {
+ return client
+ }
+
+ const allClients = await self.clients.matchAll()
+
+ return allClients
+ .filter((client) => {
+ // Get only those clients that are currently visible.
+ return client.visibilityState === 'visible'
+ })
+ .find((client) => {
+ // Find the client ID that's recorded in the
+ // set of clients that have registered the worker.
+ return activeClientIds.has(client.id)
+ })
+}
+
+async function handleRequest(event, requestId) {
+ const client = await resolveMasterClient(event)
+ const response = await getResponse(event, client, requestId)
+
+ // Send back the response clone for the "response:*" life-cycle events.
+ // Ensure MSW is active and ready to handle the message, otherwise
+ // this message will pend indefinitely.
+ if (client && activeClientIds.has(client.id)) {
+ ;(async function () {
+ const clonedResponse = response.clone()
+ sendToClient(client, {
+ type: 'RESPONSE',
+ payload: {
+ requestId,
+ type: clonedResponse.type,
+ ok: clonedResponse.ok,
+ status: clonedResponse.status,
+ statusText: clonedResponse.statusText,
+ body:
+ clonedResponse.body === null ? null : await clonedResponse.text(),
+ headers: serializeHeaders(clonedResponse.headers),
+ redirected: clonedResponse.redirected,
+ },
+ })
+ })()
+ }
+
+ return response
+}
+
+async function getResponse(event, client, requestId) {
+ const { request } = event
+ const requestClone = request.clone()
+ const getOriginalResponse = () => fetch(requestClone)
+
+ // Bypass mocking when the request client is not active.
+ if (!client) {
+ return getOriginalResponse()
+ }
+
+ // Bypass initial page load requests (i.e. static assets).
+ // The absence of the immediate/parent client in the map of the active clients
+ // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet
+ // and is not ready to handle requests.
+ if (!activeClientIds.has(client.id)) {
+ return await getOriginalResponse()
+ }
+
+ // Bypass requests with the explicit bypass header
+ if (requestClone.headers.get(bypassHeaderName) === 'true') {
+ const cleanRequestHeaders = serializeHeaders(requestClone.headers)
+
+ // Remove the bypass header to comply with the CORS preflight check.
+ delete cleanRequestHeaders[bypassHeaderName]
+
+ const originalRequest = new Request(requestClone, {
+ headers: new Headers(cleanRequestHeaders),
+ })
+
+ return fetch(originalRequest)
+ }
+
+ // Send the request to the client-side MSW.
+ const reqHeaders = serializeHeaders(request.headers)
+ const body = await request.text()
+
+ const clientMessage = await sendToClient(client, {
+ type: 'REQUEST',
+ payload: {
+ id: requestId,
+ url: request.url,
+ method: request.method,
+ headers: reqHeaders,
+ cache: request.cache,
+ mode: request.mode,
+ credentials: request.credentials,
+ destination: request.destination,
+ integrity: request.integrity,
+ redirect: request.redirect,
+ referrer: request.referrer,
+ referrerPolicy: request.referrerPolicy,
+ body,
+ bodyUsed: request.bodyUsed,
+ keepalive: request.keepalive,
+ },
+ })
+
+ switch (clientMessage.type) {
+ case 'MOCK_SUCCESS': {
+ return delayPromise(
+ () => respondWithMock(clientMessage),
+ clientMessage.payload.delay,
+ )
+ }
+
+ case 'MOCK_NOT_FOUND': {
+ return getOriginalResponse()
+ }
+
+ case 'NETWORK_ERROR': {
+ const { name, message } = clientMessage.payload
+ const networkError = new Error(message)
+ networkError.name = name
+
+ // Rejecting a request Promise emulates a network error.
+ throw networkError
+ }
+
+ case 'INTERNAL_ERROR': {
+ const parsedBody = JSON.parse(clientMessage.payload.body)
+
+ console.error(
+ `\
+[MSW] Uncaught exception in the request handler for "%s %s":
+
+${parsedBody.location}
+
+This exception has been gracefully handled as a 500 response, however, it's strongly recommended to resolve this error, as it indicates a mistake in your code. If you wish to mock an error response, please see this guide: https://mswjs.io/docs/recipes/mocking-error-responses\
+`,
+ request.method,
+ request.url,
+ )
+
+ return respondWithMock(clientMessage)
+ }
+ }
+
+ return getOriginalResponse()
+}
+
+self.addEventListener('fetch', function (event) {
+ const { request } = event
+ const accept = request.headers.get('accept') || ''
+
+ // Bypass server-sent events.
+ if (accept.includes('text/event-stream')) {
+ return
+ }
+
+ // Bypass navigation requests.
+ if (request.mode === 'navigate') {
+ return
+ }
+
+ // Opening the DevTools triggers the "only-if-cached" request
+ // that cannot be handled by the worker. Bypass such requests.
+ if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') {
+ return
+ }
+
+ // Bypass all requests when there are no active clients.
+ // Prevents the self-unregistered worked from handling requests
+ // after it's been deleted (still remains active until the next reload).
+ if (activeClientIds.size === 0) {
+ return
+ }
+
+ const requestId = uuidv4()
+
+ return event.respondWith(
+ handleRequest(event, requestId).catch((error) => {
+ if (error.name === 'NetworkError') {
+ console.warn(
+ '[MSW] Successfully emulated a network error for the "%s %s" request.',
+ request.method,
+ request.url,
+ )
+ return
+ }
+
+ // At this point, any exception indicates an issue with the original request/response.
+ console.error(
+ `\
+[MSW] Caught an exception from the "%s %s" request (%s). This is probably not a problem with Mock Service Worker. There is likely an additional logging output above.`,
+ request.method,
+ request.url,
+ `${error.name}: ${error.message}`,
+ )
+ }),
+ )
+})
+
+function serializeHeaders(headers) {
+ const reqHeaders = {}
+ headers.forEach((value, name) => {
+ reqHeaders[name] = reqHeaders[name]
+ ? [].concat(reqHeaders[name]).concat(value)
+ : value
+ })
+ return reqHeaders
+}
+
+function sendToClient(client, message) {
+ return new Promise((resolve, reject) => {
+ const channel = new MessageChannel()
+
+ channel.port1.onmessage = (event) => {
+ if (event.data && event.data.error) {
+ return reject(event.data.error)
+ }
+
+ resolve(event.data)
+ }
+
+ client.postMessage(JSON.stringify(message), [channel.port2])
+ })
+}
+
+function delayPromise(cb, duration) {
+ return new Promise((resolve) => {
+ setTimeout(() => resolve(cb()), duration)
+ })
+}
+
+function respondWithMock(clientMessage) {
+ return new Response(clientMessage.payload.body, {
+ ...clientMessage.payload,
+ headers: clientMessage.payload.headers,
+ })
+}
+
+function uuidv4() {
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
+ const r = (Math.random() * 16) | 0
+ const v = c == 'x' ? r : (r & 0x3) | 0x8
+ return v.toString(16)
+ })
+}
diff --git a/spring-boot-admin-server-ui/src/main/frontend/mocks/browser.js b/spring-boot-admin-server-ui/src/main/frontend/mocks/browser.js
new file mode 100644
index 00000000000..2428b407589
--- /dev/null
+++ b/spring-boot-admin-server-ui/src/main/frontend/mocks/browser.js
@@ -0,0 +1,4 @@
+import {setupWorker} from 'msw'
+import {handlers} from '@/handlers';
+
+export const worker = setupWorker(...handlers)
diff --git a/spring-boot-admin-server-ui/src/main/frontend/mocks/instance/mappings/auditevents_data.js b/spring-boot-admin-server-ui/src/main/frontend/mocks/instance/mappings/auditevents_data.js
new file mode 100644
index 00000000000..ccd1654ce45
--- /dev/null
+++ b/spring-boot-admin-server-ui/src/main/frontend/mocks/instance/mappings/auditevents_data.js
@@ -0,0 +1,293 @@
+let now = new Date();
+const today = now.getFullYear() + "-" + (now.getMonth()+1) + "-" + now.getDate();
+
+export const auditeventsresponse = {
+ "events": [
+ {
+ "timestamp": today +"T05:03:58.546Z",
+ "principal": "anonymous",
+ "type": "CREATE_TEST",
+ "data": {
+ "json": "\"Test\"",
+ "source": "DUM",
+ "sessionId": "anonymous",
+ "objectId": "Test"
+ }
+ },
+ {
+ "timestamp": today +"T05:03:57.435400Z",
+ "principal": "anonymous",
+ "type": "CREATE_TEST",
+ "data": {
+ "json": "{\"id\":\"12345\",\"timestamp\":\"2021-10-12T14:48:34.738201+08:00\",\"gender\":\"M\"}",
+ "source": "DUM",
+ "sessionId": "anonymous",
+ "objectId": "12345"
+ }
+ },
+ {
+ "timestamp": today +"T05:03:55.729744Z",
+ "principal": "anonymous",
+ "type": "CREATE_TEST",
+ "data": {
+ "json": "\"Test\"",
+ "source": "DUM",
+ "sessionId": "anonymous",
+ "objectId": "Test"
+ }
+ },
+ {
+ "timestamp": today +"T05:03:55.729498Z",
+ "principal": "anonymous",
+ "type": "CREATE_TEST",
+ "data": {
+ "json": "{\"id\":\"12345\",\"timestamp\":\"2021-10-12T14:48:34.738201+08:00\",\"gender\":\"M\"}",
+ "source": "DUM",
+ "sessionId": "anonymous",
+ "objectId": "12345"
+ }
+ },
+ {
+ "timestamp": today +"T04:42:49.715651Z",
+ "principal": "anonymous",
+ "type": "CREATE_TEST",
+ "data": {
+ "json": "\"Test\"",
+ "source": "DUM",
+ "sessionId": "anonymous",
+ "objectId": "Test"
+ }
+ },
+ {
+ "timestamp": today +"T04:42:49.715194Z",
+ "principal": "anonymous",
+ "type": "CREATE_TEST",
+ "data": {
+ "json": "{\"id\":\"12345\",\"timestamp\":\"2021-10-12T14:48:34.738201+08:00\",\"gender\":\"M\"}",
+ "source": "DUM",
+ "sessionId": "anonymous",
+ "objectId": "12345"
+ }
+ },
+ {
+ "timestamp": today +"T04:42:49.156299Z",
+ "principal": "anonymous",
+ "type": "CREATE_TEST",
+ "data": {
+ "json": "\"Test\"",
+ "source": "DUM",
+ "sessionId": "anonymous",
+ "objectId": "Test"
+ }
+ },
+ {
+ "timestamp": today +"T04:42:49.156030Z",
+ "principal": "anonymous",
+ "type": "CREATE_TEST",
+ "data": {
+ "json": "{\"id\":\"12345\",\"timestamp\":\"2021-10-12T14:48:34.738201+08:00\",\"gender\":\"M\"}",
+ "source": "DUM",
+ "sessionId": "anonymous",
+ "objectId": "12345"
+ }
+ },
+ {
+ "timestamp": today +"T04:42:48.773277Z",
+ "principal": "anonymous",
+ "type": "CREATE_TEST",
+ "data": {
+ "json": "\"Test\"",
+ "source": "DUM",
+ "sessionId": "anonymous",
+ "objectId": "Test"
+ }
+ },
+ {
+ "timestamp": today +"T04:42:48.773099Z",
+ "principal": "anonymous",
+ "type": "CREATE_TEST",
+ "data": {
+ "json": "{\"id\":\"12345\",\"timestamp\":\"2021-10-12T14:48:34.738201+08:00\",\"gender\":\"M\"}",
+ "source": "DUM",
+ "sessionId": "anonymous",
+ "objectId": "12345"
+ }
+ },
+ {
+ "timestamp": today +"T04:42:05.304815Z",
+ "principal": "anonymous",
+ "type": "CREATE_TEST",
+ "data": {
+ "json": "\"Test\"",
+ "source": "DUM",
+ "sessionId": "anonymous",
+ "objectId": "Test"
+ }
+ },
+ {
+ "timestamp": today +"T04:42:05.297055Z",
+ "principal": "anonymous",
+ "type": "CREATE_TEST",
+ "data": {
+ "json": "{\"id\":\"12345\",\"timestamp\":\"2021-10-12T14:48:34.738201+08:00\",\"gender\":\"M\"}",
+ "source": "DUM",
+ "sessionId": "anonymous",
+ "objectId": "12345"
+ }
+ },
+ {
+ "timestamp": today +"T04:37:54.450217Z",
+ "principal": "anonymous",
+ "type": "CREATE_TEST",
+ "data": {
+ "json": "\"Test\"",
+ "source": "application",
+ "sessionId": "anonymous",
+ "objectId": "Test"
+ }
+ },
+ {
+ "timestamp": today +"T04:37:54.449951Z",
+ "principal": "anonymous",
+ "type": "CREATE_TEST",
+ "data": {
+ "json": "{\"id\":\"12345\",\"timestamp\":\"2021-10-12T14:48:34.738201+08:00\",\"gender\":\"M\"}",
+ "source": "application",
+ "sessionId": "anonymous",
+ "objectId": "12345"
+ }
+ },
+ {
+ "timestamp": today +"T04:29:40.238505Z",
+ "principal": "anonymous",
+ "type": "CREATE_TEST",
+ "data": {
+ "json": "\"Test\"",
+ "source": "application",
+ "sessionId": "anonymous",
+ "objectId": "Test"
+ }
+ },
+ {
+ "timestamp": today +"T04:29:40.238317Z",
+ "principal": "anonymous",
+ "type": "CREATE_TEST",
+ "data": {
+ "json": "{\"id\":\"12345\",\"timestamp\":\"2021-10-12T14:48:34.738201+08:00\",\"gender\":\"M\"}",
+ "source": "application",
+ "sessionId": "anonymous",
+ "objectId": "12345"
+ }
+ },
+ {
+ "timestamp": today +"T01:15:34.825846Z",
+ "principal": "anonymous",
+ "type": "CREATE_TEST",
+ "data": {
+ "json": "\"Test\"",
+ "source": "DUM",
+ "sessionId": "anonymous",
+ "objectId": "Test"
+ }
+ },
+ {
+ "timestamp": today +"T01:15:34.825565Z",
+ "principal": "anonymous",
+ "type": "CREATE_TEST",
+ "data": {
+ "json": "{\"id\":\"12345\",\"timestamp\":\"2021-10-12T14:48:34.738201+08:00\",\"gender\":\"M\"}",
+ "source": "DUM",
+ "sessionId": "anonymous",
+ "objectId": "12345"
+ }
+ },
+ {
+ "timestamp": today +"T01:15:34.001904Z",
+ "principal": "anonymous",
+ "type": "CREATE_TEST",
+ "data": {
+ "json": "\"Test\"",
+ "source": "DUM",
+ "sessionId": "anonymous",
+ "objectId": "Test"
+ }
+ },
+ {
+ "timestamp": today +"T01:15:34.001034Z",
+ "principal": "anonymous",
+ "type": "CREATE_TEST",
+ "data": {
+ "json": "{\"id\":\"12345\",\"timestamp\":\"2021-10-12T14:48:34.738201+08:00\",\"gender\":\"M\"}",
+ "source": "DUM",
+ "sessionId": "anonymous",
+ "objectId": "12345"
+ }
+ },
+ {
+ "timestamp": today +"T01:15:33.561225Z",
+ "principal": "anonymous",
+ "type": "CREATE_TEST",
+ "data": {
+ "json": "\"Test\"",
+ "source": "DUM",
+ "sessionId": "anonymous",
+ "objectId": "Test"
+ }
+ },
+ {
+ "timestamp": today +"T01:15:33.560174Z",
+ "principal": "anonymous",
+ "type": "CREATE_TEST",
+ "data": {
+ "json": "{\"id\":\"12345\",\"timestamp\":\"2021-10-12T14:48:34.738201+08:00\",\"gender\":\"M\"}",
+ "source": "DUM",
+ "sessionId": "anonymous",
+ "objectId": "12345"
+ }
+ },
+ {
+ "timestamp": today +"T01:14:41.743788Z",
+ "principal": "anonymous",
+ "type": "CREATE_TEST",
+ "data": {
+ "json": "\"Test\"",
+ "source": "DUM",
+ "sessionId": "anonymous",
+ "objectId": "Test"
+ }
+ },
+ {
+ "timestamp": today +"T01:14:41.742988Z",
+ "principal": "anonymous",
+ "type": "CREATE_TEST",
+ "data": {
+ "json": "{\"id\":\"12345\",\"timestamp\":\"2021-10-12T14:48:34.738201+08:00\",\"gender\":\"M\"}",
+ "source": "DUM",
+ "sessionId": "anonymous",
+ "objectId": "12345"
+ }
+ },
+ {
+ "timestamp": today +"T01:14:13.969356Z",
+ "principal": "anonymous",
+ "type": "CREATE_TEST",
+ "data": {
+ "json": "\"Test\"",
+ "source": "DUM",
+ "sessionId": "anonymous",
+ "objectId": "Test"
+ }
+ },
+ {
+ "timestamp": today +"T01:14:13.954901Z",
+ "principal": "anonymous",
+ "type": "CREATE_TEST",
+ "data": {
+ "json": "{\"id\":\"12345\",\"timestamp\":\"2021-10-12T14:48:34.738201+08:00\",\"gender\":\"M\"}",
+ "source": "DUM",
+ "sessionId": "anonymous",
+ "objectId": "12345"
+ }
+ }
+ ]
+}
diff --git a/spring-boot-admin-server-ui/src/main/frontend/mocks/instance/mappings/index.js b/spring-boot-admin-server-ui/src/main/frontend/mocks/instance/mappings/index.js
index 6868aeaef97..87bc068c33b 100644
--- a/spring-boot-admin-server-ui/src/main/frontend/mocks/instance/mappings/index.js
+++ b/spring-boot-admin-server-ui/src/main/frontend/mocks/instance/mappings/index.js
@@ -1,5 +1,6 @@
import { rest } from 'msw';
import { mappings } from './data';
+import { auditeventsresponse } from "./auditevents_data";
const mappingsEndpoint = [
rest.get(
@@ -8,6 +9,12 @@ const mappingsEndpoint = [
return res(ctx.status(200), ctx.json(mappings));
}
),
+ rest.get(
+ '/instances/:instanceId/actuator/auditevents',
+ (req, res, ctx) => {
+ return res(ctx.status(200), ctx.json(auditeventsresponse));
+ }
+ ),
];
export default mappingsEndpoint;
diff --git a/spring-boot-admin-server-ui/src/main/frontend/views/instances/auditevents/auditevents-list.stories.js b/spring-boot-admin-server-ui/src/main/frontend/views/instances/auditevents/auditevents-list.stories.js
new file mode 100644
index 00000000000..425dfb93066
--- /dev/null
+++ b/spring-boot-admin-server-ui/src/main/frontend/views/instances/auditevents/auditevents-list.stories.js
@@ -0,0 +1,20 @@
+import Index from './index';
+import Instance from "@/services/instance";
+import {applications} from '@/mocks/applications/data'
+
+export default {
+ component: Index,
+ title: 'SBA View/AuditeventsList',
+};
+
+const Template = (args, {argTypes}) => ({
+ components: {Index},
+ props: Object.keys(argTypes),
+ template: ''
+});
+
+export const Test = Template.bind({});
+Test.args = {
+ instance: new Instance({id: 'bba333956ae6', ...applications[0].instances[0]})
+};
+