Skip to content

Commit c947a6d

Browse files
akucharskagrego952
andauthored
feat: Condition list highlights (#3608)
* Add highlights in Conditions List * Add helper for badge type * Unknown badge should be type: Information * Add documentation * Remove hpa changes * Apply suggestions from code review Co-authored-by: Grzegorz Karaluch <grzegorz.karaluch@sap.com> * Format docs --------- Co-authored-by: Grzegorz Karaluch <grzegorz.karaluch@sap.com>
1 parent e8602a9 commit c947a6d

File tree

7 files changed

+123
-47
lines changed

7 files changed

+123
-47
lines changed

docs/extensibility/50-list-and-details-widgets.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,34 @@ This is an exaple of kind only:
9797

9898
The `ConditionList` widget renders the conditions as an expandable list with condition details. This widget is primarily designed for the overview section **data.details.status** or **data.details.status.body**
9999

100-
See the following example:
100+
| Parameter | Required | Type | Description |
101+
| -------------- | -------- | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
102+
| **highlights** | No | | A map of highlight rules that will only be applied to the `condition` matching `type`. Key refers to the type of highlight, while the rule can be a plain array of values ​​or a string containing the [JSONata](100-jsonata.md) rule. Allowed keys are `informative`, `positive`, `warning`, `critical`, and `type`. <br><br> With the `type` key (required), you can specify which condition the highlighting must be applied to. It must contain one of the `types` of the source condition. <br><br> If no highlighting is provided, the following values ​​are automatically supported: <br> - rendered as informational: `Unknown`. <br> - rendered as positive: `True`. <br> - rendered as critical: `False`. |
103+
104+
See the following example of the standard `ConditionList`:
105+
106+
```yaml
107+
status:
108+
- name: Condition details
109+
widget: ConditionList
110+
source: status.conditions
111+
```
112+
113+
This is an example of `ConditionList` with overriden statuses:
101114

102115
```yaml
103116
status:
104117
- name: Condition details
105118
widget: ConditionList
106119
source: status.conditions
120+
highlights:
121+
- type: ScalingActive
122+
positive:
123+
- 'False'
124+
negative:
125+
- 'True'
126+
informative:
127+
- unknown
107128
```
108129

109130
<img src="./assets/display-widgets/ConditionList.png" alt="Example of a condition list widget" style="border: 1px solid #D2D5D9">

kyma/extensions/discovery-and-network/horizontal-pod-autoscalers.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ data:
2121
networkFlowLevel: -1
2222
dataSources:
2323
- source: relatedDeployments
24-
header:
24+
header:
2525
- name: Status
2626
source: $filter(status.conditions, function($v, $i, $a) {$v.status = 'True'}).type
2727
widget: Labels

src/components/Extensibility/components/Badge.js

Lines changed: 5 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,11 @@ import { StatusBadge } from 'shared/components/StatusBadge/StatusBadge';
66
import {
77
useGetPlaceholder,
88
useGetTranslation,
9+
getBadgeType,
910
} from 'components/Extensibility/helpers';
1011

1112
import './Badge.scss';
1213

13-
const TYPE_FALLBACK = new Map([
14-
['success', 'Success'],
15-
['warning', 'Warning'],
16-
['error', 'Error'],
17-
['info', 'Information'],
18-
]);
19-
2014
export function Badge({
2115
value,
2216
structure,
@@ -40,36 +34,7 @@ export function Badge({
4034

4135
const [tooltip, tooltipError] = jsonata(structure?.description);
4236

43-
let type = null;
44-
if (structure?.highlights) {
45-
const match = Object.entries(structure.highlights).find(([key, rule]) => {
46-
if (Array.isArray(rule)) {
47-
return rule.includes(value);
48-
} else {
49-
const [doesMatch, matchError] = jsonata(rule);
50-
if (matchError) {
51-
console.error(
52-
t('extensibility.configuration-error', {
53-
error: matchError.message,
54-
}),
55-
);
56-
return false;
57-
}
58-
return doesMatch;
59-
}
60-
});
61-
if (match) {
62-
type = match[0];
63-
}
64-
}
65-
66-
if (type === 'negative') type = 'Warning';
67-
else if (type === 'informative') type = 'Information';
68-
else if (type === 'positive') type = 'Success';
69-
else if (type === 'critical') type = 'Error';
70-
else if (type === 'none') type = 'None';
71-
72-
type = TYPE_FALLBACK.get(type) || type;
37+
const badgeType = getBadgeType(structure.highlights, value, jsonata, t);
7338

7439
const getTooltipContent = description => {
7540
if (tooltip && !tooltipError) {
@@ -85,14 +50,14 @@ export function Badge({
8550
emptyLeafPlaceholder
8651
) : structure?.description ? (
8752
<StatusBadge
88-
autoResolveType={!type}
89-
type={type}
53+
autoResolveType={!badgeType}
54+
type={badgeType}
9055
tooltipContent={getTooltipContent(structure.description)}
9156
>
9257
{tExt(value)}
9358
</StatusBadge>
9459
) : (
95-
<StatusBadge autoResolveType={!type} type={type}>
60+
<StatusBadge autoResolveType={!badgeType} type={badgeType}>
9661
{tExt(value)}
9762
</StatusBadge>
9863
);

src/components/Extensibility/components/ConditionList.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,41 @@
11
import { ConditionList as ConditionListComponent } from 'shared/components/ConditionList/ConditionList';
2+
import { useJsonata } from '../hooks/useJsonata';
3+
import { useTranslation } from 'react-i18next';
4+
import { getBadgeType } from 'components/Extensibility/helpers';
5+
6+
export const ConditionList = ({
7+
value,
8+
structure,
9+
originalResource,
10+
scope,
11+
arrayItems,
12+
singleRootResource,
13+
embedResource,
14+
}) => {
15+
const { t } = useTranslation();
16+
const jsonata = useJsonata({
17+
resource: originalResource,
18+
parent: singleRootResource,
19+
embedResource: embedResource,
20+
scope,
21+
value,
22+
arrayItems,
23+
});
224

3-
export const ConditionList = ({ value }) => {
425
if (!Array.isArray(value) || value?.length === 0) {
526
return null;
627
}
728

829
const conditions = value.map(v => {
30+
const override = structure?.highlights?.find(o => o.type === v.type);
31+
const badgeType = override
32+
? getBadgeType(override, v.status, jsonata, t)
33+
: undefined;
934
return {
1035
header: {
1136
status: v.status,
1237
titleText: v.type,
38+
overrideStatusType: badgeType,
1339
},
1440
message: v.message,
1541
};

src/components/Extensibility/helpers/index.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,3 +267,48 @@ export const getTextSearchProperties = ({
267267
...searchingFunctions(searchOptions, originalResource),
268268
];
269269
};
270+
271+
const TYPE_FALLBACK = new Map([
272+
['success', 'Success'],
273+
['warning', 'Warning'],
274+
['error', 'Error'],
275+
['info', 'Information'],
276+
]);
277+
278+
export const getBadgeType = (highlights, value, jsonata, t) => {
279+
let type = null;
280+
if (highlights) {
281+
const match = Object.entries(highlights).find(([key, rule]) => {
282+
if (key === 'type') {
283+
return null;
284+
}
285+
if (Array.isArray(rule)) {
286+
return rule.includes(value);
287+
} else {
288+
const [doesMatch, matchError] = jsonata(rule);
289+
if (matchError) {
290+
console.error(
291+
t('extensibility.configuration-error', {
292+
error: matchError.message,
293+
}),
294+
);
295+
return false;
296+
}
297+
return doesMatch;
298+
}
299+
});
300+
if (match) {
301+
type = match[0];
302+
}
303+
}
304+
305+
if (type === 'negative') type = 'Warning';
306+
else if (type === 'informative') type = 'Information';
307+
else if (type === 'positive') type = 'Success';
308+
else if (type === 'critical') type = 'Error';
309+
else if (type === 'none') type = 'None';
310+
311+
type = TYPE_FALLBACK.get(type) || type;
312+
313+
return type;
314+
};

src/resources/Deployments/DeploymentDetails.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,16 @@ export function DeploymentDetails(props) {
6363

6464
const statusConditions = deployment => {
6565
return deployment?.status?.conditions?.map(condition => {
66+
const overridenStatus = () => {
67+
if (condition.type === 'ReplicaFailure')
68+
return condition.status === 'True' ? 'Error' : 'Success';
69+
return undefined;
70+
};
6671
return {
6772
header: {
6873
titleText: condition.type,
6974
status: condition.status,
70-
overrideStatusType:
71-
condition.type === 'ReplicaFailure' ? 'False' : condition.status,
75+
overrideStatusType: overridenStatus(),
7276
},
7377
message: condition.message,
7478
};

src/shared/components/ExpandableListItem/ExpandableListItem.tsx

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,24 @@ export const ExpandableListItem = ({
2929
const { t } = useTranslation();
3030
const [expanded, setExpanded] = useState(false);
3131

32-
let statusType = status === 'True' ? 'Success' : 'Error';
32+
let statusType;
33+
switch (status) {
34+
case 'True':
35+
statusType = 'Success';
36+
break;
37+
case 'False':
38+
statusType = 'Error';
39+
break;
40+
case 'Unknown':
41+
statusType = 'Information';
42+
break;
43+
default:
44+
statusType = 'None';
45+
break;
46+
}
47+
3348
if (overrideStatusType !== undefined) {
34-
statusType = overrideStatusType === 'True' ? 'Success' : 'Error';
49+
statusType = overrideStatusType;
3550
}
3651

3752
return (

0 commit comments

Comments
 (0)