Skip to content

Commit

Permalink
Conditions evaluation report (#3474)
Browse files Browse the repository at this point in the history
  • Loading branch information
ulischulte authored Jul 20, 2024
1 parent b1e378e commit fdf2a98
Show file tree
Hide file tree
Showing 8 changed files with 508 additions and 1 deletion.
2 changes: 1 addition & 1 deletion spring-boot-admin-server-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"scripts": {
"build": "vite build --emptyOutDir --sourcemap",
"build:dev": "NODE_ENV=development vite build --emptyOutDir --sourcemap --mode development",
"build:watch": "NODE_ENV=development vite build --emptyOutDir --watch --mode development",
"build:watch": "NODE_ENV=development vite build --emptyOutDir --sourcemap --watch --mode development",
"dev": "vite",
"test": "vitest run --silent",
"test:watch": "vitest",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,10 @@ class Instance {
return this.axios.get(uri`actuator/beans`);
}

async fetchConditions() {
return this.axios.get(uri`actuator/conditions`);
}

async fetchThreaddump() {
return this.axios.get(uri`actuator/threaddump`);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { screen } from '@testing-library/vue';
import { describe, expect, it } from 'vitest';

import { render } from '@/test-utils';
import ConditionsListDetails from '@/views/instances/conditions/conditions-list-details.vue';

describe('ConditionsListDetails', () => {
it('should display condition', async () => {
render(ConditionsListDetails, {
props: {
condition: {
condition: 'SpringBootAdminServerEnabledCondition',
},
},
});
expect(
await screen.findByLabelText('instances.conditions.condition'),
).toHaveTextContent('SpringBootAdminServerEnabledCondition');
});

it('should display message', async () => {
render(ConditionsListDetails, {
props: {
condition: {
message: 'matched',
},
},
});
expect(
await screen.findByLabelText('instances.conditions.message'),
).toHaveTextContent('matched');
});

it.each`
condition
${undefined}
${null}
${''}
`(
'should not display condition if condition is $condition',
async ({ condition }) => {
render(ConditionsListDetails, {
props: {
condition: {
condition,
},
},
});
expect(
screen.queryByLabelText('instances.conditions.condition'),
).not.toBeInTheDocument();
},
);

it.each`
message
${undefined}
${null}
${''}
`(
'should not display message if message is $message',
async ({ message }) => {
render(ConditionsListDetails, {
props: {
condition: {
message,
},
},
});
expect(
screen.queryByLabelText('instances.conditions.message'),
).not.toBeInTheDocument();
},
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<!--
- Copyright 2014-2024 the original author or authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-->

<template>
<table>
<colgroup>
<col class="text-gray-500" />
<col class="py-3" />
</colgroup>
<tbody>
<!-- Condition -->
<tr v-if="condition.condition">
<th
:id="`conditions-label-${id}`"
class="label"
v-text="$t('instances.conditions.condition')"
/>
<td
:aria-labelledby="`conditions-label-${id}`"
class="value"
v-text="condition.condition"
/>
</tr>

<!-- Message -->
<tr v-if="condition.message">
<th
:id="`message-label-${id}`"
class="label"
v-text="$t('instances.conditions.message')"
/>
<td
:aria-labelledby="`message-label-${id}`"
class="value"
v-text="condition.message"
/>
</tr>
</tbody>
</table>
</template>

<script setup lang="ts">
defineProps<{
condition: {
condition: string;
message: string;
};
}>();
const id = Math.floor(Math.random() * 1_000_000);
</script>

<style>
.label {
@apply text-gray-500 text-sm text-right px-2 align-top w-32;
}
.value {
@apply text-sm break-all;
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<!--
- Copyright 2014-2024 the original author or authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-->

<template>
<div class="-mx-4 -my-3">
<template
v-for="(conditionalBean, index) in conditionalBeans"
:key="conditionalBean.name"
>
<div class="m-1 border rounded shadow-sm">
<div
:key="conditionalBean.name"
class="flex items-center"
:class="{
'bg-gray-50':
index % 2 === 0 || showDetails[conditionalBean.name] === true,
'px-3 pt-2': showDetails[conditionalBean.name] === true,
'px-4 py-3': showDetails[conditionalBean.name] !== true,
}"
>
<div class="flex-1 sm:break-all">
<h4
:class="{
'font-bold': showDetails[conditionalBean.name] === true,
}"
:title="conditionalBean.name"
@click="toggle(conditionalBean.name)"
v-text="conditionalBean.name"
/>
<template v-if="showDetails[conditionalBean.name] === true">
<h5
v-if="
conditionalBean.matched.length &&
conditionalBean.notMatched.length
"
class="px-2 py-1"
>
{{ $t('instances.conditions.matched') }}
</h5>
<template
v-for="matchedCondition in conditionalBean.matched"
:key="matchedCondition.condition"
>
<div class="py-2 m-1 border rounded">
<conditions-list-details :condition="matchedCondition" />
</div>
</template>
<h5 v-if="conditionalBean.notMatched.length" class="px-2 py-1">
{{ $t('instances.conditions.not-matched') }}
</h5>
<template
v-for="notMatchedCondition in conditionalBean.notMatched"
:key="notMatchedCondition.condition"
>
<div class="py-2 m-1 border rounded">
<conditions-list-details :condition="notMatchedCondition" />
</div>
</template>
</template>
</div>
</div>
</div>
</template>
</div>
</template>

<script>
import ConditionsListDetails from '@/views/instances/conditions/conditions-list-details.vue';

export default {
components: { ConditionsListDetails },
props: {
conditionalBeans: {
type: Array,
default: () => [],
},
},
data() {
return {
showDetails: {},
};
},
methods: {
toggle(name) {
if (this.showDetails[name]) {
this.showDetails = {
...this.showDetails,
[name]: null,
};
} else {
this.showDetails = {
...this.showDetails,
[name]: true,
};
}
},
},
};
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"instances": {
"conditions": {
"label": "Bedingungen",
"positive-matches": "Übereinstimmungen",
"negative-matches": "Keine Übereinstimmungen",
"condition": "Bedingung",
"message": "Hinweis",
"not-matched": "Nicht übereinstimmend",
"matched": "Übereinstimmend"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"instances": {
"conditions": {
"label": "Conditions",
"positive-matches": "Positive matches",
"negative-matches": "Negative matches",
"condition": "Condition",
"message": "Message",
"not-matched": "Not matched",
"matched": "Matched"
}
}
}
Loading

0 comments on commit fdf2a98

Please sign in to comment.