Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion docs/extensibility/50-list-and-details-widgets.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,34 @@ This is an exaple of kind only:

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**

See the following example:
| Parameter | Required | Type | Description |
| -------------- | -------- | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **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`. |

See the following example of the standard `ConditionList`:

```yaml
status:
- name: Condition details
widget: ConditionList
source: status.conditions
```

This is an example of `ConditionList` with overriden statuses:

```yaml
status:
- name: Condition details
widget: ConditionList
source: status.conditions
highlights:
- type: ScalingActive
positive:
- 'False'
negative:
- 'True'
informative:
- unknown
```

<img src="./assets/display-widgets/ConditionList.png" alt="Example of a condition list widget" style="border: 1px solid #D2D5D9">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ data:
networkFlowLevel: -1
dataSources:
- source: relatedDeployments
header:
header:
- name: Status
source: $filter(status.conditions, function($v, $i, $a) {$v.status = 'True'}).type
widget: Labels
Expand Down
45 changes: 5 additions & 40 deletions src/components/Extensibility/components/Badge.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,11 @@ import { StatusBadge } from 'shared/components/StatusBadge/StatusBadge';
import {
useGetPlaceholder,
useGetTranslation,
getBadgeType,
} from 'components/Extensibility/helpers';

import './Badge.scss';

const TYPE_FALLBACK = new Map([
['success', 'Success'],
['warning', 'Warning'],
['error', 'Error'],
['info', 'Information'],
]);

export function Badge({
value,
structure,
Expand All @@ -40,36 +34,7 @@ export function Badge({

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

let type = null;
if (structure?.highlights) {
const match = Object.entries(structure.highlights).find(([key, rule]) => {
if (Array.isArray(rule)) {
return rule.includes(value);
} else {
const [doesMatch, matchError] = jsonata(rule);
if (matchError) {
console.error(
t('extensibility.configuration-error', {
error: matchError.message,
}),
);
return false;
}
return doesMatch;
}
});
if (match) {
type = match[0];
}
}

if (type === 'negative') type = 'Warning';
else if (type === 'informative') type = 'Information';
else if (type === 'positive') type = 'Success';
else if (type === 'critical') type = 'Error';
else if (type === 'none') type = 'None';

type = TYPE_FALLBACK.get(type) || type;
const badgeType = getBadgeType(structure.highlights, value, jsonata, t);

const getTooltipContent = description => {
if (tooltip && !tooltipError) {
Expand All @@ -85,14 +50,14 @@ export function Badge({
emptyLeafPlaceholder
) : structure?.description ? (
<StatusBadge
autoResolveType={!type}
type={type}
autoResolveType={!badgeType}
type={badgeType}
tooltipContent={getTooltipContent(structure.description)}
>
{tExt(value)}
</StatusBadge>
) : (
<StatusBadge autoResolveType={!type} type={type}>
<StatusBadge autoResolveType={!badgeType} type={badgeType}>
{tExt(value)}
</StatusBadge>
);
Expand Down
28 changes: 27 additions & 1 deletion src/components/Extensibility/components/ConditionList.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,41 @@
import { ConditionList as ConditionListComponent } from 'shared/components/ConditionList/ConditionList';
import { useJsonata } from '../hooks/useJsonata';
import { useTranslation } from 'react-i18next';
import { getBadgeType } from 'components/Extensibility/helpers';

export const ConditionList = ({
value,
structure,
originalResource,
scope,
arrayItems,
singleRootResource,
embedResource,
}) => {
const { t } = useTranslation();
const jsonata = useJsonata({
resource: originalResource,
parent: singleRootResource,
embedResource: embedResource,
scope,
value,
arrayItems,
});

export const ConditionList = ({ value }) => {
if (!Array.isArray(value) || value?.length === 0) {
return null;
}

const conditions = value.map(v => {
const override = structure?.highlights?.find(o => o.type === v.type);
const badgeType = override
? getBadgeType(override, v.status, jsonata, t)
: undefined;
return {
header: {
status: v.status,
titleText: v.type,
overrideStatusType: badgeType,
},
message: v.message,
};
Expand Down
45 changes: 45 additions & 0 deletions src/components/Extensibility/helpers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -267,3 +267,48 @@ export const getTextSearchProperties = ({
...searchingFunctions(searchOptions, originalResource),
];
};

const TYPE_FALLBACK = new Map([
['success', 'Success'],
['warning', 'Warning'],
['error', 'Error'],
['info', 'Information'],
]);

export const getBadgeType = (highlights, value, jsonata, t) => {
let type = null;
if (highlights) {
const match = Object.entries(highlights).find(([key, rule]) => {
if (key === 'type') {
return null;
}
if (Array.isArray(rule)) {
return rule.includes(value);
} else {
const [doesMatch, matchError] = jsonata(rule);
if (matchError) {
console.error(
t('extensibility.configuration-error', {
error: matchError.message,
}),
);
return false;
}
return doesMatch;
}
});
if (match) {
type = match[0];
}
}

if (type === 'negative') type = 'Warning';
else if (type === 'informative') type = 'Information';
else if (type === 'positive') type = 'Success';
else if (type === 'critical') type = 'Error';
else if (type === 'none') type = 'None';

type = TYPE_FALLBACK.get(type) || type;

return type;
};
8 changes: 6 additions & 2 deletions src/resources/Deployments/DeploymentDetails.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,16 @@ export function DeploymentDetails(props) {

const statusConditions = deployment => {
return deployment?.status?.conditions?.map(condition => {
const overridenStatus = () => {
if (condition.type === 'ReplicaFailure')
return condition.status === 'True' ? 'Error' : 'Success';
return undefined;
};
return {
header: {
titleText: condition.type,
status: condition.status,
overrideStatusType:
condition.type === 'ReplicaFailure' ? 'False' : condition.status,
overrideStatusType: overridenStatus(),
},
message: condition.message,
};
Expand Down
19 changes: 17 additions & 2 deletions src/shared/components/ExpandableListItem/ExpandableListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,24 @@ export const ExpandableListItem = ({
const { t } = useTranslation();
const [expanded, setExpanded] = useState(false);

let statusType = status === 'True' ? 'Success' : 'Error';
let statusType;
switch (status) {
case 'True':
statusType = 'Success';
break;
case 'False':
statusType = 'Error';
break;
case 'Unknown':
statusType = 'Information';
break;
default:
statusType = 'None';
break;
}

if (overrideStatusType !== undefined) {
statusType = overrideStatusType === 'True' ? 'Success' : 'Error';
statusType = overrideStatusType;
}

return (
Expand Down
Loading