@@ -20,7 +20,7 @@ use crate::{
2020 handlers:: http:: rbac:: RBACError ,
2121 parseable:: PARSEABLE ,
2222 storage:: { object_storage:: dashboard_path, ObjectStorageError } ,
23- users:: dashboards:: { Dashboard , CURRENT_DASHBOARD_VERSION , DASHBOARDS } ,
23+ users:: dashboards:: { Dashboard , Tile , CURRENT_DASHBOARD_VERSION , DASHBOARDS } ,
2424 utils:: { get_hash, get_user_from_request} ,
2525} ;
2626use actix_web:: {
@@ -30,13 +30,33 @@ use actix_web::{
3030} ;
3131use bytes:: Bytes ;
3232
33+ use chrono:: Utc ;
3334use http:: StatusCode ;
34- use serde_json:: Error as SerdeError ;
35+ use serde_json:: { Error as SerdeError , Map } ;
3536use ulid:: Ulid ;
3637
3738pub async fn list ( ) -> Result < impl Responder , DashboardError > {
3839 let dashboards = DASHBOARDS . list_dashboards ( ) . await ;
39-
40+ //dashboards list should contain the title, author and modified date
41+ let dashboards: Vec < Map < String , serde_json:: Value > > = dashboards
42+ . iter ( )
43+ . map ( |dashboard| {
44+ let mut map = Map :: new ( ) ;
45+ map. insert (
46+ "title" . to_string ( ) ,
47+ serde_json:: Value :: String ( dashboard. title . clone ( ) ) ,
48+ ) ;
49+ map. insert (
50+ "author" . to_string ( ) ,
51+ serde_json:: Value :: String ( dashboard. author . clone ( ) ) ,
52+ ) ;
53+ map. insert (
54+ "modified" . to_string ( ) ,
55+ serde_json:: Value :: String ( dashboard. modified . unwrap ( ) . to_string ( ) ) ,
56+ ) ;
57+ map
58+ } )
59+ . collect ( ) ;
4060 Ok ( ( web:: Json ( dashboards) , StatusCode :: OK ) )
4161}
4262
@@ -63,7 +83,7 @@ pub async fn post(
6383 let dashboard_id = Ulid :: new ( ) ;
6484 dashboard. dashboard_id = dashboard_id;
6585 dashboard. version = Some ( CURRENT_DASHBOARD_VERSION . to_string ( ) ) ;
66-
86+ dashboard . modified = Some ( Utc :: now ( ) ) ;
6787 dashboard. author = user_id. clone ( ) ;
6888 for tile in dashboard. tiles . iter_mut ( ) {
6989 tile. tile_id = Ulid :: new ( ) ;
@@ -99,6 +119,7 @@ pub async fn update(
99119 }
100120 dashboard. dashboard_id = dashboard_id;
101121 dashboard. author = user_id. clone ( ) ;
122+ dashboard. modified = Some ( Utc :: now ( ) ) ;
102123 dashboard. version = Some ( CURRENT_DASHBOARD_VERSION . to_string ( ) ) ;
103124 for tile in dashboard. tiles . iter_mut ( ) {
104125 if tile. tile_id . is_nil ( ) {
@@ -141,6 +162,42 @@ pub async fn delete(
141162 Ok ( HttpResponse :: Ok ( ) . finish ( ) )
142163}
143164
165+ pub async fn add_tile (
166+ req : HttpRequest ,
167+ dashboard_id : Path < String > ,
168+ Json ( mut tile) : Json < Tile > ,
169+ ) -> Result < impl Responder , DashboardError > {
170+ let mut user_id = get_user_from_request ( & req) ?;
171+ user_id = get_hash ( & user_id) ;
172+ let dashboard_id = if let Ok ( dashboard_id) = Ulid :: from_string ( & dashboard_id. into_inner ( ) ) {
173+ dashboard_id
174+ } else {
175+ return Err ( DashboardError :: Metadata ( "Invalid dashboard ID" ) ) ;
176+ } ;
177+
178+ let mut dashboard = DASHBOARDS
179+ . get_dashboard ( dashboard_id)
180+ . await
181+ . ok_or ( DashboardError :: Metadata ( "Dashboard does not exist" ) ) ?;
182+ if tile. tile_id . is_nil ( ) {
183+ tile. tile_id = Ulid :: new ( ) ;
184+ }
185+ dashboard. tiles . push ( tile. clone ( ) ) ;
186+ dashboard. modified = Some ( Utc :: now ( ) ) ;
187+ dashboard. version = Some ( CURRENT_DASHBOARD_VERSION . to_string ( ) ) ;
188+ DASHBOARDS . update ( & dashboard) . await ;
189+
190+ let path = dashboard_path ( & user_id, & format ! ( "{}.json" , dashboard_id) ) ;
191+
192+ let store = PARSEABLE . storage . get_object_store ( ) ;
193+ let dashboard_bytes = serde_json:: to_vec ( & dashboard) ?;
194+ store
195+ . put_object ( & path, Bytes :: from ( dashboard_bytes) )
196+ . await ?;
197+
198+ Ok ( ( web:: Json ( dashboard) , StatusCode :: OK ) )
199+ }
200+
144201#[ derive( Debug , thiserror:: Error ) ]
145202pub enum DashboardError {
146203 #[ error( "Failed to connect to storage: {0}" ) ]
0 commit comments