From 9fb2e6059734c3d530fc4a909bbae65ed0994098 Mon Sep 17 00:00:00 2001 From: Purvesh Date: Wed, 3 Jul 2024 19:40:29 +1200 Subject: [PATCH] add support for select dropdown --- react-admin/src/pages/page/PageCreate.tsx | 5 +- react-admin/src/pages/page/PageEdit.tsx | 2 +- react-admin/src/types/page/ICreatablePage.ts | 8 +- react-admin/src/types/page/IEditablePage.ts | 9 +- .../page/request/store_page_request.rs | 7 ++ .../page/request/update_page_request.rs | 14 ++- .../handlers/page/store_page_api_handler.rs | 14 ++- .../handlers/page/update_page_api_handler.rs | 14 ++- src/models/page_model.rs | 97 ++++++++++++++++--- src/repositories/page_repository.rs | 93 +++++++++++++----- 10 files changed, 212 insertions(+), 51 deletions(-) diff --git a/react-admin/src/pages/page/PageCreate.tsx b/react-admin/src/pages/page/PageCreate.tsx index 4ecd7bdd..4182bc8f 100644 --- a/react-admin/src/pages/page/PageCreate.tsx +++ b/react-admin/src/pages/page/PageCreate.tsx @@ -191,6 +191,7 @@ function PageCreate() { }; const submitHandler = async (data: ICreatablePage) => { + // console.log(data) mutate(data); }; @@ -243,8 +244,8 @@ function PageCreate() { > - {t("add_component")} - + {t("add_component")} + diff --git a/react-admin/src/pages/page/PageEdit.tsx b/react-admin/src/pages/page/PageEdit.tsx index fc7d45ea..5b0844b9 100644 --- a/react-admin/src/pages/page/PageEdit.tsx +++ b/react-admin/src/pages/page/PageEdit.tsx @@ -58,7 +58,7 @@ function PageEdit() { const getSelectFieldDataOptionCurrentValue = ((pageComponentIndex: number, componentFieldIndex: number) => { let val = getValues(`components_content.${pageComponentIndex}.fields.${componentFieldIndex}.field_content`) - console.log(val) + if (val) { return [val] } diff --git a/react-admin/src/types/page/ICreatablePage.ts b/react-admin/src/types/page/ICreatablePage.ts index 8afefabc..f1c3b524 100644 --- a/react-admin/src/types/page/ICreatablePage.ts +++ b/react-admin/src/types/page/ICreatablePage.ts @@ -24,9 +24,15 @@ export interface ICreatablePageComponentFieldModel { identifier: string; field_type: string; field_content: string; - field_data?: Array; + field_data?: Array; created_at: string; updated_at: string; created_by: string; updated_by: string; +} + +export interface ICreatablePageComponentFieldDataModel { + label: string; + value: string; + field_data_content: string; } \ No newline at end of file diff --git a/react-admin/src/types/page/IEditablePage.ts b/react-admin/src/types/page/IEditablePage.ts index 99846028..7a8fc806 100644 --- a/react-admin/src/types/page/IEditablePage.ts +++ b/react-admin/src/types/page/IEditablePage.ts @@ -25,9 +25,16 @@ export interface IEditablePageComponentFieldModel { identifier: string; field_type: string; field_content: string; - field_data?: Array; + field_data?: Array; created_at: string; updated_at: string; created_by: string; updated_by: string; +} + + +export interface IEditablePageComponentFieldDataModel { + label: string; + value: string; + field_data_content: string; } \ No newline at end of file diff --git a/src/api/handlers/page/request/store_page_request.rs b/src/api/handlers/page/request/store_page_request.rs index a14951dd..e9b4fdc3 100644 --- a/src/api/handlers/page/request/store_page_request.rs +++ b/src/api/handlers/page/request/store_page_request.rs @@ -30,6 +30,13 @@ pub struct CreatableComponentFieldContentRequest { pub identifier: String, pub field_type: String, pub field_content: String, + pub field_data: Option> +} + +#[derive(Deserialize, Debug, Clone, Default)] +pub struct CreatablePageComponentFieldDataOptionRequest { + pub label: String, + pub value: String, } diff --git a/src/api/handlers/page/request/update_page_request.rs b/src/api/handlers/page/request/update_page_request.rs index 06145b91..ba554805 100644 --- a/src/api/handlers/page/request/update_page_request.rs +++ b/src/api/handlers/page/request/update_page_request.rs @@ -1,16 +1,11 @@ use rust_i18n::t; use serde::Deserialize; - use crate::models::validation_error::{ErrorMessage, Validate}; #[derive(Deserialize, Debug, Clone, Default)] pub struct UpdatePageRequest { - // #[validate(length(min = 1, message = "The name is a required field."))] pub name: String, - - // #[validate(length(min = 1, message = "The identifier is a required field."))] pub identifier: String, - pub components_content: Vec, } @@ -31,8 +26,17 @@ pub struct UpdatableComponentFieldContentRequest { pub identifier: String, pub field_type: String, pub field_content: String, + pub field_data: Option> +} + + +#[derive(Deserialize, Debug, Clone, Default)] +pub struct EditablePageComponentFieldDataOptionRequest { + pub label: String, + pub value: String, } + impl UpdatePageRequest { pub fn validate(&self) -> crate::error::Result> { let mut errors: Vec = vec![]; diff --git a/src/api/handlers/page/store_page_api_handler.rs b/src/api/handlers/page/store_page_api_handler.rs index edd2bb8d..0b6d6485 100644 --- a/src/api/handlers/page/store_page_api_handler.rs +++ b/src/api/handlers/page/store_page_api_handler.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use crate::error::Error; -use crate::models::page_model::{CreatableComponentContentModel, CreatableComponentFieldContentModel, CreatablePageModel, PageModel}; +use crate::models::page_model::{CreatableComponentContentModel, CreatableComponentFieldContentModel, CreatablePageModel, PageModel, CreatablePageComponentFieldDataModel}; use crate::models::validation_error::ErrorResponse; use crate::{ avored_state::AvoRedState, error::Result @@ -54,12 +54,24 @@ pub async fn store_page_api_handler( }; for payload_component_fields_data in payload_component_content.fields { + let mut payload_field_data_model_options: Vec = Vec::new(); + let payload_field_options_data = payload_component_fields_data.field_data.unwrap_or(Vec::new()); + + for payload_component_field_data_option in payload_field_options_data { + let creatable_page_field_option_data = CreatablePageComponentFieldDataModel { + label: payload_component_field_data_option.label, + value: payload_component_field_data_option.value, + }; + payload_field_data_model_options.push(creatable_page_field_option_data); + } + let creatable_component_field_content = CreatableComponentFieldContentModel { id: payload_component_fields_data.id, name: payload_component_fields_data.name, identifier: payload_component_fields_data.identifier, field_type: payload_component_fields_data.field_type, field_content: payload_component_fields_data.field_content, + field_data: payload_field_data_model_options }; creatable_component_content_model.fields.push(creatable_component_field_content); diff --git a/src/api/handlers/page/update_page_api_handler.rs b/src/api/handlers/page/update_page_api_handler.rs index 66bcb50a..9b40d906 100644 --- a/src/api/handlers/page/update_page_api_handler.rs +++ b/src/api/handlers/page/update_page_api_handler.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use crate::error::Error; -use crate::models::page_model::{PageModel, UpdatableComponentContentModel, UpdatableComponentFieldContentModel, UpdatablePageModel}; +use crate::models::page_model::{PageModel, UpdatableComponentContentModel, UpdatableComponentFieldContentModel, UpdatablePageComponentFieldDataModel, UpdatablePageModel}; use crate::models::validation_error::ErrorResponse; use crate::{ api::handlers::page::request::update_page_request::UpdatePageRequest, @@ -57,12 +57,24 @@ pub async fn update_page_api_handler( }; for payload_component_fields_data in payload_component_content.fields { + let mut payload_field_data_model_options: Vec = Vec::new(); + let payload_field_options_data = payload_component_fields_data.field_data.unwrap_or(Vec::new()); + + for payload_component_field_data_option in payload_field_options_data { + let creatable_page_field_option_data = UpdatablePageComponentFieldDataModel { + label: payload_component_field_data_option.label, + value: payload_component_field_data_option.value, + }; + payload_field_data_model_options.push(creatable_page_field_option_data); + } + let updatable_component_field_content = UpdatableComponentFieldContentModel { id: payload_component_fields_data.id, name: payload_component_fields_data.name, identifier: payload_component_fields_data.identifier, field_type: payload_component_fields_data.field_type, field_content: payload_component_fields_data.field_content, + field_data: payload_field_data_model_options }; updatable_component_content_model.fields.push(updatable_component_field_content); diff --git a/src/models/page_model.rs b/src/models/page_model.rs index 646ca907..ab43c303 100644 --- a/src/models/page_model.rs +++ b/src/models/page_model.rs @@ -23,6 +23,13 @@ pub struct ComponentFieldModel { pub identifier: String, pub field_type: String, pub field_content: String, + pub field_data: Vec +} + +#[derive(Serialize, Debug, Deserialize, Clone, Default)] +pub struct PageComponentFieldDataOption { + pub label: String, + pub value: String } #[derive(Serialize, Debug, Deserialize, Clone, Default)] @@ -195,18 +202,6 @@ impl TryFrom for ComponentContentModel { None => Vec::new(), }; - // let field_type = match val.get("field_type") { - // Some(val) => { - // let value = match val.clone() { - // Value::Strand(v) => v.as_string(), - // _ => String::from(""), - // }; - // value - // } - // None => String::from(""), - // }; - - Ok(ComponentContentModel { id, name, @@ -216,8 +211,6 @@ impl TryFrom for ComponentContentModel { } } - - impl TryFrom for ComponentFieldModel { type Error = Error; fn try_from(val: Object) -> Result { @@ -277,13 +270,71 @@ impl TryFrom for ComponentFieldModel { } None => String::from(""), }; + + let field_data = match val.get("field_data") { + Some(val) => { + let value = match val.clone() { + Value::Array(v) => { + let mut arr = Vec::new(); + + for array in v.into_iter() { + let object = match array.clone() { + Value::Object(v) => v, + _ => surrealdb::sql::Object::default(), + }; + + let field_data_option: PageComponentFieldDataOption = object.try_into()?; + + arr.push(field_data_option) + } + arr + } + _ => Vec::new(), + }; + value + } + None => Vec::new(), + }; Ok(ComponentFieldModel { id, name, identifier, field_type, - field_content + field_content, + field_data + }) + } +} + +impl TryFrom for PageComponentFieldDataOption { + type Error = Error; + fn try_from(val: Object) -> Result { + let label = match val.get("label") { + Some(val) => { + let value = match val.clone() { + Value::Strand(v) => v.as_string(), + _ => String::from(""), + }; + value + } + None => String::from(""), + }; + let value = match val.get("value") { + Some(val) => { + let value = match val.clone() { + Value::Strand(v) => v.as_string(), + _ => String::from(""), + }; + value + } + None => String::from(""), + }; + + + Ok(PageComponentFieldDataOption { + label, + value }) } } @@ -322,6 +373,14 @@ pub struct CreatableComponentFieldContentModel { pub identifier: String, pub field_type: String, pub field_content: String, + pub field_data: Vec +} + + +#[derive(Deserialize, Debug, Clone, Default, Serialize)] +pub struct CreatablePageComponentFieldDataModel { + pub label: String, + pub value: String, } #[derive(Serialize, Debug, Deserialize, Clone)] @@ -351,4 +410,12 @@ pub struct UpdatableComponentFieldContentModel { pub identifier: String, pub field_type: String, pub field_content: String, + pub field_data: Vec +} + + +#[derive(Deserialize, Debug, Clone, Default, Serialize)] +pub struct UpdatablePageComponentFieldDataModel { + pub label: String, + pub value: String, } \ No newline at end of file diff --git a/src/repositories/page_repository.rs b/src/repositories/page_repository.rs index b7927360..bf2216e5 100644 --- a/src/repositories/page_repository.rs +++ b/src/repositories/page_repository.rs @@ -114,25 +114,54 @@ impl PageRepository { let mut fields_sql = String::from(""); for creatable_component_field_content in creatable_component_content_model.fields { - - fields_sql.push_str(&format!("{open_brace} id: '{id}', name: '{name}', identifier: '{identifier}', field_type: '{field_type}', field_content: '{field_content}' {close_brace}", - id = creatable_component_field_content.id, - name = creatable_component_field_content.name, - identifier = creatable_component_field_content.identifier, - field_type = creatable_component_field_content.field_type, - field_content = creatable_component_field_content.field_content, - open_brace = String::from("{"), - close_brace = String::from("}") + let mut field_data_sql = String::from(""); + + for field_data_value in creatable_component_field_content.field_data { + field_data_sql.push_str( + &format!("{open_brace} \ + label: '{label}', \ + value: '{value}' \ + {close_brace}", + open_brace = String::from("{"), + label = field_data_value.label, + value = field_data_value.value, + close_brace = String::from("},") + )); + } + + fields_sql.push_str( + &format!("{open_brace} \ + id: '{id}', \ + name: '{name}', \ + identifier: '{identifier}', \ + field_type: '{field_type}', \ + field_content: '{field_content}', \ + field_data: [{field_data_sql}] \ + {close_brace}", + id = creatable_component_field_content.id, + name = creatable_component_field_content.name, + identifier = creatable_component_field_content.identifier, + field_type = creatable_component_field_content.field_type, + field_data_sql = field_data_sql, + field_content = creatable_component_field_content.field_content, + open_brace = String::from("{"), + close_brace = String::from("}") )); } - components_content_sql.push_str(&format!("{open_brace} id: '{id}', name: '{name}', identifier: '{identifier}', fields: [{fields_sql}] {close_brace}", - id = creatable_component_content_model.id, - name = creatable_component_content_model.name, - identifier = creatable_component_content_model.identifier, - fields_sql = fields_sql, - open_brace = String::from("{"), - close_brace = String::from("}") + components_content_sql.push_str( + &format!("{open_brace} \ + id: '{id}', \ + name: '{name}', \ + identifier: '{identifier}', \ + fields: [{fields_sql}] \ + {close_brace}", + id = creatable_component_content_model.id, + name = creatable_component_content_model.name, + identifier = creatable_component_content_model.identifier, + fields_sql = fields_sql, + open_brace = String::from("{"), + close_brace = String::from("}") )); } @@ -182,14 +211,30 @@ impl PageRepository { for updatable_component_field_content in updatable_component_content_model.fields { - fields_sql.push_str(&format!("{open_brace} id: '{id}', name: '{name}', identifier: '{identifier}', field_type: '{field_type}', field_content: '{field_content}' {close_brace}", - id = updatable_component_field_content.id, - name = updatable_component_field_content.name, - identifier = updatable_component_field_content.identifier, - field_type = updatable_component_field_content.field_type, - field_content = updatable_component_field_content.field_content, - open_brace = String::from("{"), - close_brace = String::from("}") + let mut field_data_sql = String::from(""); + + for field_data_value in updatable_component_field_content.field_data { + field_data_sql.push_str( + &format!("{open_brace} \ + label: '{label}', \ + value: '{value}' \ + {close_brace}", + open_brace = String::from("{"), + label = field_data_value.label, + value = field_data_value.value, + close_brace = String::from("},") + )); + } + + fields_sql.push_str(&format!("{open_brace} id: '{id}', name: '{name}', identifier: '{identifier}', field_type: '{field_type}', field_content: '{field_content}', field_data: [{field_data_sql}] {close_brace}", + id = updatable_component_field_content.id, + name = updatable_component_field_content.name, + identifier = updatable_component_field_content.identifier, + field_type = updatable_component_field_content.field_type, + field_content = updatable_component_field_content.field_content, + field_data_sql = field_data_sql, + open_brace = String::from("{"), + close_brace = String::from("}") )); }