init gw list ordering

This commit is contained in:
Tomas Tulka 2024-12-12 16:22:18 +01:00
parent 98f9c5fe1e
commit d8116feb88
6 changed files with 113 additions and 8 deletions

View File

@ -229,6 +229,9 @@ message ListGatewaysRequest {
// Multicast-group ID (UUID) to filter gateways on.
string multicast_group_id = 5;
// If set, the given string will be used to sort by (optional).
string order_by = 6;
}
message ListGatewaysResponse {

View File

@ -229,6 +229,9 @@ message ListGatewaysRequest {
// Multicast-group ID (UUID) to filter gateways on.
string multicast_group_id = 5;
// If set, the given string will be used to sort by (optional).
string order_by = 6;
}
message ListGatewaysResponse {

View File

@ -237,8 +237,14 @@ impl GatewayService for Gateway {
},
};
let order_by = if req.order_by.is_empty() {
None
} else {
Some(device::OrderBy::new(&req.order_by))
};
let count = gateway::get_count(&filters).await.map_err(|e| e.status())?;
let result = gateway::list(req.limit as i64, req.offset as i64, &filters)
let result = gateway::list(req.limit as i64, req.offset as i64, &filters, order_by)
.await
.map_err(|e| e.status())?;

View File

@ -235,7 +235,7 @@ impl OrderBy {
} else {
Self {
column: value.trim().into(),
modifier: String::from("asc"),
modifier: String::from("asc"),
}
}
}
@ -650,7 +650,7 @@ pub async fn list(
device::battery_level,
))
.distinct()
.into_boxed();
.into_boxed();
if let Some(application_id) = &filters.application_id {
q = q.filter(device::dsl::application_id.eq(fields::Uuid::from(application_id)));
@ -676,7 +676,7 @@ pub async fn list(
if let Some(order) = order_by {
match order.column.as_str() {
"name" if "" == order.modifier =>
"name" if "asc" == order.modifier =>
q = q.order_by(device::dsl::name),
"name" if "desc" == order.modifier =>
q = q.order_by(device::dsl::name.desc()),

View File

@ -110,6 +110,31 @@ pub struct Filters {
pub search: Option<String>,
}
#[derive(Default, Clone, Debug)]
pub struct OrderBy {
column: String,
modifier: String,
}
impl OrderBy {
pub fn new(value: &str) -> Self {
if value.contains(',') {
let i = value.find(',').expect("");
let column = value[0..i].trim().into();
let modifier = value[(i+1)..].trim().into();
Self {
column,
modifier,
}
} else {
Self {
column: value.trim().into(),
modifier: String::from("asc"),
}
}
}
}
#[derive(QueryableByName, PartialEq, Eq, Debug)]
pub struct GatewayCountsByState {
#[diesel(sql_type = diesel::sql_types::BigInt)]
@ -309,6 +334,7 @@ pub async fn list(
limit: i64,
offset: i64,
filters: &Filters,
order_by: Option<OrderBy>,
) -> Result<Vec<GatewayListItem>, Error> {
let mut q = gateway::dsl::gateway
.left_join(multicast_group_gateway::table)
@ -351,8 +377,29 @@ pub async fn list(
);
}
if let Some(order) = order_by {
match order.column.as_str() {
"name" if "asc" == order.modifier =>
q = q.order_by(gateway::dsl::name),
"name" if "desc" == order.modifier =>
q = q.order_by(gateway::dsl::name.desc()),
"gatewayId" if "asc" == order.modifier =>
q = q.order_by(gateway::dsl::gateway_id),
"gatewayId" if "desc" == order.modifier =>
q = q.order_by(gateway::dsl::gateway_id.desc()),
"lastSeenAt" if "asc" == order.modifier =>
q = q.order_by(gateway::dsl::last_seen_at)
.then_order_by(gateway::dsl::name),
"lastSeenAt" if "desc" == order.modifier =>
q = q.order_by(gateway::dsl::last_seen_at.desc())
.then_order_by(gateway::dsl::name),
_ => q = q.order_by(gateway::dsl::name)
};
} else {
q = q.order_by(gateway::dsl::name)
};
let items = q
.order_by(gateway::dsl::name)
.limit(limit)
.offset(offset)
.load(&mut get_async_db_conn().await?)
@ -522,6 +569,7 @@ pub mod test {
count: usize,
limit: i64,
offset: i64,
order: Option<OrderBy>,
}
struct RelayGatewayFilterTest<'a> {
@ -603,6 +651,7 @@ pub mod test {
count: 1,
limit: 10,
offset: 0,
order: None,
},
FilterTest {
filters: Filters {
@ -614,6 +663,7 @@ pub mod test {
count: 0,
limit: 10,
offset: 0,
order: None,
},
FilterTest {
filters: Filters {
@ -625,6 +675,7 @@ pub mod test {
count: 1,
limit: 10,
offset: 0,
order: None,
},
FilterTest {
filters: Filters {
@ -636,6 +687,7 @@ pub mod test {
count: 1,
limit: 10,
offset: 0,
order: None,
},
FilterTest {
filters: Filters {
@ -647,6 +699,7 @@ pub mod test {
count: 0,
limit: 10,
offset: 0,
order: None,
},
FilterTest {
filters: Filters {
@ -658,6 +711,7 @@ pub mod test {
count: 1,
limit: 10,
offset: 0,
order: None,
},
FilterTest {
filters: Filters {
@ -669,6 +723,43 @@ pub mod test {
count: 0,
limit: 10,
offset: 0,
order: None,
},
FilterTest {
filters: Filters {
tenant_id: None,
multicast_group_id: None,
search: None,
},
gws: vec![&gw],
count: 1,
limit: 10,
offset: 0,
order: Some(OrderBy::new("name")),
},
FilterTest {
filters: Filters {
tenant_id: None,
multicast_group_id: None,
search: None,
},
gws: vec![&gw],
count: 1,
limit: 10,
offset: 0,
order: Some(OrderBy::new("name,asc")),
},
FilterTest {
filters: Filters {
tenant_id: None,
multicast_group_id: None,
search: None,
},
gws: vec![&gw],
count: 1,
limit: 10,
offset: 0,
order: Some(OrderBy::new("name,desc")),
},
];
@ -676,7 +767,7 @@ pub mod test {
let count = get_count(&tst.filters).await.unwrap() as usize;
assert_eq!(tst.count, count);
let items = list(tst.limit, tst.offset, &tst.filters).await.unwrap();
let items = list(tst.limit, tst.offset, &tst.filters, tst.order).await.unwrap();
assert_eq!(
tst.gws
.iter()

View File

@ -71,6 +71,7 @@ function ListGateways(props: IProps) {
return format(ts, "yyyy-MM-dd HH:mm:ss");
}
},
sorter: true,
},
{
title: "Gateway ID",
@ -80,11 +81,13 @@ function ListGateways(props: IProps) {
render: (text, record) => (
<Link to={`/tenants/${props.tenant.getId()}/gateways/${record.gatewayId}`}>{text}</Link>
),
sorter: true,
},
{
title: "Name",
dataIndex: "name",
key: "name",
sorter: true,
},
{
title: "Region ID",
@ -97,7 +100,6 @@ function ListGateways(props: IProps) {
return <Link to={`/regions/${v}`}>{v}</Link>;
}
}
return "";
},
},
@ -112,7 +114,6 @@ function ListGateways(props: IProps) {
return v;
}
}
return "";
},
},
@ -152,6 +153,7 @@ function ListGateways(props: IProps) {
req.setTenantId(props.tenant.getId());
req.setLimit(limit);
req.setOffset(offset);
req.setOrderBy(orderBy || "");
GatewayStore.list(req, (resp: ListGatewaysResponse) => {
const obj = resp.toObject();