fix unremoveable package bug
add update api endpoint add force update button on pkg overview
This commit is contained in:
		| @@ -1,95 +0,0 @@ | ||||
| use crate::aur::aur::get_info_by_name; | ||||
| use crate::builder::types::Action; | ||||
| use crate::db::prelude::{Packages, Versions}; | ||||
| use crate::db::{packages, versions}; | ||||
| use rocket::response::status::BadRequest; | ||||
| use rocket::serde::json::Json; | ||||
| use rocket::serde::Deserialize; | ||||
| use rocket::{post, State}; | ||||
| use rocket_okapi::okapi::schemars; | ||||
| use rocket_okapi::{openapi, JsonSchema}; | ||||
| use sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter}; | ||||
| use sea_orm::{DatabaseConnection, Set}; | ||||
| use tokio::sync::broadcast::Sender; | ||||
|  | ||||
| #[derive(Deserialize, JsonSchema)] | ||||
| #[serde(crate = "rocket::serde")] | ||||
| pub struct AddBody { | ||||
|     name: String, | ||||
|     force_build: bool, | ||||
| } | ||||
|  | ||||
| #[openapi(tag = "test")] | ||||
| #[post("/packages/add", data = "<input>")] | ||||
| pub async fn package_add( | ||||
|     db: &State<DatabaseConnection>, | ||||
|     input: Json<AddBody>, | ||||
|     tx: &State<Sender<Action>>, | ||||
| ) -> Result<(), BadRequest<String>> { | ||||
|     let db = db as &DatabaseConnection; | ||||
|  | ||||
|     // remove leading and trailing whitespaces | ||||
|     let pkg_name = input.name.trim(); | ||||
|  | ||||
|     let pkg = get_info_by_name(pkg_name) | ||||
|         .await | ||||
|         .map_err(|_| BadRequest(Some("couldn't download package metadata".to_string())))?; | ||||
|  | ||||
|     let mut pkg_model = match Packages::find() | ||||
|         .filter(packages::Column::Name.eq(pkg_name)) | ||||
|         .one(db) | ||||
|         .await | ||||
|         .map_err(|e| BadRequest(Some(e.to_string())))? | ||||
|     { | ||||
|         None => { | ||||
|             let new_package = packages::ActiveModel { | ||||
|                 name: Set(pkg_name.to_string()), | ||||
|                 status: Set(3), | ||||
|                 latest_aur_version: Set(pkg.version.clone()), | ||||
|                 ..Default::default() | ||||
|             }; | ||||
|  | ||||
|             new_package.save(db).await.expect("TODO: panic message") | ||||
|         } | ||||
|         Some(p) => p.into(), | ||||
|     }; | ||||
|  | ||||
|     let version_model = match Versions::find() | ||||
|         .filter(versions::Column::Version.eq(pkg.version.clone())) | ||||
|         .one(db) | ||||
|         .await | ||||
|         .map_err(|e| BadRequest(Some(e.to_string())))? | ||||
|     { | ||||
|         None => { | ||||
|             let new_version = versions::ActiveModel { | ||||
|                 version: Set(pkg.version.clone()), | ||||
|                 package_id: Set(pkg_model.id.clone().unwrap()), | ||||
|                 ..Default::default() | ||||
|             }; | ||||
|  | ||||
|             new_version.save(db).await.expect("TODO: panic message") | ||||
|         } | ||||
|         Some(p) => { | ||||
|             // todo add check if this version was successfully built | ||||
|             // if not allow build | ||||
|             if input.force_build { | ||||
|                 p.into() | ||||
|             } else { | ||||
|                 return Err(BadRequest(Some("Version already existing".to_string()))); | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     pkg_model.status = Set(3); | ||||
|     pkg_model.latest_version_id = Set(Some(version_model.id.clone().unwrap())); | ||||
|     pkg_model.save(db).await.expect("todo error message"); | ||||
|  | ||||
|     let _ = tx.send(Action::Build( | ||||
|         pkg.name, | ||||
|         pkg.version, | ||||
|         pkg.url_path.unwrap(), | ||||
|         version_model, | ||||
|     )); | ||||
|  | ||||
|     Ok(()) | ||||
| } | ||||
| @@ -1,16 +1,20 @@ | ||||
| use crate::api::add::okapi_add_operation_for_package_add_; | ||||
| use crate::api::add::package_add; | ||||
| use crate::api::list::build_output; | ||||
| use crate::api::list::okapi_add_operation_for_get_build_; | ||||
| use crate::api::list::okapi_add_operation_for_get_package_; | ||||
| use crate::api::list::okapi_add_operation_for_stats_; | ||||
| use crate::api::list::{build_output, okapi_add_operation_for_package_list_}; | ||||
| use crate::api::list::{get_build, get_package, okapi_add_operation_for_list_builds_}; | ||||
| use crate::api::list::search; | ||||
| use crate::api::list::{get_build, okapi_add_operation_for_list_builds_}; | ||||
| use crate::api::list::{list_builds, okapi_add_operation_for_search_}; | ||||
| use crate::api::list::{okapi_add_operation_for_build_output_, stats}; | ||||
| use crate::api::list::{package_list, search}; | ||||
| use crate::api::remove::okapi_add_operation_for_package_del_; | ||||
| use crate::api::package::okapi_add_operation_for_get_package_; | ||||
| use crate::api::package::okapi_add_operation_for_package_del_; | ||||
| use crate::api::package::okapi_add_operation_for_package_list_; | ||||
| use crate::api::package::okapi_add_operation_for_package_update_; | ||||
| use crate::api::package::package_add; | ||||
| use crate::api::package::{ | ||||
|     get_package, okapi_add_operation_for_package_add_, package_del, package_list, package_update, | ||||
| }; | ||||
| use crate::api::remove::okapi_add_operation_for_version_del_; | ||||
| use crate::api::remove::{package_del, version_del}; | ||||
| use crate::api::remove::version_del; | ||||
| use rocket::Route; | ||||
| use rocket_okapi::openapi_get_routes; | ||||
|  | ||||
| @@ -25,6 +29,7 @@ pub fn build_api() -> Vec<Route> { | ||||
|         list_builds, | ||||
|         stats, | ||||
|         get_build, | ||||
|         get_package | ||||
|         get_package, | ||||
|         package_update | ||||
|     ] | ||||
| } | ||||
|   | ||||
| @@ -50,62 +50,6 @@ pub struct ListPackageModel { | ||||
|     latest_aur_version: String, | ||||
| } | ||||
|  | ||||
| #[openapi(tag = "test")] | ||||
| #[get("/packages/list?<limit>")] | ||||
| pub async fn package_list( | ||||
|     db: &State<DatabaseConnection>, | ||||
|     limit: Option<u64>, | ||||
| ) -> Result<Json<Vec<ListPackageModel>>, NotFound<String>> { | ||||
|     let db = db as &DatabaseConnection; | ||||
|  | ||||
|     let all: Vec<ListPackageModel> = Packages::find() | ||||
|         .join_rev(JoinType::LeftJoin, versions::Relation::LatestPackage.def()) | ||||
|         .select_only() | ||||
|         .column(packages::Column::Name) | ||||
|         .column(packages::Column::Id) | ||||
|         .column(packages::Column::Status) | ||||
|         .column_as(packages::Column::OutOfDate, "outofdate") | ||||
|         .column_as(packages::Column::LatestAurVersion, "latest_aur_version") | ||||
|         .column_as(versions::Column::Version, "latest_version") | ||||
|         .column_as(packages::Column::LatestVersionId, "latest_version_id") | ||||
|         .order_by(packages::Column::Id, Order::Desc) | ||||
|         .limit(limit) | ||||
|         .into_model::<ListPackageModel>() | ||||
|         .all(db) | ||||
|         .await | ||||
|         .map_err(|e| NotFound(e.to_string()))?; | ||||
|  | ||||
|     Ok(Json(all)) | ||||
| } | ||||
|  | ||||
| #[openapi(tag = "test")] | ||||
| #[get("/package/<id>")] | ||||
| pub async fn get_package( | ||||
|     db: &State<DatabaseConnection>, | ||||
|     id: u64, | ||||
| ) -> Result<Json<ListPackageModel>, NotFound<String>> { | ||||
|     let db = db as &DatabaseConnection; | ||||
|  | ||||
|     let all: ListPackageModel = Packages::find() | ||||
|         .join_rev(JoinType::LeftJoin, versions::Relation::LatestPackage.def()) | ||||
|         .filter(packages::Column::Id.eq(id)) | ||||
|         .select_only() | ||||
|         .column(packages::Column::Name) | ||||
|         .column(packages::Column::Id) | ||||
|         .column(packages::Column::Status) | ||||
|         .column_as(packages::Column::OutOfDate, "outofdate") | ||||
|         .column_as(packages::Column::LatestAurVersion, "latest_aur_version") | ||||
|         .column_as(versions::Column::Version, "latest_version") | ||||
|         .column_as(packages::Column::LatestVersionId, "latest_version_id") | ||||
|         .into_model::<ListPackageModel>() | ||||
|         .one(db) | ||||
|         .await | ||||
|         .map_err(|e| NotFound(e.to_string()))? | ||||
|         .ok_or(NotFound("id not found".to_string()))?; | ||||
|  | ||||
|     Ok(Json(all)) | ||||
| } | ||||
|  | ||||
| #[openapi(tag = "test")] | ||||
| #[get("/builds/output?<buildid>&<startline>")] | ||||
| pub async fn build_output( | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| mod add; | ||||
| pub mod backend; | ||||
| #[cfg(feature = "static")] | ||||
| pub mod embed; | ||||
| mod list; | ||||
| mod package; | ||||
| mod remove; | ||||
|   | ||||
							
								
								
									
										225
									
								
								backend/src/api/package.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										225
									
								
								backend/src/api/package.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,225 @@ | ||||
| use crate::api::list::ListPackageModel; | ||||
| use crate::aur::aur::get_info_by_name; | ||||
| use crate::builder::types::Action; | ||||
| use crate::db::migration::{JoinType, Order}; | ||||
| use crate::db::prelude::{Packages, Versions}; | ||||
| use crate::db::{packages, versions}; | ||||
| use crate::repo::repo::remove_pkg; | ||||
| use rocket::response::status::{BadRequest, NotFound}; | ||||
| use rocket::serde::json::Json; | ||||
| use rocket::serde::Deserialize; | ||||
| use rocket::{get, post, State}; | ||||
| use rocket_okapi::okapi::schemars; | ||||
| use rocket_okapi::{openapi, JsonSchema}; | ||||
| use sea_orm::{ | ||||
|     ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter, QueryOrder, QuerySelect, RelationTrait, | ||||
| }; | ||||
| use sea_orm::{DatabaseConnection, Set}; | ||||
| use tokio::sync::broadcast::Sender; | ||||
|  | ||||
| #[derive(Deserialize, JsonSchema)] | ||||
| #[serde(crate = "rocket::serde")] | ||||
| pub struct AddBody { | ||||
|     name: String, | ||||
| } | ||||
|  | ||||
| #[openapi(tag = "Packages")] | ||||
| #[post("/packages/add", data = "<input>")] | ||||
| pub async fn package_add( | ||||
|     db: &State<DatabaseConnection>, | ||||
|     input: Json<AddBody>, | ||||
|     tx: &State<Sender<Action>>, | ||||
| ) -> Result<(), BadRequest<String>> { | ||||
|     let db = db as &DatabaseConnection; | ||||
|  | ||||
|     // remove leading and trailing whitespaces | ||||
|     let pkg_name = input.name.trim(); | ||||
|  | ||||
|     let pkg = get_info_by_name(pkg_name) | ||||
|         .await | ||||
|         .map_err(|_| BadRequest(Some("couldn't download package metadata".to_string())))?; | ||||
|  | ||||
|     if let None = Packages::find() | ||||
|         .filter(packages::Column::Name.eq(pkg_name)) | ||||
|         .one(db) | ||||
|         .await | ||||
|         .map_err(|e| BadRequest(Some(e.to_string())))? | ||||
|     { | ||||
|         return Err(BadRequest(Some("Package already exists".to_string()))); | ||||
|     } | ||||
|  | ||||
|     let mut new_package = packages::ActiveModel { | ||||
|         name: Set(pkg_name.to_string()), | ||||
|         status: Set(3), | ||||
|         latest_aur_version: Set(pkg.version.clone()), | ||||
|         ..Default::default() | ||||
|     }; | ||||
|  | ||||
|     new_package | ||||
|         .clone() | ||||
|         .save(db) | ||||
|         .await | ||||
|         .map_err(|e| BadRequest(Some(e.to_string())))?; | ||||
|  | ||||
|     let new_version = versions::ActiveModel { | ||||
|         version: Set(pkg.version.clone()), | ||||
|         package_id: Set(new_package.id.clone().unwrap()), | ||||
|         ..Default::default() | ||||
|     }; | ||||
|  | ||||
|     new_version | ||||
|         .clone() | ||||
|         .save(db) | ||||
|         .await | ||||
|         .map_err(|e| BadRequest(Some(e.to_string())))?; | ||||
|  | ||||
|     new_package.status = Set(3); | ||||
|     new_package.latest_version_id = Set(Some(new_version.id.clone().unwrap())); | ||||
|     new_package | ||||
|         .save(db) | ||||
|         .await | ||||
|         .map_err(|e| BadRequest(Some(e.to_string())))?; | ||||
|  | ||||
|     let _ = tx.send(Action::Build( | ||||
|         pkg.name, | ||||
|         pkg.version, | ||||
|         pkg.url_path.unwrap(), | ||||
|         new_version, | ||||
|     )); | ||||
|  | ||||
|     Ok(()) | ||||
| } | ||||
|  | ||||
| #[derive(Deserialize, JsonSchema)] | ||||
| #[serde(crate = "rocket::serde")] | ||||
| pub struct UpdateBody { | ||||
|     force: bool, | ||||
| } | ||||
|  | ||||
| #[openapi(tag = "Packages")] | ||||
| #[post("/packages/<id>/update", data = "<input>")] | ||||
| pub async fn package_update( | ||||
|     db: &State<DatabaseConnection>, | ||||
|     id: i32, | ||||
|     input: Json<UpdateBody>, | ||||
|     tx: &State<Sender<Action>>, | ||||
| ) -> Result<(), BadRequest<String>> { | ||||
|     let db = db as &DatabaseConnection; | ||||
|  | ||||
|     let mut pkg_model: packages::ActiveModel = Packages::find_by_id(id) | ||||
|         .one(db) | ||||
|         .await | ||||
|         .map_err(|e| BadRequest(Some(e.to_string())))? | ||||
|         .ok_or(BadRequest(Some("id not found".to_string())))? | ||||
|         .into(); | ||||
|  | ||||
|     let pkg = get_info_by_name(pkg_model.name.clone().unwrap().as_str()) | ||||
|         .await | ||||
|         .map_err(|_| BadRequest(Some("couldn't download package metadata".to_string())))?; | ||||
|  | ||||
|     let version_model = match Versions::find() | ||||
|         .filter(versions::Column::Version.eq(pkg.version.clone())) | ||||
|         .filter(versions::Column::PackageId.eq(pkg.id.clone())) | ||||
|         .one(db) | ||||
|         .await | ||||
|         .map_err(|e| BadRequest(Some(e.to_string())))? | ||||
|     { | ||||
|         None => { | ||||
|             let new_version = versions::ActiveModel { | ||||
|                 version: Set(pkg.version.clone()), | ||||
|                 package_id: Set(pkg_model.id.clone().unwrap()), | ||||
|                 ..Default::default() | ||||
|             }; | ||||
|  | ||||
|             new_version.save(db).await.expect("TODO: panic message") | ||||
|         } | ||||
|         Some(p) => { | ||||
|             // todo add check if this version was successfully built | ||||
|             // if not allow build | ||||
|             if input.force { | ||||
|                 p.into() | ||||
|             } else { | ||||
|                 return Err(BadRequest(Some("Version already existing".to_string()))); | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     pkg_model.status = Set(3); | ||||
|     pkg_model.latest_version_id = Set(Some(version_model.id.clone().unwrap())); | ||||
|     pkg_model.save(db).await.expect("todo error message"); | ||||
|  | ||||
|     let _ = tx.send(Action::Build( | ||||
|         pkg.name, | ||||
|         pkg.version, | ||||
|         pkg.url_path.unwrap(), | ||||
|         version_model, | ||||
|     )); | ||||
|  | ||||
|     Ok(()) | ||||
| } | ||||
|  | ||||
| #[openapi(tag = "Packages")] | ||||
| #[post("/package/delete/<id>")] | ||||
| pub async fn package_del(db: &State<DatabaseConnection>, id: i32) -> Result<(), String> { | ||||
|     let db = db as &DatabaseConnection; | ||||
|  | ||||
|     remove_pkg(db, id).await.map_err(|e| e.to_string())?; | ||||
|  | ||||
|     Ok(()) | ||||
| } | ||||
|  | ||||
| #[openapi(tag = "Packages")] | ||||
| #[get("/packages/list?<limit>")] | ||||
| pub async fn package_list( | ||||
|     db: &State<DatabaseConnection>, | ||||
|     limit: Option<u64>, | ||||
| ) -> Result<Json<Vec<ListPackageModel>>, NotFound<String>> { | ||||
|     let db = db as &DatabaseConnection; | ||||
|  | ||||
|     let all: Vec<ListPackageModel> = Packages::find() | ||||
|         .join_rev(JoinType::LeftJoin, versions::Relation::LatestPackage.def()) | ||||
|         .select_only() | ||||
|         .column(packages::Column::Name) | ||||
|         .column(packages::Column::Id) | ||||
|         .column(packages::Column::Status) | ||||
|         .column_as(packages::Column::OutOfDate, "outofdate") | ||||
|         .column_as(packages::Column::LatestAurVersion, "latest_aur_version") | ||||
|         .column_as(versions::Column::Version, "latest_version") | ||||
|         .column_as(packages::Column::LatestVersionId, "latest_version_id") | ||||
|         .order_by(packages::Column::Id, Order::Desc) | ||||
|         .limit(limit) | ||||
|         .into_model::<ListPackageModel>() | ||||
|         .all(db) | ||||
|         .await | ||||
|         .map_err(|e| NotFound(e.to_string()))?; | ||||
|  | ||||
|     Ok(Json(all)) | ||||
| } | ||||
|  | ||||
| #[openapi(tag = "Packages")] | ||||
| #[get("/package/<id>")] | ||||
| pub async fn get_package( | ||||
|     db: &State<DatabaseConnection>, | ||||
|     id: u64, | ||||
| ) -> Result<Json<ListPackageModel>, NotFound<String>> { | ||||
|     let db = db as &DatabaseConnection; | ||||
|  | ||||
|     let all: ListPackageModel = Packages::find() | ||||
|         .join_rev(JoinType::LeftJoin, versions::Relation::LatestPackage.def()) | ||||
|         .filter(packages::Column::Id.eq(id)) | ||||
|         .select_only() | ||||
|         .column(packages::Column::Name) | ||||
|         .column(packages::Column::Id) | ||||
|         .column(packages::Column::Status) | ||||
|         .column_as(packages::Column::OutOfDate, "outofdate") | ||||
|         .column_as(packages::Column::LatestAurVersion, "latest_aur_version") | ||||
|         .column_as(versions::Column::Version, "latest_version") | ||||
|         .column_as(packages::Column::LatestVersionId, "latest_version_id") | ||||
|         .into_model::<ListPackageModel>() | ||||
|         .one(db) | ||||
|         .await | ||||
|         .map_err(|e| NotFound(e.to_string()))? | ||||
|         .ok_or(NotFound("id not found".to_string()))?; | ||||
|  | ||||
|     Ok(Json(all)) | ||||
| } | ||||
| @@ -3,16 +3,6 @@ use rocket::{post, State}; | ||||
| use rocket_okapi::openapi; | ||||
| use sea_orm::DatabaseConnection; | ||||
|  | ||||
| #[openapi(tag = "test")] | ||||
| #[post("/package/delete/<id>")] | ||||
| pub async fn package_del(db: &State<DatabaseConnection>, id: i32) -> Result<(), String> { | ||||
|     let db = db as &DatabaseConnection; | ||||
|  | ||||
|     remove_pkg(db, id).await.map_err(|e| e.to_string())?; | ||||
|  | ||||
|     Ok(()) | ||||
| } | ||||
|  | ||||
| #[openapi(tag = "test")] | ||||
| #[post("/versions/delete/<id>")] | ||||
| pub async fn version_del(db: &State<DatabaseConnection>, id: i32) -> Result<(), String> { | ||||
|   | ||||
| @@ -4,7 +4,10 @@ use crate::db::prelude::{Builds, Packages}; | ||||
| use crate::db::{builds, versions}; | ||||
| use crate::pkgbuild::build::build_pkgbuild; | ||||
| use anyhow::anyhow; | ||||
| use sea_orm::{ColumnTrait, DatabaseConnection, EntityTrait, ModelTrait, QueryFilter}; | ||||
| use sea_orm::{ | ||||
|     ColumnTrait, DatabaseConnection, DatabaseTransaction, EntityTrait, ModelTrait, QueryFilter, | ||||
|     TransactionTrait, | ||||
| }; | ||||
| use std::fs; | ||||
| use std::process::Command; | ||||
| use tokio::sync::broadcast::Sender; | ||||
| @@ -46,46 +49,55 @@ pub async fn add_pkg( | ||||
| } | ||||
|  | ||||
| pub async fn remove_pkg(db: &DatabaseConnection, pkg_id: i32) -> anyhow::Result<()> { | ||||
|     let txn = db.begin().await?; | ||||
|  | ||||
|     let pkg = Packages::find_by_id(pkg_id) | ||||
|         .one(db) | ||||
|         .one(&txn) | ||||
|         .await? | ||||
|         .ok_or(anyhow!("id not found"))?; | ||||
|  | ||||
|     // remove build dir if available | ||||
|     let _ = fs::remove_dir_all(format!("./builds/{}", pkg.name)); | ||||
|  | ||||
|     // remove package db entry | ||||
|     pkg.clone().delete(&txn).await?; | ||||
|  | ||||
|     let versions = Versions::find() | ||||
|         .filter(versions::Column::PackageId.eq(pkg.id)) | ||||
|         .all(db) | ||||
|         .all(&txn) | ||||
|         .await?; | ||||
|  | ||||
|     for v in versions { | ||||
|         rem_ver(db, v).await?; | ||||
|         rem_ver(&txn, v).await?; | ||||
|     } | ||||
|  | ||||
|     // remove corresponding builds | ||||
|     let builds = Builds::find() | ||||
|         .filter(builds::Column::PkgId.eq(pkg.id)) | ||||
|         .all(db) | ||||
|         .all(&txn) | ||||
|         .await?; | ||||
|     for b in builds { | ||||
|         b.delete(db).await?; | ||||
|         b.delete(&txn).await?; | ||||
|     } | ||||
|  | ||||
|     // remove package db entry | ||||
|     pkg.delete(db).await?; | ||||
|     txn.commit().await?; | ||||
|  | ||||
|     Ok(()) | ||||
| } | ||||
|  | ||||
| pub async fn remove_version(db: &DatabaseConnection, version_id: i32) -> anyhow::Result<()> { | ||||
|     let txn = db.begin().await?; | ||||
|  | ||||
|     let version = Versions::find() | ||||
|         .filter(versions::Column::PackageId.eq(version_id)) | ||||
|         .one(db) | ||||
|         .one(&txn) | ||||
|         .await?; | ||||
|     if let Some(version) = version { | ||||
|         rem_ver(db, version).await?; | ||||
|         rem_ver(&txn, version).await?; | ||||
|     } | ||||
|  | ||||
|     txn.commit().await?; | ||||
|  | ||||
|     Ok(()) | ||||
| } | ||||
|  | ||||
| @@ -129,7 +141,7 @@ fn repo_remove(pkg_file_name: String) -> anyhow::Result<()> { | ||||
|     Ok(()) | ||||
| } | ||||
|  | ||||
| async fn rem_ver(db: &DatabaseConnection, version: versions::Model) -> anyhow::Result<()> { | ||||
| async fn rem_ver(db: &DatabaseTransaction, version: versions::Model) -> anyhow::Result<()> { | ||||
|     if let Some(filename) = version.file_name.clone() { | ||||
|         // so repo-remove only supports passing a package name and removing the whole package | ||||
|         // it seems that repo-add removes an older version when called | ||||
|   | ||||
| @@ -19,9 +19,15 @@ extension PackagesAPI on ApiClient { | ||||
|     return package; | ||||
|   } | ||||
|  | ||||
|   Future<void> addPackage({bool force = false, required String name}) async { | ||||
|   Future<void> addPackage({required String name}) async { | ||||
|     final resp = | ||||
|         await getRawClient().post("/packages/add", data: {'name': name}); | ||||
|     print(resp.data); | ||||
|   } | ||||
|  | ||||
|   Future<void> updatePackage({bool force = false, required int id}) async { | ||||
|     final resp = await getRawClient() | ||||
|         .post("/packages/add", data: {'force_build': force, 'name': name}); | ||||
|         .post("/packages/$id/update", data: {'force': force}); | ||||
|     print(resp.data); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -54,11 +54,19 @@ class PackagesTable extends StatelessWidget { | ||||
|         DataCell(IconButton( | ||||
|           icon: Icon( | ||||
|             package.outofdate ? Icons.update : Icons.verified, | ||||
|             color: package.outofdate ? Color(0xFF6B43A4) : Color(0xFF0A6900), | ||||
|             color: package.outofdate | ||||
|                 ? const Color(0xFF6B43A4) | ||||
|                 : const Color(0xFF0A6900), | ||||
|           ), | ||||
|           onPressed: package.outofdate | ||||
|               ? () { | ||||
|                   // todo open build info with logs | ||||
|               ? () async { | ||||
|                   await API.updatePackage(id: package.id); | ||||
|                   Provider.of<PackagesProvider>(context, listen: false) | ||||
|                       .refresh(context); | ||||
|                   Provider.of<BuildsProvider>(context, listen: false) | ||||
|                       .refresh(context); | ||||
|                   Provider.of<StatsProvider>(context, listen: false) | ||||
|                       .refresh(context); | ||||
|                 } | ||||
|               : null, | ||||
|         )), | ||||
|   | ||||
| @@ -56,18 +56,19 @@ class _PackageScreenState extends State<PackageScreen> { | ||||
|                             style: const TextStyle(fontSize: 32), | ||||
|                           ), | ||||
|                         ), | ||||
|                         Container( | ||||
|                           margin: const EdgeInsets.only(right: 15), | ||||
|                           child: ElevatedButton( | ||||
|                             onPressed: () async { | ||||
|                               final confirmResult = | ||||
|                                   await showConfirmationDialog( | ||||
|                                 context, | ||||
|                                 "Delete Package", | ||||
|                                 "Are you sure to delete this Package?", | ||||
|                                 () async { | ||||
|                                   final succ = await API.deletePackage(pkg.id); | ||||
|                                   if (succ) { | ||||
|                         Row( | ||||
|                           children: [ | ||||
|                             ElevatedButton( | ||||
|                               onPressed: () async { | ||||
|                                 final confirmResult = | ||||
|                                     await showConfirmationDialog( | ||||
|                                   context, | ||||
|                                   "Force update Package", | ||||
|                                   "Are you sure to force an Package rebuild?", | ||||
|                                   () async { | ||||
|                                     await API.updatePackage( | ||||
|                                         force: true, id: pkg.id); | ||||
|  | ||||
|                                     context.pop(); | ||||
|  | ||||
|                                     Provider.of<PackagesProvider>(context, | ||||
| @@ -79,16 +80,51 @@ class _PackageScreenState extends State<PackageScreen> { | ||||
|                                     Provider.of<StatsProvider>(context, | ||||
|                                             listen: false) | ||||
|                                         .refresh(context); | ||||
|                                   } | ||||
|                                 }, | ||||
|                                 () {}, | ||||
|                               ); | ||||
|                             }, | ||||
|                             child: const Text( | ||||
|                               "Delete", | ||||
|                               style: TextStyle(color: Colors.redAccent), | ||||
|                                   }, | ||||
|                                   () {}, | ||||
|                                 ); | ||||
|                               }, | ||||
|                               child: const Text( | ||||
|                                 "Force Update", | ||||
|                                 style: TextStyle(color: Colors.yellowAccent), | ||||
|                               ), | ||||
|                             ), | ||||
|                           ), | ||||
|                             ElevatedButton( | ||||
|                               onPressed: () async { | ||||
|                                 final confirmResult = | ||||
|                                     await showConfirmationDialog( | ||||
|                                   context, | ||||
|                                   "Delete Package", | ||||
|                                   "Are you sure to delete this Package?", | ||||
|                                   () async { | ||||
|                                     final succ = | ||||
|                                         await API.deletePackage(pkg.id); | ||||
|                                     if (succ) { | ||||
|                                       context.pop(); | ||||
|  | ||||
|                                       Provider.of<PackagesProvider>(context, | ||||
|                                               listen: false) | ||||
|                                           .refresh(context); | ||||
|                                       Provider.of<BuildsProvider>(context, | ||||
|                                               listen: false) | ||||
|                                           .refresh(context); | ||||
|                                       Provider.of<StatsProvider>(context, | ||||
|                                               listen: false) | ||||
|                                           .refresh(context); | ||||
|                                     } | ||||
|                                   }, | ||||
|                                   () {}, | ||||
|                                 ); | ||||
|                               }, | ||||
|                               child: const Text( | ||||
|                                 "Delete", | ||||
|                                 style: TextStyle(color: Colors.redAccent), | ||||
|                               ), | ||||
|                             ), | ||||
|                             SizedBox( | ||||
|                               width: 15, | ||||
|                             ) | ||||
|                           ], | ||||
|                         ) | ||||
|                       ], | ||||
|                     ), | ||||
|   | ||||
		Reference in New Issue
	
	Block a user