diff --git a/.generator/schemas/v1/openapi.yaml b/.generator/schemas/v1/openapi.yaml index 832230d382b..099902b4772 100644 --- a/.generator/schemas/v1/openapi.yaml +++ b/.generator/schemas/v1/openapi.yaml @@ -25954,6 +25954,8 @@ components: $ref: '#/components/schemas/WidgetLineType' line_width: $ref: '#/components/schemas/WidgetLineWidth' + order_by: + $ref: '#/components/schemas/WidgetStyleOrderBy' palette: description: Color palette to apply to the widget. type: string @@ -26016,6 +26018,19 @@ components: description: Color palette to apply to the widget. type: string type: object + WidgetStyleOrderBy: + description: 'How to order series in timeseries visualizations. + + - `tags`: Order series alphabetically by tag name (default behavior) + + - `values`: Order series by their current metric values (typically descending)' + enum: + - tags + - values + type: string + x-enum-varnames: + - TAGS + - VALUES WidgetSummaryType: description: Which summary type should be used. enum: diff --git a/cassettes/features/v1/dashboards/Create-a-new-dashboard-with-timeseries-widget-using-order-by-tags.frozen b/cassettes/features/v1/dashboards/Create-a-new-dashboard-with-timeseries-widget-using-order-by-tags.frozen new file mode 100644 index 00000000000..951919f26bd --- /dev/null +++ b/cassettes/features/v1/dashboards/Create-a-new-dashboard-with-timeseries-widget-using-order-by-tags.frozen @@ -0,0 +1 @@ +2026-01-20T23:39:22.864Z \ No newline at end of file diff --git a/cassettes/features/v1/dashboards/Create-a-new-dashboard-with-timeseries-widget-using-order-by-tags.yml b/cassettes/features/v1/dashboards/Create-a-new-dashboard-with-timeseries-widget-using-order-by-tags.yml new file mode 100644 index 00000000000..df9b55081bf --- /dev/null +++ b/cassettes/features/v1/dashboards/Create-a-new-dashboard-with-timeseries-widget-using-order-by-tags.yml @@ -0,0 +1,46 @@ +http_interactions: +- recorded_at: Tue, 20 Jan 2026 23:39:22 GMT + request: + body: + encoding: UTF-8 + string: '{"layout_type":"ordered","title":"Test-Create_a_new_dashboard_with_timeseries_widget_using_order_by_tags-1768952362 + with order_by tags","widgets":[{"definition":{"requests":[{"display_type":"line","q":"avg:system.cpu.user{*} + by {host}","style":{"order_by":"tags","palette":"dog_classic"}}],"type":"timeseries"}}]}' + headers: + Accept: + - application/json + Content-Type: + - application/json + method: POST + uri: https://api.datadoghq.com/api/v1/dashboard + response: + body: + encoding: UTF-8 + string: '{"id":"2r3-a4g-ubz","title":"Test-Create_a_new_dashboard_with_timeseries_widget_using_order_by_tags-1768952362 + with order_by tags","description":null,"author_handle":"frog@datadoghq.com","author_name":"frog","layout_type":"ordered","url":"/dashboard/2r3-a4g-ubz/test-createanewdashboardwithtimeserieswidgetusingorderbytags-1768952362-with-ord","template_variables":null,"widgets":[{"definition":{"requests":[{"display_type":"line","q":"avg:system.cpu.user{*} + by {host}","style":{"order_by":"tags","palette":"dog_classic"}}],"type":"timeseries"},"id":8704189893014651}],"notify_list":null,"created_at":"2026-01-20T23:39:22.992533+00:00","modified_at":"2026-01-20T23:39:22.992533+00:00","restricted_roles":[]}' + headers: + Content-Type: + - application/json + status: + code: 200 + message: OK +- recorded_at: Tue, 20 Jan 2026 23:39:22 GMT + request: + body: null + headers: + Accept: + - application/json + method: DELETE + uri: https://api.datadoghq.com/api/v1/dashboard/2r3-a4g-ubz + response: + body: + encoding: UTF-8 + string: '{"deleted_dashboard_id":"2r3-a4g-ubz"}' + headers: + Content-Type: + - application/json + status: + code: 200 + message: OK +recorded_with: VCR 6.0.0 diff --git a/cassettes/features/v1/dashboards/Create-a-new-dashboard-with-timeseries-widget-using-order-by-values.frozen b/cassettes/features/v1/dashboards/Create-a-new-dashboard-with-timeseries-widget-using-order-by-values.frozen new file mode 100644 index 00000000000..67f72333494 --- /dev/null +++ b/cassettes/features/v1/dashboards/Create-a-new-dashboard-with-timeseries-widget-using-order-by-values.frozen @@ -0,0 +1 @@ +2026-01-20T23:39:50.889Z \ No newline at end of file diff --git a/cassettes/features/v1/dashboards/Create-a-new-dashboard-with-timeseries-widget-using-order-by-values.yml b/cassettes/features/v1/dashboards/Create-a-new-dashboard-with-timeseries-widget-using-order-by-values.yml new file mode 100644 index 00000000000..e8f43832ef4 --- /dev/null +++ b/cassettes/features/v1/dashboards/Create-a-new-dashboard-with-timeseries-widget-using-order-by-values.yml @@ -0,0 +1,46 @@ +http_interactions: +- recorded_at: Tue, 20 Jan 2026 23:39:50 GMT + request: + body: + encoding: UTF-8 + string: '{"layout_type":"ordered","title":"Test-Create_a_new_dashboard_with_timeseries_widget_using_order_by_values-1768952390 + with order_by values","widgets":[{"definition":{"requests":[{"display_type":"line","q":"avg:system.cpu.user{*} + by {host}","style":{"order_by":"values","palette":"warm"}}],"type":"timeseries"}}]}' + headers: + Accept: + - application/json + Content-Type: + - application/json + method: POST + uri: https://api.datadoghq.com/api/v1/dashboard + response: + body: + encoding: UTF-8 + string: '{"id":"5ee-dqv-ruw","title":"Test-Create_a_new_dashboard_with_timeseries_widget_using_order_by_values-1768952390 + with order_by values","description":null,"author_handle":"frog@datadoghq.com","author_name":"frog","layout_type":"ordered","url":"/dashboard/5ee-dqv-ruw/test-createanewdashboardwithtimeserieswidgetusingorderbyvalues-1768952390-with-o","template_variables":null,"widgets":[{"definition":{"requests":[{"display_type":"line","q":"avg:system.cpu.user{*} + by {host}","style":{"order_by":"values","palette":"warm"}}],"type":"timeseries"},"id":8314193502199768}],"notify_list":null,"created_at":"2026-01-20T23:39:51.018015+00:00","modified_at":"2026-01-20T23:39:51.018015+00:00","restricted_roles":[]}' + headers: + Content-Type: + - application/json + status: + code: 200 + message: OK +- recorded_at: Tue, 20 Jan 2026 23:39:50 GMT + request: + body: null + headers: + Accept: + - application/json + method: DELETE + uri: https://api.datadoghq.com/api/v1/dashboard/5ee-dqv-ruw + response: + body: + encoding: UTF-8 + string: '{"deleted_dashboard_id":"5ee-dqv-ruw"}' + headers: + Content-Type: + - application/json + status: + code: 200 + message: OK +recorded_with: VCR 6.0.0 diff --git a/cassettes/features/v1/dashboards/Create-a-new-dashboard-with-timeseries-widget-without-order-by-for-backward-compatibility.frozen b/cassettes/features/v1/dashboards/Create-a-new-dashboard-with-timeseries-widget-without-order-by-for-backward-compatibility.frozen new file mode 100644 index 00000000000..608e803e2fa --- /dev/null +++ b/cassettes/features/v1/dashboards/Create-a-new-dashboard-with-timeseries-widget-without-order-by-for-backward-compatibility.frozen @@ -0,0 +1 @@ +2026-01-20T23:40:15.566Z \ No newline at end of file diff --git a/cassettes/features/v1/dashboards/Create-a-new-dashboard-with-timeseries-widget-without-order-by-for-backward-compatibility.yml b/cassettes/features/v1/dashboards/Create-a-new-dashboard-with-timeseries-widget-without-order-by-for-backward-compatibility.yml new file mode 100644 index 00000000000..9e7cb1d80e0 --- /dev/null +++ b/cassettes/features/v1/dashboards/Create-a-new-dashboard-with-timeseries-widget-without-order-by-for-backward-compatibility.yml @@ -0,0 +1,46 @@ +http_interactions: +- recorded_at: Tue, 20 Jan 2026 23:40:15 GMT + request: + body: + encoding: UTF-8 + string: '{"layout_type":"ordered","title":"Test-Create_a_new_dashboard_with_timeseries_widget_without_order_by_for_backward_compatibility-1768952415 + without order_by","widgets":[{"definition":{"requests":[{"display_type":"line","q":"avg:system.cpu.user{*} + by {host}","style":{"line_type":"solid","line_width":"normal","palette":"dog_classic"}}],"type":"timeseries"}}]}' + headers: + Accept: + - application/json + Content-Type: + - application/json + method: POST + uri: https://api.datadoghq.com/api/v1/dashboard + response: + body: + encoding: UTF-8 + string: '{"id":"6bg-rgq-fxc","title":"Test-Create_a_new_dashboard_with_timeseries_widget_without_order_by_for_backward_compatibility-1768952415 + without order_by","description":null,"author_handle":"frog@datadoghq.com","author_name":"frog","layout_type":"ordered","url":"/dashboard/6bg-rgq-fxc/test-createanewdashboardwithtimeserieswidgetwithoutorderbyforbackwardcompatibili","template_variables":null,"widgets":[{"definition":{"requests":[{"display_type":"line","q":"avg:system.cpu.user{*} + by {host}","style":{"line_type":"solid","line_width":"normal","palette":"dog_classic"}}],"type":"timeseries"},"id":2503785343641105}],"notify_list":null,"created_at":"2026-01-20T23:40:15.937647+00:00","modified_at":"2026-01-20T23:40:15.937647+00:00","restricted_roles":[]}' + headers: + Content-Type: + - application/json + status: + code: 200 + message: OK +- recorded_at: Tue, 20 Jan 2026 23:40:15 GMT + request: + body: null + headers: + Accept: + - application/json + method: DELETE + uri: https://api.datadoghq.com/api/v1/dashboard/6bg-rgq-fxc + response: + body: + encoding: UTF-8 + string: '{"deleted_dashboard_id":"6bg-rgq-fxc"}' + headers: + Content-Type: + - application/json + status: + code: 200 + message: OK +recorded_with: VCR 6.0.0 diff --git a/examples/v1/dashboards/CreateDashboard_1259346254.rb b/examples/v1/dashboards/CreateDashboard_1259346254.rb new file mode 100644 index 00000000000..32bb6e24ca1 --- /dev/null +++ b/examples/v1/dashboards/CreateDashboard_1259346254.rb @@ -0,0 +1,27 @@ +# Create a new dashboard with timeseries widget using order_by values + +require "datadog_api_client" +api_instance = DatadogAPIClient::V1::DashboardsAPI.new + +body = DatadogAPIClient::V1::Dashboard.new({ + layout_type: DatadogAPIClient::V1::DashboardLayoutType::ORDERED, + title: "Example-Dashboard with order_by values", + widgets: [ + DatadogAPIClient::V1::Widget.new({ + definition: DatadogAPIClient::V1::TimeseriesWidgetDefinition.new({ + type: DatadogAPIClient::V1::TimeseriesWidgetDefinitionType::TIMESERIES, + requests: [ + DatadogAPIClient::V1::TimeseriesWidgetRequest.new({ + q: "avg:system.cpu.user{*} by {host}", + style: DatadogAPIClient::V1::WidgetRequestStyle.new({ + palette: "warm", + order_by: DatadogAPIClient::V1::WidgetStyleOrderBy::VALUES, + }), + display_type: DatadogAPIClient::V1::WidgetDisplayType::LINE, + }), + ], + }), + }), + ], +}) +p api_instance.create_dashboard(body) diff --git a/examples/v1/dashboards/CreateDashboard_3631423980.rb b/examples/v1/dashboards/CreateDashboard_3631423980.rb new file mode 100644 index 00000000000..30be6a702a9 --- /dev/null +++ b/examples/v1/dashboards/CreateDashboard_3631423980.rb @@ -0,0 +1,28 @@ +# Create a new dashboard with timeseries widget without order_by for backward compatibility + +require "datadog_api_client" +api_instance = DatadogAPIClient::V1::DashboardsAPI.new + +body = DatadogAPIClient::V1::Dashboard.new({ + layout_type: DatadogAPIClient::V1::DashboardLayoutType::ORDERED, + title: "Example-Dashboard without order_by", + widgets: [ + DatadogAPIClient::V1::Widget.new({ + definition: DatadogAPIClient::V1::TimeseriesWidgetDefinition.new({ + type: DatadogAPIClient::V1::TimeseriesWidgetDefinitionType::TIMESERIES, + requests: [ + DatadogAPIClient::V1::TimeseriesWidgetRequest.new({ + q: "avg:system.cpu.user{*} by {host}", + style: DatadogAPIClient::V1::WidgetRequestStyle.new({ + palette: "dog_classic", + line_type: DatadogAPIClient::V1::WidgetLineType::SOLID, + line_width: DatadogAPIClient::V1::WidgetLineWidth::NORMAL, + }), + display_type: DatadogAPIClient::V1::WidgetDisplayType::LINE, + }), + ], + }), + }), + ], +}) +p api_instance.create_dashboard(body) diff --git a/examples/v1/dashboards/CreateDashboard_416487533.rb b/examples/v1/dashboards/CreateDashboard_416487533.rb new file mode 100644 index 00000000000..2be098d89f6 --- /dev/null +++ b/examples/v1/dashboards/CreateDashboard_416487533.rb @@ -0,0 +1,27 @@ +# Create a new dashboard with timeseries widget using order_by tags + +require "datadog_api_client" +api_instance = DatadogAPIClient::V1::DashboardsAPI.new + +body = DatadogAPIClient::V1::Dashboard.new({ + layout_type: DatadogAPIClient::V1::DashboardLayoutType::ORDERED, + title: "Example-Dashboard with order_by tags", + widgets: [ + DatadogAPIClient::V1::Widget.new({ + definition: DatadogAPIClient::V1::TimeseriesWidgetDefinition.new({ + type: DatadogAPIClient::V1::TimeseriesWidgetDefinitionType::TIMESERIES, + requests: [ + DatadogAPIClient::V1::TimeseriesWidgetRequest.new({ + q: "avg:system.cpu.user{*} by {host}", + style: DatadogAPIClient::V1::WidgetRequestStyle.new({ + palette: "dog_classic", + order_by: DatadogAPIClient::V1::WidgetStyleOrderBy::TAGS, + }), + display_type: DatadogAPIClient::V1::WidgetDisplayType::LINE, + }), + ], + }), + }), + ], +}) +p api_instance.create_dashboard(body) diff --git a/features/v1/dashboards.feature b/features/v1/dashboards.feature index 6b67bc65044..349f7de6f9d 100644 --- a/features/v1/dashboards.feature +++ b/features/v1/dashboards.feature @@ -946,6 +946,24 @@ Feature: Dashboards And the response "widgets[0].definition.requests[0].display_type" is equal to "bars" And the response "widgets[0].definition.requests[0].q" is equal to "sum:trace.test.errors{env:prod,service:datadog-api-spec} by {resource_name}.as_count()" + @team:DataDog/dashboards-backend + Scenario: Create a new dashboard with timeseries widget using order_by tags + Given new "CreateDashboard" request + And body with value {"layout_type": "ordered", "title": "{{ unique }} with order_by tags","widgets": [{"definition": {"type": "timeseries","requests": [{"q": "avg:system.cpu.user{*} by {host}","style": {"palette": "dog_classic","order_by": "tags"},"display_type": "line"}]}}]} + When the request is sent + Then the response status is 200 OK + And the response "widgets[0].definition.requests[0].style.order_by" is equal to "tags" + And the response "widgets[0].definition.requests[0].style.palette" is equal to "dog_classic" + + @team:DataDog/dashboards-backend + Scenario: Create a new dashboard with timeseries widget using order_by values + Given new "CreateDashboard" request + And body with value {"layout_type": "ordered", "title": "{{ unique }} with order_by values","widgets": [{"definition": {"type": "timeseries","requests": [{"q": "avg:system.cpu.user{*} by {host}","style": {"palette": "warm","order_by": "values"},"display_type": "line"}]}}]} + When the request is sent + Then the response status is 200 OK + And the response "widgets[0].definition.requests[0].style.order_by" is equal to "values" + And the response "widgets[0].definition.requests[0].style.palette" is equal to "warm" + @team:DataDog/dashboards-backend Scenario: Create a new dashboard with timeseries widget with custom_unit Given new "CreateDashboard" request @@ -958,6 +976,16 @@ Feature: Dashboards And the response "widgets[0].definition.requests[0].formulas[0].number_format.unit.type" is equal to "canonical_unit" And the response "widgets[0].definition.requests[0].formulas[0].number_format.unit.unit_name" is equal to "fraction" + @team:DataDog/dashboards-backend + Scenario: Create a new dashboard with timeseries widget without order_by for backward compatibility + Given new "CreateDashboard" request + And body with value {"layout_type": "ordered", "title": "{{ unique }} without order_by","widgets": [{"definition": {"type": "timeseries","requests": [{"q": "avg:system.cpu.user{*} by {host}","style": {"palette": "dog_classic","line_type": "solid","line_width": "normal"},"display_type": "line"}]}}]} + When the request is sent + Then the response status is 200 OK + And the response "widgets[0].definition.requests[0].style.palette" is equal to "dog_classic" + And the response "widgets[0].definition.requests[0].style.line_type" is equal to "solid" + And the response "widgets[0].definition.requests[0].style.line_width" is equal to "normal" + @team:DataDog/dashboards-backend Scenario: Create a new dashboard with toplist widget Given new "CreateDashboard" request diff --git a/lib/datadog_api_client/inflector.rb b/lib/datadog_api_client/inflector.rb index 0d9ba8f96c3..59605a3597a 100644 --- a/lib/datadog_api_client/inflector.rb +++ b/lib/datadog_api_client/inflector.rb @@ -971,6 +971,7 @@ def overrides "v1.widget_sort_by" => "WidgetSortBy", "v1.widget_sort_order_by" => "WidgetSortOrderBy", "v1.widget_style" => "WidgetStyle", + "v1.widget_style_order_by" => "WidgetStyleOrderBy", "v1.widget_summary_type" => "WidgetSummaryType", "v1.widget_text_align" => "WidgetTextAlign", "v1.widget_tick_edge" => "WidgetTickEdge", diff --git a/lib/datadog_api_client/v1/models/widget_request_style.rb b/lib/datadog_api_client/v1/models/widget_request_style.rb index e2fec3790c8..73aab4605ea 100644 --- a/lib/datadog_api_client/v1/models/widget_request_style.rb +++ b/lib/datadog_api_client/v1/models/widget_request_style.rb @@ -27,6 +27,11 @@ class WidgetRequestStyle # Width of line displayed. attr_accessor :line_width + # How to order series in timeseries visualizations. + # - `tags`: Order series alphabetically by tag name (default behavior) + # - `values`: Order series by their current metric values (typically descending) + attr_accessor :order_by + # Color palette to apply to the widget. attr_accessor :palette @@ -38,6 +43,7 @@ def self.attribute_map { :'line_type' => :'line_type', :'line_width' => :'line_width', + :'order_by' => :'order_by', :'palette' => :'palette' } end @@ -48,6 +54,7 @@ def self.openapi_types { :'line_type' => :'WidgetLineType', :'line_width' => :'WidgetLineWidth', + :'order_by' => :'WidgetStyleOrderBy', :'palette' => :'String' } end @@ -78,6 +85,10 @@ def initialize(attributes = {}) self.line_width = attributes[:'line_width'] end + if attributes.key?(:'order_by') + self.order_by = attributes[:'order_by'] + end + if attributes.key?(:'palette') self.palette = attributes[:'palette'] end @@ -111,6 +122,7 @@ def ==(o) self.class == o.class && line_type == o.line_type && line_width == o.line_width && + order_by == o.order_by && palette == o.palette && additional_properties == o.additional_properties end @@ -119,7 +131,7 @@ def ==(o) # @return [Integer] Hash code # @!visibility private def hash - [line_type, line_width, palette, additional_properties].hash + [line_type, line_width, order_by, palette, additional_properties].hash end end end diff --git a/lib/datadog_api_client/v1/models/widget_style_order_by.rb b/lib/datadog_api_client/v1/models/widget_style_order_by.rb new file mode 100644 index 00000000000..4a32c25f650 --- /dev/null +++ b/lib/datadog_api_client/v1/models/widget_style_order_by.rb @@ -0,0 +1,29 @@ +=begin +#Datadog API V1 Collection + +#Collection of all Datadog Public endpoints. + +The version of the OpenAPI document: 1.0 +Contact: support@datadoghq.com +Generated by: https://github.com/DataDog/datadog-api-client-ruby/tree/master/.generator + + Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. + This product includes software developed at Datadog (https://www.datadoghq.com/). + Copyright 2020-Present Datadog, Inc. + +=end + +require 'date' +require 'time' + +module DatadogAPIClient::V1 + # How to order series in timeseries visualizations. + # - `tags`: Order series alphabetically by tag name (default behavior) + # - `values`: Order series by their current metric values (typically descending) + class WidgetStyleOrderBy + include BaseEnumModel + + TAGS = "tags".freeze + VALUES = "values".freeze + end +end