diff --git a/.generator/schemas/v1/openapi.yaml b/.generator/schemas/v1/openapi.yaml index 6ccf9dc766..3d139b2f3b 100644 --- a/.generator/schemas/v1/openapi.yaml +++ b/.generator/schemas/v1/openapi.yaml @@ -13325,6 +13325,88 @@ components: type: string x-enum-varnames: - SCATTERPLOT + ScatterplotDataProjectionDimension: + description: A single dimension mapping for a scatterplot data projection. + properties: + alias: + description: Display alias for the dimension. + type: string + column: + description: The column name from the data source. + example: duration + type: string + dimension: + $ref: "#/components/schemas/ScatterplotDimension" + number_format: + $ref: "#/components/schemas/WidgetNumberFormat" + required: + - column + - dimension + type: object + ScatterplotDataProjectionProjection: + description: The projection configuration for a scatterplot data projection request. + properties: + dimensions: + description: Dimension mappings for the scatterplot axes. + items: + $ref: "#/components/schemas/ScatterplotDataProjectionDimension" + type: array + type: + $ref: "#/components/schemas/ScatterplotDataProjectionProjectionType" + required: + - type + - dimensions + type: object + ScatterplotDataProjectionProjectionType: + description: The type of the scatterplot data projection. + enum: + - scatterplot + example: scatterplot + type: string + x-enum-varnames: + - SCATTERPLOT + ScatterplotDataProjectionQuery: + description: The query for a scatterplot data projection request. + properties: + data_source: + $ref: "#/components/schemas/FormulaAndFunctionEventsDataSource" + indexes: + description: Indexes to search. + items: + type: string + type: array + query_string: + description: The search query string. + example: "@service:web-store" + type: string + storage: + $ref: "#/components/schemas/ScatterplotDataProjectionQueryStorage" + required: + - query_string + - data_source + type: object + ScatterplotDataProjectionQueryStorage: + description: Storage tier to query. + enum: + - live + - hot + - habanero + - online_archives + - driveline + - flex_tier + - case_insensitive + - cloud_prem + example: hot + type: string + x-enum-varnames: + - LIVE + - HOT + - HABANERO + - ONLINE_ARCHIVES + - DRIVELINE + - FLEX_TIER + - CASE_INSENSITIVE + - CLOUD_PREM ScatterplotDimension: description: Dimension of the Scatterplot. enum: @@ -13340,21 +13422,47 @@ components: - RADIUS - COLOR ScatterplotTableRequest: - description: Scatterplot request containing formulas and functions. + description: |- + Scatterplot table request. Supports two modes: + - **Formulas and functions** (default): `request_type` is absent or `"table"`. Uses `queries` and `formulas`. + - **Data projection**: `request_type` is `"data_projection"`. Uses `query`, `projection`, and optionally `limit`. properties: formulas: description: List of Scatterplot formulas that operate on queries. items: $ref: "#/components/schemas/ScatterplotWidgetFormula" type: array + limit: + description: Maximum number of rows to return. Used when `request_type` is `"data_projection"`. + format: int64 + type: integer + projection: + $ref: "#/components/schemas/ScatterplotDataProjectionProjection" + description: Projection configuration for data projection mode. Used when `request_type` is `"data_projection"`. queries: description: List of queries that can be returned directly or used in formulas. items: $ref: "#/components/schemas/FormulaAndFunctionQueryDefinition" type: array + query: + $ref: "#/components/schemas/ScatterplotDataProjectionQuery" + description: Query for data projection mode. Used when `request_type` is `"data_projection"`. + request_type: + $ref: "#/components/schemas/ScatterplotTableRequestType" + description: The type of the scatterplot table request. Use `"data_projection"` for unaggregated raw data. response_format: $ref: "#/components/schemas/FormulaAndFunctionResponseFormat" type: object + ScatterplotTableRequestType: + description: The type of the scatterplot table request. + enum: + - table + - data_projection + example: data_projection + type: string + x-enum-varnames: + - TABLE + - DATA_PROJECTION ScatterplotWidgetAggregator: description: Aggregator used for the request. enum: diff --git a/examples/v1_dashboards_CreateDashboard_2342457693.rs b/examples/v1_dashboards_CreateDashboard_2342457693.rs index bb8f660ff8..177660eb00 100644 --- a/examples/v1_dashboards_CreateDashboard_2342457693.rs +++ b/examples/v1_dashboards_CreateDashboard_2342457693.rs @@ -3,6 +3,7 @@ use datadog_api_client::datadog; use datadog_api_client::datadogV1::api_dashboards::DashboardsAPI; use datadog_api_client::datadogV1::model::Dashboard; use datadog_api_client::datadogV1::model::DashboardLayoutType; +use datadog_api_client::datadogV1::model::FormulaAndFunctionEventsDataSource; use datadog_api_client::datadogV1::model::FormulaAndFunctionMetricAggregation; use datadog_api_client::datadogV1::model::FormulaAndFunctionMetricDataSource; use datadog_api_client::datadogV1::model::FormulaAndFunctionMetricQueryDefinition; @@ -11,8 +12,13 @@ use datadog_api_client::datadogV1::model::FormulaAndFunctionResponseFormat; use datadog_api_client::datadogV1::model::ScatterPlotWidgetDefinition; use datadog_api_client::datadogV1::model::ScatterPlotWidgetDefinitionRequests; use datadog_api_client::datadogV1::model::ScatterPlotWidgetDefinitionType; +use datadog_api_client::datadogV1::model::ScatterplotDataProjectionDimension; +use datadog_api_client::datadogV1::model::ScatterplotDataProjectionProjection; +use datadog_api_client::datadogV1::model::ScatterplotDataProjectionProjectionType; +use datadog_api_client::datadogV1::model::ScatterplotDataProjectionQuery; use datadog_api_client::datadogV1::model::ScatterplotDimension; use datadog_api_client::datadogV1::model::ScatterplotTableRequest; +use datadog_api_client::datadogV1::model::ScatterplotTableRequestType; use datadog_api_client::datadogV1::model::ScatterplotWidgetFormula; use datadog_api_client::datadogV1::model::Widget; use datadog_api_client::datadogV1::model::WidgetAxis; @@ -97,7 +103,60 @@ async fn main() { ), ), ), - ).layout(WidgetLayout::new(15, 47, 0, 0)) + ).layout(WidgetLayout::new(15, 47, 0, 0)), + Widget::new( + WidgetDefinition::ScatterPlotWidgetDefinition( + Box::new( + ScatterPlotWidgetDefinition::new( + ScatterPlotWidgetDefinitionRequests + ::new().table( + ScatterplotTableRequest::new() + .limit(200) + .projection( + ScatterplotDataProjectionProjection::new( + vec![ + ScatterplotDataProjectionDimension::new( + "duration".to_string(), + ScatterplotDimension::X, + ), + ScatterplotDataProjectionDimension::new( + "@resource_name".to_string(), + ScatterplotDimension::Y, + ) + ], + ScatterplotDataProjectionProjectionType::SCATTERPLOT, + ), + ) + .query( + ScatterplotDataProjectionQuery::new( + FormulaAndFunctionEventsDataSource::SPANS, + "@service:web-store".to_string(), + ), + ) + .request_type(ScatterplotTableRequestType::DATA_PROJECTION), + ), + ScatterPlotWidgetDefinitionType::SCATTERPLOT, + ) + .title("Data Projection Scatterplot".to_string()) + .title_align(WidgetTextAlign::LEFT) + .title_size("16".to_string()) + .xaxis( + WidgetAxis::new() + .include_zero(true) + .max("auto".to_string()) + .min("auto".to_string()) + .scale("linear".to_string()), + ) + .yaxis( + WidgetAxis::new() + .include_zero(true) + .max("auto".to_string()) + .min("auto".to_string()) + .scale("linear".to_string()), + ), + ), + ), + ).layout(WidgetLayout::new(15, 47, 48, 0)) ], ) .description(Some("".to_string())) diff --git a/src/datadogV1/model/mod.rs b/src/datadogV1/model/mod.rs index d07c2a7d63..8c8f2145ec 100644 --- a/src/datadogV1/model/mod.rs +++ b/src/datadogV1/model/mod.rs @@ -540,6 +540,18 @@ pub mod model_scatterplot_widget_formula; pub use self::model_scatterplot_widget_formula::ScatterplotWidgetFormula; pub mod model_scatterplot_dimension; pub use self::model_scatterplot_dimension::ScatterplotDimension; +pub mod model_scatterplot_data_projection_projection; +pub use self::model_scatterplot_data_projection_projection::ScatterplotDataProjectionProjection; +pub mod model_scatterplot_data_projection_dimension; +pub use self::model_scatterplot_data_projection_dimension::ScatterplotDataProjectionDimension; +pub mod model_scatterplot_data_projection_projection_type; +pub use self::model_scatterplot_data_projection_projection_type::ScatterplotDataProjectionProjectionType; +pub mod model_scatterplot_data_projection_query; +pub use self::model_scatterplot_data_projection_query::ScatterplotDataProjectionQuery; +pub mod model_scatterplot_data_projection_query_storage; +pub use self::model_scatterplot_data_projection_query_storage::ScatterplotDataProjectionQueryStorage; +pub mod model_scatterplot_table_request_type; +pub use self::model_scatterplot_table_request_type::ScatterplotTableRequestType; pub mod model_scatter_plot_request; pub use self::model_scatter_plot_request::ScatterPlotRequest; pub mod model_scatterplot_widget_aggregator; diff --git a/src/datadogV1/model/model_scatter_plot_widget_definition_requests.rs b/src/datadogV1/model/model_scatter_plot_widget_definition_requests.rs index f60a071d86..968f8a56bb 100644 --- a/src/datadogV1/model/model_scatter_plot_widget_definition_requests.rs +++ b/src/datadogV1/model/model_scatter_plot_widget_definition_requests.rs @@ -11,7 +11,9 @@ use std::fmt::{self, Formatter}; #[skip_serializing_none] #[derive(Clone, Debug, PartialEq, Serialize)] pub struct ScatterPlotWidgetDefinitionRequests { - /// Scatterplot request containing formulas and functions. + /// Scatterplot table request. Supports two modes: + /// - **Formulas and functions** (default): `request_type` is absent or `"table"`. Uses `queries` and `formulas`. + /// - **Data projection**: `request_type` is `"data_projection"`. Uses `query`, `projection`, and optionally `limit`. #[serde(rename = "table")] pub table: Option, /// Updated scatter plot. diff --git a/src/datadogV1/model/model_scatterplot_data_projection_dimension.rs b/src/datadogV1/model/model_scatterplot_data_projection_dimension.rs new file mode 100644 index 0000000000..f87dc1d9a3 --- /dev/null +++ b/src/datadogV1/model/model_scatterplot_data_projection_dimension.rs @@ -0,0 +1,148 @@ +// 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 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// A single dimension mapping for a scatterplot data projection. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct ScatterplotDataProjectionDimension { + /// Display alias for the dimension. + #[serde(rename = "alias")] + pub alias: Option, + /// The column name from the data source. + #[serde(rename = "column")] + pub column: String, + /// Dimension of the Scatterplot. + #[serde(rename = "dimension")] + pub dimension: crate::datadogV1::model::ScatterplotDimension, + /// Number format options for the widget. + #[serde(rename = "number_format")] + pub number_format: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl ScatterplotDataProjectionDimension { + pub fn new( + column: String, + dimension: crate::datadogV1::model::ScatterplotDimension, + ) -> ScatterplotDataProjectionDimension { + ScatterplotDataProjectionDimension { + alias: None, + column, + dimension, + number_format: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn alias(mut self, value: String) -> Self { + self.alias = Some(value); + self + } + + pub fn number_format(mut self, value: crate::datadogV1::model::WidgetNumberFormat) -> Self { + self.number_format = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for ScatterplotDataProjectionDimension { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct ScatterplotDataProjectionDimensionVisitor; + impl<'a> Visitor<'a> for ScatterplotDataProjectionDimensionVisitor { + type Value = ScatterplotDataProjectionDimension; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut alias: Option = None; + let mut column: Option = None; + let mut dimension: Option = None; + let mut number_format: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "alias" => { + if v.is_null() { + continue; + } + alias = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "column" => { + column = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "dimension" => { + dimension = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _dimension) = dimension { + match _dimension { + crate::datadogV1::model::ScatterplotDimension::UnparsedObject(_dimension) => { + _unparsed = true; + }, + _ => {} + } + } + } + "number_format" => { + if v.is_null() { + continue; + } + number_format = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let column = column.ok_or_else(|| M::Error::missing_field("column"))?; + let dimension = dimension.ok_or_else(|| M::Error::missing_field("dimension"))?; + + let content = ScatterplotDataProjectionDimension { + alias, + column, + dimension, + number_format, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(ScatterplotDataProjectionDimensionVisitor) + } +} diff --git a/src/datadogV1/model/model_scatterplot_data_projection_projection.rs b/src/datadogV1/model/model_scatterplot_data_projection_projection.rs new file mode 100644 index 0000000000..884d53f019 --- /dev/null +++ b/src/datadogV1/model/model_scatterplot_data_projection_projection.rs @@ -0,0 +1,117 @@ +// 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 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// The projection configuration for a scatterplot data projection request. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct ScatterplotDataProjectionProjection { + /// Dimension mappings for the scatterplot axes. + #[serde(rename = "dimensions")] + pub dimensions: Vec, + /// The type of the scatterplot data projection. + #[serde(rename = "type")] + pub type_: crate::datadogV1::model::ScatterplotDataProjectionProjectionType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl ScatterplotDataProjectionProjection { + pub fn new( + dimensions: Vec, + type_: crate::datadogV1::model::ScatterplotDataProjectionProjectionType, + ) -> ScatterplotDataProjectionProjection { + ScatterplotDataProjectionProjection { + dimensions, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for ScatterplotDataProjectionProjection { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct ScatterplotDataProjectionProjectionVisitor; + impl<'a> Visitor<'a> for ScatterplotDataProjectionProjectionVisitor { + type Value = ScatterplotDataProjectionProjection; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut dimensions: Option< + Vec, + > = None; + let mut type_: Option< + crate::datadogV1::model::ScatterplotDataProjectionProjectionType, + > = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "dimensions" => { + dimensions = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "type" => { + type_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _type_) = type_ { + match _type_ { + crate::datadogV1::model::ScatterplotDataProjectionProjectionType::UnparsedObject(_type_) => { + _unparsed = true; + }, + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let dimensions = dimensions.ok_or_else(|| M::Error::missing_field("dimensions"))?; + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = ScatterplotDataProjectionProjection { + dimensions, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(ScatterplotDataProjectionProjectionVisitor) + } +} diff --git a/src/datadogV1/model/model_scatterplot_data_projection_projection_type.rs b/src/datadogV1/model/model_scatterplot_data_projection_projection_type.rs new file mode 100644 index 0000000000..0e4856a66f --- /dev/null +++ b/src/datadogV1/model/model_scatterplot_data_projection_projection_type.rs @@ -0,0 +1,48 @@ +// 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 2019-Present Datadog, Inc. + +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +#[non_exhaustive] +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum ScatterplotDataProjectionProjectionType { + SCATTERPLOT, + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl ToString for ScatterplotDataProjectionProjectionType { + fn to_string(&self) -> String { + match self { + Self::SCATTERPLOT => String::from("scatterplot"), + Self::UnparsedObject(v) => v.value.to_string(), + } + } +} + +impl Serialize for ScatterplotDataProjectionProjectionType { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self { + Self::UnparsedObject(v) => v.serialize(serializer), + _ => serializer.serialize_str(self.to_string().as_str()), + } + } +} + +impl<'de> Deserialize<'de> for ScatterplotDataProjectionProjectionType { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = String::deserialize(deserializer)?; + Ok(match s.as_str() { + "scatterplot" => Self::SCATTERPLOT, + _ => Self::UnparsedObject(crate::datadog::UnparsedObject { + value: serde_json::Value::String(s.into()), + }), + }) + } +} diff --git a/src/datadogV1/model/model_scatterplot_data_projection_query.rs b/src/datadogV1/model/model_scatterplot_data_projection_query.rs new file mode 100644 index 0000000000..6591e787cd --- /dev/null +++ b/src/datadogV1/model/model_scatterplot_data_projection_query.rs @@ -0,0 +1,166 @@ +// 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 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// The query for a scatterplot data projection request. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct ScatterplotDataProjectionQuery { + /// Data source for event platform-based queries. + #[serde(rename = "data_source")] + pub data_source: crate::datadogV1::model::FormulaAndFunctionEventsDataSource, + /// Indexes to search. + #[serde(rename = "indexes")] + pub indexes: Option>, + /// The search query string. + #[serde(rename = "query_string")] + pub query_string: String, + /// Storage tier to query. + #[serde(rename = "storage")] + pub storage: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl ScatterplotDataProjectionQuery { + pub fn new( + data_source: crate::datadogV1::model::FormulaAndFunctionEventsDataSource, + query_string: String, + ) -> ScatterplotDataProjectionQuery { + ScatterplotDataProjectionQuery { + data_source, + indexes: None, + query_string, + storage: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn indexes(mut self, value: Vec) -> Self { + self.indexes = Some(value); + self + } + + pub fn storage( + mut self, + value: crate::datadogV1::model::ScatterplotDataProjectionQueryStorage, + ) -> Self { + self.storage = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for ScatterplotDataProjectionQuery { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct ScatterplotDataProjectionQueryVisitor; + impl<'a> Visitor<'a> for ScatterplotDataProjectionQueryVisitor { + type Value = ScatterplotDataProjectionQuery; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut data_source: Option< + crate::datadogV1::model::FormulaAndFunctionEventsDataSource, + > = None; + let mut indexes: Option> = None; + let mut query_string: Option = None; + let mut storage: Option< + crate::datadogV1::model::ScatterplotDataProjectionQueryStorage, + > = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "data_source" => { + data_source = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _data_source) = data_source { + match _data_source { + crate::datadogV1::model::FormulaAndFunctionEventsDataSource::UnparsedObject(_data_source) => { + _unparsed = true; + }, + _ => {} + } + } + } + "indexes" => { + if v.is_null() { + continue; + } + indexes = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "query_string" => { + query_string = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "storage" => { + if v.is_null() { + continue; + } + storage = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _storage) = storage { + match _storage { + crate::datadogV1::model::ScatterplotDataProjectionQueryStorage::UnparsedObject(_storage) => { + _unparsed = true; + }, + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let data_source = + data_source.ok_or_else(|| M::Error::missing_field("data_source"))?; + let query_string = + query_string.ok_or_else(|| M::Error::missing_field("query_string"))?; + + let content = ScatterplotDataProjectionQuery { + data_source, + indexes, + query_string, + storage, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(ScatterplotDataProjectionQueryVisitor) + } +} diff --git a/src/datadogV1/model/model_scatterplot_data_projection_query_storage.rs b/src/datadogV1/model/model_scatterplot_data_projection_query_storage.rs new file mode 100644 index 0000000000..9acd10a7f1 --- /dev/null +++ b/src/datadogV1/model/model_scatterplot_data_projection_query_storage.rs @@ -0,0 +1,69 @@ +// 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 2019-Present Datadog, Inc. + +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +#[non_exhaustive] +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum ScatterplotDataProjectionQueryStorage { + LIVE, + HOT, + HABANERO, + ONLINE_ARCHIVES, + DRIVELINE, + FLEX_TIER, + CASE_INSENSITIVE, + CLOUD_PREM, + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl ToString for ScatterplotDataProjectionQueryStorage { + fn to_string(&self) -> String { + match self { + Self::LIVE => String::from("live"), + Self::HOT => String::from("hot"), + Self::HABANERO => String::from("habanero"), + Self::ONLINE_ARCHIVES => String::from("online_archives"), + Self::DRIVELINE => String::from("driveline"), + Self::FLEX_TIER => String::from("flex_tier"), + Self::CASE_INSENSITIVE => String::from("case_insensitive"), + Self::CLOUD_PREM => String::from("cloud_prem"), + Self::UnparsedObject(v) => v.value.to_string(), + } + } +} + +impl Serialize for ScatterplotDataProjectionQueryStorage { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self { + Self::UnparsedObject(v) => v.serialize(serializer), + _ => serializer.serialize_str(self.to_string().as_str()), + } + } +} + +impl<'de> Deserialize<'de> for ScatterplotDataProjectionQueryStorage { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = String::deserialize(deserializer)?; + Ok(match s.as_str() { + "live" => Self::LIVE, + "hot" => Self::HOT, + "habanero" => Self::HABANERO, + "online_archives" => Self::ONLINE_ARCHIVES, + "driveline" => Self::DRIVELINE, + "flex_tier" => Self::FLEX_TIER, + "case_insensitive" => Self::CASE_INSENSITIVE, + "cloud_prem" => Self::CLOUD_PREM, + _ => Self::UnparsedObject(crate::datadog::UnparsedObject { + value: serde_json::Value::String(s.into()), + }), + }) + } +} diff --git a/src/datadogV1/model/model_scatterplot_table_request.rs b/src/datadogV1/model/model_scatterplot_table_request.rs index de82bc5255..01ced72bde 100644 --- a/src/datadogV1/model/model_scatterplot_table_request.rs +++ b/src/datadogV1/model/model_scatterplot_table_request.rs @@ -6,7 +6,9 @@ use serde::{Deserialize, Deserializer, Serialize}; use serde_with::skip_serializing_none; use std::fmt::{self, Formatter}; -/// Scatterplot request containing formulas and functions. +/// Scatterplot table request. Supports two modes: +/// - **Formulas and functions** (default): `request_type` is absent or `"table"`. Uses `queries` and `formulas`. +/// - **Data projection**: `request_type` is `"data_projection"`. Uses `query`, `projection`, and optionally `limit`. #[non_exhaustive] #[skip_serializing_none] #[derive(Clone, Debug, PartialEq, Serialize)] @@ -14,9 +16,21 @@ pub struct ScatterplotTableRequest { /// List of Scatterplot formulas that operate on queries. #[serde(rename = "formulas")] pub formulas: Option>, + /// Maximum number of rows to return. Used when `request_type` is `"data_projection"`. + #[serde(rename = "limit")] + pub limit: Option, + /// The projection configuration for a scatterplot data projection request. + #[serde(rename = "projection")] + pub projection: Option, /// List of queries that can be returned directly or used in formulas. #[serde(rename = "queries")] pub queries: Option>, + /// The query for a scatterplot data projection request. + #[serde(rename = "query")] + pub query: Option, + /// The type of the scatterplot table request. + #[serde(rename = "request_type")] + pub request_type: Option, /// Timeseries, scalar, or event list response. Event list response formats are supported by Geomap widgets. #[serde(rename = "response_format")] pub response_format: Option, @@ -31,7 +45,11 @@ impl ScatterplotTableRequest { pub fn new() -> ScatterplotTableRequest { ScatterplotTableRequest { formulas: None, + limit: None, + projection: None, queries: None, + query: None, + request_type: None, response_format: None, additional_properties: std::collections::BTreeMap::new(), _unparsed: false, @@ -46,6 +64,19 @@ impl ScatterplotTableRequest { self } + pub fn limit(mut self, value: i64) -> Self { + self.limit = Some(value); + self + } + + pub fn projection( + mut self, + value: crate::datadogV1::model::ScatterplotDataProjectionProjection, + ) -> Self { + self.projection = Some(value); + self + } + pub fn queries( mut self, value: Vec, @@ -54,6 +85,19 @@ impl ScatterplotTableRequest { self } + pub fn query(mut self, value: crate::datadogV1::model::ScatterplotDataProjectionQuery) -> Self { + self.query = Some(value); + self + } + + pub fn request_type( + mut self, + value: crate::datadogV1::model::ScatterplotTableRequestType, + ) -> Self { + self.request_type = Some(value); + self + } + pub fn response_format( mut self, value: crate::datadogV1::model::FormulaAndFunctionResponseFormat, @@ -96,9 +140,17 @@ impl<'de> Deserialize<'de> for ScatterplotTableRequest { { let mut formulas: Option> = None; + let mut limit: Option = None; + let mut projection: Option< + crate::datadogV1::model::ScatterplotDataProjectionProjection, + > = None; let mut queries: Option< Vec, > = None; + let mut query: Option = + None; + let mut request_type: Option = + None; let mut response_format: Option< crate::datadogV1::model::FormulaAndFunctionResponseFormat, > = None; @@ -116,12 +168,45 @@ impl<'de> Deserialize<'de> for ScatterplotTableRequest { } formulas = Some(serde_json::from_value(v).map_err(M::Error::custom)?); } + "limit" => { + if v.is_null() { + continue; + } + limit = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "projection" => { + if v.is_null() { + continue; + } + projection = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } "queries" => { if v.is_null() { continue; } queries = Some(serde_json::from_value(v).map_err(M::Error::custom)?); } + "query" => { + if v.is_null() { + continue; + } + query = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "request_type" => { + if v.is_null() { + continue; + } + request_type = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _request_type) = request_type { + match _request_type { + crate::datadogV1::model::ScatterplotTableRequestType::UnparsedObject(_request_type) => { + _unparsed = true; + }, + _ => {} + } + } + } "response_format" => { if v.is_null() { continue; @@ -147,7 +232,11 @@ impl<'de> Deserialize<'de> for ScatterplotTableRequest { let content = ScatterplotTableRequest { formulas, + limit, + projection, queries, + query, + request_type, response_format, additional_properties, _unparsed, diff --git a/src/datadogV1/model/model_scatterplot_table_request_type.rs b/src/datadogV1/model/model_scatterplot_table_request_type.rs new file mode 100644 index 0000000000..541e70020d --- /dev/null +++ b/src/datadogV1/model/model_scatterplot_table_request_type.rs @@ -0,0 +1,51 @@ +// 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 2019-Present Datadog, Inc. + +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +#[non_exhaustive] +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum ScatterplotTableRequestType { + TABLE, + DATA_PROJECTION, + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl ToString for ScatterplotTableRequestType { + fn to_string(&self) -> String { + match self { + Self::TABLE => String::from("table"), + Self::DATA_PROJECTION => String::from("data_projection"), + Self::UnparsedObject(v) => v.value.to_string(), + } + } +} + +impl Serialize for ScatterplotTableRequestType { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self { + Self::UnparsedObject(v) => v.serialize(serializer), + _ => serializer.serialize_str(self.to_string().as_str()), + } + } +} + +impl<'de> Deserialize<'de> for ScatterplotTableRequestType { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = String::deserialize(deserializer)?; + Ok(match s.as_str() { + "table" => Self::TABLE, + "data_projection" => Self::DATA_PROJECTION, + _ => Self::UnparsedObject(crate::datadog::UnparsedObject { + value: serde_json::Value::String(s.into()), + }), + }) + } +} diff --git a/tests/scenarios/cassettes/v1/dashboards/Create-a-new-dashboard-with-scatterplot-widget.frozen b/tests/scenarios/cassettes/v1/dashboards/Create-a-new-dashboard-with-scatterplot-widget.frozen index 2f263e05b5..f981265341 100644 --- a/tests/scenarios/cassettes/v1/dashboards/Create-a-new-dashboard-with-scatterplot-widget.frozen +++ b/tests/scenarios/cassettes/v1/dashboards/Create-a-new-dashboard-with-scatterplot-widget.frozen @@ -1 +1 @@ -2024-11-15T19:32:52.260Z \ No newline at end of file +2026-04-14T13:48:27.274Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v1/dashboards/Create-a-new-dashboard-with-scatterplot-widget.json b/tests/scenarios/cassettes/v1/dashboards/Create-a-new-dashboard-with-scatterplot-widget.json index 12c992de11..15759aedc9 100644 --- a/tests/scenarios/cassettes/v1/dashboards/Create-a-new-dashboard-with-scatterplot-widget.json +++ b/tests/scenarios/cassettes/v1/dashboards/Create-a-new-dashboard-with-scatterplot-widget.json @@ -3,7 +3,7 @@ { "request": { "body": { - "string": "{\"description\":\"\",\"layout_type\":\"free\",\"notify_list\":[],\"template_variables\":[],\"title\":\"Test-Create_a_new_dashboard_with_scatterplot_widget-1731699172\",\"widgets\":[{\"definition\":{\"color_by_groups\":[],\"requests\":{\"table\":{\"formulas\":[{\"alias\":\"\",\"dimension\":\"x\",\"formula\":\"query1\"},{\"alias\":\"\",\"dimension\":\"y\",\"formula\":\"query2\"}],\"queries\":[{\"aggregator\":\"avg\",\"data_source\":\"metrics\",\"name\":\"query1\",\"query\":\"avg:system.cpu.user{*} by {service}\"},{\"aggregator\":\"avg\",\"data_source\":\"metrics\",\"name\":\"query2\",\"query\":\"avg:system.mem.used{*} by {service}\"}],\"response_format\":\"scalar\"}},\"time\":{},\"title\":\"\",\"title_align\":\"left\",\"title_size\":\"16\",\"type\":\"scatterplot\",\"xaxis\":{\"include_zero\":true,\"max\":\"auto\",\"min\":\"auto\",\"scale\":\"linear\"},\"yaxis\":{\"include_zero\":true,\"max\":\"auto\",\"min\":\"auto\",\"scale\":\"linear\"}},\"layout\":{\"height\":15,\"width\":47,\"x\":0,\"y\":0}}]}", + "string": "{\"description\":\"\",\"layout_type\":\"free\",\"notify_list\":[],\"template_variables\":[],\"title\":\"Test-Create_a_new_dashboard_with_scatterplot_widget-1776174507\",\"widgets\":[{\"definition\":{\"color_by_groups\":[],\"requests\":{\"table\":{\"formulas\":[{\"alias\":\"\",\"dimension\":\"x\",\"formula\":\"query1\"},{\"alias\":\"\",\"dimension\":\"y\",\"formula\":\"query2\"}],\"queries\":[{\"aggregator\":\"avg\",\"data_source\":\"metrics\",\"name\":\"query1\",\"query\":\"avg:system.cpu.user{*} by {service}\"},{\"aggregator\":\"avg\",\"data_source\":\"metrics\",\"name\":\"query2\",\"query\":\"avg:system.mem.used{*} by {service}\"}],\"response_format\":\"scalar\"}},\"time\":{},\"title\":\"\",\"title_align\":\"left\",\"title_size\":\"16\",\"type\":\"scatterplot\",\"xaxis\":{\"include_zero\":true,\"max\":\"auto\",\"min\":\"auto\",\"scale\":\"linear\"},\"yaxis\":{\"include_zero\":true,\"max\":\"auto\",\"min\":\"auto\",\"scale\":\"linear\"}},\"layout\":{\"height\":15,\"width\":47,\"x\":0,\"y\":0}},{\"definition\":{\"requests\":{\"table\":{\"limit\":200,\"projection\":{\"dimensions\":[{\"column\":\"duration\",\"dimension\":\"x\"},{\"column\":\"@resource_name\",\"dimension\":\"y\"}],\"type\":\"scatterplot\"},\"query\":{\"data_source\":\"spans\",\"query_string\":\"@service:web-store\"},\"request_type\":\"data_projection\"}},\"title\":\"Data Projection Scatterplot\",\"title_align\":\"left\",\"title_size\":\"16\",\"type\":\"scatterplot\",\"xaxis\":{\"include_zero\":true,\"max\":\"auto\",\"min\":\"auto\",\"scale\":\"linear\"},\"yaxis\":{\"include_zero\":true,\"max\":\"auto\",\"min\":\"auto\",\"scale\":\"linear\"}},\"layout\":{\"height\":15,\"width\":47,\"x\":48,\"y\":0}}]}", "encoding": null }, "headers": { @@ -19,7 +19,7 @@ }, "response": { "body": { - "string": "{\"id\":\"s39-kcu-kcv\",\"title\":\"Test-Create_a_new_dashboard_with_scatterplot_widget-1731699172\",\"description\":\"\",\"author_handle\":\"frog@datadoghq.com\",\"author_name\":null,\"layout_type\":\"free\",\"url\":\"/dashboard/s39-kcu-kcv/test-createanewdashboardwithscatterplotwidget-1731699172\",\"is_read_only\":false,\"template_variables\":[],\"widgets\":[{\"definition\":{\"color_by_groups\":[],\"requests\":{\"table\":{\"formulas\":[{\"alias\":\"\",\"dimension\":\"x\",\"formula\":\"query1\"},{\"alias\":\"\",\"dimension\":\"y\",\"formula\":\"query2\"}],\"queries\":[{\"aggregator\":\"avg\",\"data_source\":\"metrics\",\"name\":\"query1\",\"query\":\"avg:system.cpu.user{*} by {service}\"},{\"aggregator\":\"avg\",\"data_source\":\"metrics\",\"name\":\"query2\",\"query\":\"avg:system.mem.used{*} by {service}\"}],\"response_format\":\"scalar\"}},\"time\":{},\"title\":\"\",\"title_align\":\"left\",\"title_size\":\"16\",\"type\":\"scatterplot\",\"xaxis\":{\"include_zero\":true,\"max\":\"auto\",\"min\":\"auto\",\"scale\":\"linear\"},\"yaxis\":{\"include_zero\":true,\"max\":\"auto\",\"min\":\"auto\",\"scale\":\"linear\"}},\"layout\":{\"height\":15,\"width\":47,\"x\":0,\"y\":0},\"id\":6421549335837738}],\"notify_list\":[],\"created_at\":\"2024-11-15T19:32:52.488297+00:00\",\"modified_at\":\"2024-11-15T19:32:52.488297+00:00\",\"restricted_roles\":[]}\n", + "string": "{\"id\":\"zdc-f9y-htv\",\"title\":\"Test-Create_a_new_dashboard_with_scatterplot_widget-1776174507\",\"description\":\"\",\"author_handle\":\"9919ec9b-ebc7-49ee-8dc8-03626e717cca\",\"author_name\":\"CI Account\",\"layout_type\":\"free\",\"url\":\"/dashboard/zdc-f9y-htv/test-createanewdashboardwithscatterplotwidget-1776174507\",\"template_variables\":[],\"widgets\":[{\"definition\":{\"color_by_groups\":[],\"requests\":{\"table\":{\"formulas\":[{\"alias\":\"\",\"dimension\":\"x\",\"formula\":\"query1\"},{\"alias\":\"\",\"dimension\":\"y\",\"formula\":\"query2\"}],\"queries\":[{\"aggregator\":\"avg\",\"data_source\":\"metrics\",\"name\":\"query1\",\"query\":\"avg:system.cpu.user{*} by {service}\"},{\"aggregator\":\"avg\",\"data_source\":\"metrics\",\"name\":\"query2\",\"query\":\"avg:system.mem.used{*} by {service}\"}],\"response_format\":\"scalar\"}},\"time\":{},\"title\":\"\",\"title_align\":\"left\",\"title_size\":\"16\",\"type\":\"scatterplot\",\"xaxis\":{\"include_zero\":true,\"max\":\"auto\",\"min\":\"auto\",\"scale\":\"linear\"},\"yaxis\":{\"include_zero\":true,\"max\":\"auto\",\"min\":\"auto\",\"scale\":\"linear\"}},\"layout\":{\"height\":15,\"width\":47,\"x\":0,\"y\":0},\"id\":6156355834526034},{\"definition\":{\"requests\":{\"table\":{\"limit\":200,\"projection\":{\"dimensions\":[{\"column\":\"duration\",\"dimension\":\"x\"},{\"column\":\"@resource_name\",\"dimension\":\"y\"}],\"type\":\"scatterplot\"},\"query\":{\"data_source\":\"spans\",\"query_string\":\"@service:web-store\"},\"request_type\":\"data_projection\"}},\"title\":\"Data Projection Scatterplot\",\"title_align\":\"left\",\"title_size\":\"16\",\"type\":\"scatterplot\",\"xaxis\":{\"include_zero\":true,\"max\":\"auto\",\"min\":\"auto\",\"scale\":\"linear\"},\"yaxis\":{\"include_zero\":true,\"max\":\"auto\",\"min\":\"auto\",\"scale\":\"linear\"}},\"layout\":{\"height\":15,\"width\":47,\"x\":48,\"y\":0},\"id\":1138848396119898}],\"notify_list\":[],\"created_at\":\"2026-04-14T13:48:27.576450+00:00\",\"modified_at\":\"2026-04-14T13:48:27.576450+00:00\",\"restricted_roles\":[]}", "encoding": null }, "headers": { @@ -32,7 +32,7 @@ "message": "OK" } }, - "recorded_at": "Fri, 15 Nov 2024 19:32:52 GMT" + "recorded_at": "Tue, 14 Apr 2026 13:48:27 GMT" }, { "request": { @@ -43,11 +43,11 @@ ] }, "method": "delete", - "uri": "https://api.datadoghq.com/api/v1/dashboard/s39-kcu-kcv" + "uri": "https://api.datadoghq.com/api/v1/dashboard/zdc-f9y-htv" }, "response": { "body": { - "string": "{\"deleted_dashboard_id\":\"s39-kcu-kcv\"}\n", + "string": "{\"deleted_dashboard_id\":\"zdc-f9y-htv\"}", "encoding": null }, "headers": { @@ -60,7 +60,7 @@ "message": "OK" } }, - "recorded_at": "Fri, 15 Nov 2024 19:32:52 GMT" + "recorded_at": "Tue, 14 Apr 2026 13:48:27 GMT" } ], "recorded_with": "VCR 6.0.0" diff --git a/tests/scenarios/features/v1/dashboards.feature b/tests/scenarios/features/v1/dashboards.feature index 2541faab2d..2707ceb720 100644 --- a/tests/scenarios/features/v1/dashboards.feature +++ b/tests/scenarios/features/v1/dashboards.feature @@ -859,6 +859,13 @@ Feature: Dashboards When the request is sent Then the response status is 200 OK And the response "widgets[0].definition.type" is equal to "scatterplot" + And the response "widgets[1].definition.type" is equal to "scatterplot" + And the response "widgets[1].definition.requests.table.request_type" is equal to "data_projection" + And the response "widgets[1].definition.requests.table.query.data_source" is equal to "spans" + And the response "widgets[1].definition.requests.table.query.query_string" is equal to "@service:web-store" + And the response "widgets[1].definition.requests.table.projection.type" is equal to "scatterplot" + And the response "widgets[1].definition.requests.table.projection.dimensions" has length 2 + And the response "widgets[1].definition.requests.table.limit" is equal to 200 @team:DataDog/dashboards-backend Scenario: Create a new dashboard with servicemap widget diff --git a/tests/scenarios/features/v1/dashboards_json_payload/scatterplot_widget.json b/tests/scenarios/features/v1/dashboards_json_payload/scatterplot_widget.json index 65bcc2ff3c..ea11963333 100644 --- a/tests/scenarios/features/v1/dashboards_json_payload/scatterplot_widget.json +++ b/tests/scenarios/features/v1/dashboards_json_payload/scatterplot_widget.json @@ -64,6 +64,55 @@ ] } + }, + { + "layout":{ + "x":48, + "y":0, + "width":47, + "height":15 + }, + "definition":{ + "title":"Data Projection Scatterplot", + "title_size":"16", + "title_align":"left", + "type":"scatterplot", + "requests":{ + "table":{ + "request_type":"data_projection", + "query":{ + "query_string":"@service:web-store", + "data_source":"spans" + }, + "projection":{ + "type":"scatterplot", + "dimensions":[ + { + "column":"duration", + "dimension":"x" + }, + { + "column":"@resource_name", + "dimension":"y" + } + ] + }, + "limit":200 + } + }, + "xaxis":{ + "scale":"linear", + "include_zero":true, + "min":"auto", + "max":"auto" + }, + "yaxis":{ + "scale":"linear", + "include_zero":true, + "min":"auto", + "max":"auto" + } + } } ], "template_variables":[