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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ Previous changes not listed in this document can be traced using Git history.
- Added persistence of active tab in `TabList`
- Added `externalNavigate` and `refresh` actions

### Fixed

- Removed `enum` constraint on `event_type` in `EventList` to allow non-standard Kubernetes event types (e.g. `Error`)

## [1.0.26] - 2026-06-16

### Added
Expand Down
42 changes: 42 additions & 0 deletions src/examples/widgets/EventList/EventList.example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,48 @@ spec:
- resource_name
type: string
---
# Mixed event types including non-standard type
# Expected behavior: Displays three events with different event_type values — Normal (blue), Warning (orange), and Error (grey).
# Verifies that unknown event types do not cause errors and fall back to the default grey color.
kind: EventList
apiVersion: widgets.templates.krateo.io/v1beta1
metadata:
name: example-eventlist-mixed-types
namespace: krateo-system
spec:
widgetData:
events:
- global_uid: "mock-cluster-1:event-normal"
cluster_name: "mock-cluster-1"
namespace: "default"
resource_kind: "Pod"
resource_name: "nginx-pod"
event_type: "Normal"
reason: "Started"
message: "Started container nginx"
created_at: "2024-04-21T08:20:00Z"
raw: ""
- global_uid: "mock-cluster-1:event-warning"
cluster_name: "mock-cluster-1"
namespace: "default"
resource_kind: "Pod"
resource_name: "my-pod"
event_type: "Warning"
reason: "FailedScheduling"
message: "0/1 nodes are available: 1 Insufficient memory."
created_at: "2024-04-20T12:34:56Z"
raw: ""
- global_uid: "mock-cluster-1:event-error"
cluster_name: "mock-cluster-1"
namespace: "default"
resource_kind: "Deployment"
resource_name: "my-deployment"
event_type: "Error"
reason: "BackoffLimitExceeded"
message: "Job has reached the specified backoff limit"
created_at: "2024-04-22T09:15:00Z"
raw: ""
---
# Live updates via SSE
# Expected behavior: The widget connects to the provided SSE endpoint and updates in real time as new events are received.
# Use this configuration to test streaming behavior from a live backend.
Expand Down
35 changes: 31 additions & 4 deletions src/examples/widgets/EventList/EventList.menu.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ spec:
- resourceRefId: example-eventlist-empty-panel
- resourceRefId: example-eventlist-basic-panel
- resourceRefId: example-eventlist-with-prefix-panel
- resourceRefId: example-eventlist-mixed-types-panel
- resourceRefId: example-eventlist-sse-panel
resourcesRefs:
items:
Expand All @@ -57,19 +58,25 @@ spec:
name: example-eventlist-empty-panel
namespace: krateo-system
resource: panels
verb: GET
verb: GET
- id: example-eventlist-basic-panel
apiVersion: widgets.templates.krateo.io/v1beta1
name: example-eventlist-basic-panel
namespace: krateo-system
resource: panels
verb: GET
verb: GET
- id: example-eventlist-with-prefix-panel
apiVersion: widgets.templates.krateo.io/v1beta1
name: example-eventlist-with-prefix-panel
namespace: krateo-system
resource: panels
verb: GET
verb: GET
- id: example-eventlist-mixed-types-panel
apiVersion: widgets.templates.krateo.io/v1beta1
name: example-eventlist-mixed-types-panel
namespace: krateo-system
resource: panels
verb: GET
- id: example-eventlist-sse-panel
apiVersion: widgets.templates.krateo.io/v1beta1
name: example-eventlist-sse-panel
Expand Down Expand Up @@ -146,6 +153,26 @@ spec:
---
kind: Panel
apiVersion: widgets.templates.krateo.io/v1beta1
metadata:
name: example-eventlist-mixed-types-panel
namespace: krateo-system
spec:
widgetData:
actions: {}
title: 'Mixed event types (Normal, Warning, Error)'
items:
- resourceRefId: example-eventlist-mixed-types
resourcesRefs:
items:
- id: example-eventlist-mixed-types
apiVersion: widgets.templates.krateo.io/v1beta1
name: example-eventlist-mixed-types
namespace: krateo-system
resource: eventlists
verb: GET
---
kind: Panel
apiVersion: widgets.templates.krateo.io/v1beta1
metadata:
name: example-eventlist-sse-panel
namespace: krateo-system
Expand All @@ -162,4 +189,4 @@ spec:
name: example-eventlist-sse
namespace: krateo-system
resource: eventlists
verb: GET
verb: GET
56 changes: 56 additions & 0 deletions src/widgets/Button/Button.type.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,62 @@ export interface Button {
*/
size?: 'default' | 'large' | 'fullscreen' | 'custom'
}[]
/**
* actions to navigate to an external URL
*/
externalNavigate?: {
/**
* unique identifier for the action
*/
id: string
/**
* type of action to execute
*/
type: 'externalNavigate'
/**
* the external URL to navigate to; supports JQ expressions using ${ } syntax
*/
url: string
/**
* specifies where to open the URL (default: _blank)
*/
target?: '_blank' | '_self' | '_parent' | '_top'
/**
* whether user confirmation is required before navigating
*/
requireConfirmation?: boolean
loading?: {
display: boolean
}
}[]
/**
* actions to invalidate and reload cached data
*/
refresh?: {
/**
* unique identifier for the action
*/
id: string
/**
* type of action to execute
*/
type: 'refresh'
/**
* list of resourcesRefs item IDs whose widget queries should be invalidated; each ID must match an entry in resourcesRefs.items
*/
resourcesRefsIds?: string[]
/**
* list of widget kind names (e.g. Table, Panel) whose queries should be invalidated; all widgets of those kinds on the page are re-fetched
*/
widgetKinds?: string[]
/**
* whether user confirmation is required before refreshing
*/
requireConfirmation?: boolean
loading?: {
display: boolean
}
}[]
}
/**
* the background color of the button
Expand Down
3 changes: 1 addition & 2 deletions src/widgets/EventList/EventList.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@
},
"event_type": {
"type": "string",
"enum": ["Normal", "Warning"],
"description": "type of the event, e.g., normal or warning"
"description": "type of the event, e.g., Normal, Warning, or Error"
},
"reason": {
"type": "string",
Expand Down
7 changes: 6 additions & 1 deletion src/widgets/EventList/EventList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,11 @@ const EventList = ({ uid, widgetData }: WidgetProps<EventListWidgetData>) => {
return <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
}

const eventTypeColor: Record<string, string> = {
Normal: 'blue',
Warning: 'orange',
}

return (
<div className={styles.container} onScroll={handleScroll}>
{filteredEventList.map(
Expand All @@ -139,7 +144,7 @@ const EventList = ({ uid, widgetData }: WidgetProps<EventListWidgetData>) => {
resource_name: name,
}) => (
<RichRow
color={type === 'Normal' ? 'blue' : 'orange'}
color={eventTypeColor[type] ?? 'grey'}
icon={'fa-ellipsis-h'}
key={`${uid}-${rowUid}`}
primaryText={
Expand Down
56 changes: 56 additions & 0 deletions src/widgets/Form/Form.type.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,62 @@ export interface Form {
*/
size?: 'default' | 'large' | 'fullscreen' | 'custom'
}[]
/**
* actions to navigate to an external URL
*/
externalNavigate?: {
/**
* unique identifier for the action
*/
id: string
/**
* type of action to execute
*/
type: 'externalNavigate'
/**
* the external URL to navigate to; supports JQ expressions using ${ } syntax
*/
url: string
/**
* specifies where to open the URL (default: _blank)
*/
target?: '_blank' | '_self' | '_parent' | '_top'
/**
* whether user confirmation is required before navigating
*/
requireConfirmation?: boolean
loading?: {
display: boolean
}
}[]
/**
* actions to invalidate and reload cached data
*/
refresh?: {
/**
* unique identifier for the action
*/
id: string
/**
* type of action to execute
*/
type: 'refresh'
/**
* list of resourcesRefs item IDs whose widget queries should be invalidated; each ID must match an entry in resourcesRefs.items
*/
resourcesRefsIds?: string[]
/**
* list of widget kind names (e.g. Table, Panel) whose queries should be invalidated; all widgets of those kinds on the page are re-fetched
*/
widgetKinds?: string[]
/**
* whether user confirmation is required before refreshing
*/
requireConfirmation?: boolean
loading?: {
display: boolean
}
}[]
}
/**
* custom labels and icons for form buttons
Expand Down
56 changes: 56 additions & 0 deletions src/widgets/Panel/Panel.type.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,62 @@ export interface Panel {
*/
size?: 'default' | 'large' | 'fullscreen' | 'custom'
}[]
/**
* actions to navigate to an external URL
*/
externalNavigate?: {
/**
* unique identifier for the action
*/
id: string
/**
* type of action to execute
*/
type: 'externalNavigate'
/**
* the external URL to navigate to; supports JQ expressions using ${ } syntax
*/
url: string
/**
* specifies where to open the URL (default: _blank)
*/
target?: '_blank' | '_self' | '_parent' | '_top'
/**
* whether user confirmation is required before navigating
*/
requireConfirmation?: boolean
loading?: {
display: boolean
}
}[]
/**
* actions to invalidate and reload cached data
*/
refresh?: {
/**
* unique identifier for the action
*/
id: string
/**
* type of action to execute
*/
type: 'refresh'
/**
* list of resourcesRefs item IDs whose widget queries should be invalidated; each ID must match an entry in resourcesRefs.items
*/
resourcesRefsIds?: string[]
/**
* list of widget kind names (e.g. Table, Panel) whose queries should be invalidated; all widgets of those kinds on the page are re-fetched
*/
widgetKinds?: string[]
/**
* whether user confirmation is required before refreshing
*/
requireConfirmation?: boolean
loading?: {
display: boolean
}
}[]
}
/**
* the id of the action to be executed when the panel is clicked
Expand Down
Loading
Loading