From 1e38b38b09f912f57bee99df0aa0419b89b47658 Mon Sep 17 00:00:00 2001 From: Argha Date: Wed, 25 Sep 2024 10:51:44 +0530 Subject: [PATCH 1/7] fixed issue with deployment UI, code cleanup for `app_type` matches. --- .../assets/styles/pages/_deployment.scss | 4 +- hosted-frontend/src/pages/auth/login.rs | 9 ++-- hosted-frontend/src/pages/auth/sign_up.rs | 6 +-- .../deployment/create_deployment/details.rs | 49 +++++++++---------- .../deployment/dashboard/mod.rs | 29 ++++++----- .../deployment/manage_deployment/details.rs | 33 ++++++------- .../deployment/manage_deployment/scaling.rs | 41 +++++++--------- .../src/pages/workspace/sidebar/mod.rs | 2 +- .../src/routes/workspaced_content.rs | 4 +- 9 files changed, 80 insertions(+), 97 deletions(-) diff --git a/hosted-frontend/assets/styles/pages/_deployment.scss b/hosted-frontend/assets/styles/pages/_deployment.scss index f344877c3..cf3f9d278 100644 --- a/hosted-frontend/assets/styles/pages/_deployment.scss +++ b/hosted-frontend/assets/styles/pages/_deployment.scss @@ -11,7 +11,7 @@ } .deployment-card { - height: 20rem; + min-height: 20rem; .date-time { background-color: $bg-code-snippet; @@ -23,7 +23,7 @@ .deployment-card-items { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); - grid-auto-rows: 1fr; + grid-auto-rows: 50px; width: 100%; height: 100%; diff --git a/hosted-frontend/src/pages/auth/login.rs b/hosted-frontend/src/pages/auth/login.rs index e16137035..b061234cf 100644 --- a/hosted-frontend/src/pages/auth/login.rs +++ b/hosted-frontend/src/pages/auth/login.rs @@ -143,17 +143,14 @@ pub fn LoginForm() -> impl IntoView { { - match app_type { - AppType::SelfHosted => view! {}.into_view(), - AppType::Managed => view! { + app_type.is_managed().then(|| + view! {
"Forgot Password?"
- } - .into_view() - } + }.into_view()) } impl IntoView {
{ - match app_type { - AppType::SelfHosted => view! {}.into_view(), - AppType::Managed => view! { + app_type.is_managed().then(|| view! { "ALREADY HAVE AN OTP" }.into_view() - } + ) }
{ - match app_type { - AppType::SelfHosted => view! {}.into_view(), - AppType::Managed => view! { -
-
- -
- -
- - { - move || view! { - - - - - {move || store_errors.with_value(|errors| errors.get().runner.clone())} - - - - }.into_view() - } - -
+ app_type.is_managed().then(|| view! { +
+
+
- }.into_view() - } + +
+ + { + move || view! { + + + + + {move || store_errors.with_value(|errors| errors.get().runner.clone())} + + + + }.into_view() + } + +
+
+ }.into_view()) }
diff --git a/hosted-frontend/src/pages/infrastructure/deployment/dashboard/mod.rs b/hosted-frontend/src/pages/infrastructure/deployment/dashboard/mod.rs index da48eccbb..1ab6eacff 100644 --- a/hosted-frontend/src/pages/infrastructure/deployment/dashboard/mod.rs +++ b/hosted-frontend/src/pages/infrastructure/deployment/dashboard/mod.rs @@ -38,21 +38,20 @@ pub fn DeploymentDashboard() -> impl IntoView { { move || match deployment_list.get() { Some(Ok(data)) => view! { - - - - }.into_view() - } - /> - }, +
+
+ + + +
+
+ }.into_view(), Some(Err(err)) => view! { impl IntoView { { - match app_type { - AppType::SelfHosted => view! {}.into_view(), - AppType::Managed => view! { -
-
- -
-
- -
+ app_type.is_managed().then(|| view! { +
+
+
- }.into_view() - } +
+ +
+
+ }.into_view()) } impl IntoView {
{ - match app_type { - AppType::SelfHosted => view! {}.into_view(), - AppType::Managed => view! { -
-
- "Estimated Cost" -
+ app_type.is_managed().then(|| view! { +
+
+ "Estimated Cost" +
-
-
- - "$5" "/month" - -
- -

- "This deployment is eligible for " - "Free" "plan" - "since it's your first deployment and"
- "you have selected the base machine type with only one instance." -

+
+
+ + "$5" "/month" +
+ +

+ "This deployment is eligible for " + "Free" "plan" + "since it's your first deployment and"
+ "you have selected the base machine type with only one instance." +

- }.into_view() - } +
+ }.into_view()) }
} diff --git a/hosted-frontend/src/pages/workspace/sidebar/mod.rs b/hosted-frontend/src/pages/workspace/sidebar/mod.rs index 9f92574e2..07a233a20 100644 --- a/hosted-frontend/src/pages/workspace/sidebar/mod.rs +++ b/hosted-frontend/src/pages/workspace/sidebar/mod.rs @@ -94,7 +94,7 @@ pub fn WorkspaceSidebarComponent() -> impl IntoView { /> } .into_view(), - Err(_) => view! {"Error Loading"}.into_view(), + Err(err) => format!( "Error Loading, {:?}", err ).into_view(), }, None => view! {"loading..."}.into_view(), } diff --git a/hosted-frontend/src/routes/workspaced_content.rs b/hosted-frontend/src/routes/workspaced_content.rs index 5b8d4c970..2bf734551 100644 --- a/hosted-frontend/src/routes/workspaced_content.rs +++ b/hosted-frontend/src/routes/workspaced_content.rs @@ -65,9 +65,7 @@ pub fn WorkspacedRoutes() -> impl IntoView { view! { - }} + view={WorkspacedRouteView} redirect_path={AppRoutes::LoggedInRoute(LoggedInRoute::UserProfile)} condition={move || current_workspace_id.get().is_some()} > From 677949982c4a815b08829451025e93e7945a5250 Mon Sep 17 00:00:00 2001 From: Argha Date: Wed, 25 Sep 2024 10:53:08 +0530 Subject: [PATCH 2/7] added App Route macros for declaring the routes for workspace, deployment and runner --- hosted-frontend/src/app.rs | 66 +++------ .../src/routes/auth/verify_signup.rs | 2 +- hosted-frontend/src/routes/mod.rs | 29 ++++ hosted-frontend/src/routes/profile/mod.rs | 35 +++++ .../workspace/infrastructure/deployment.rs | 133 ++++++++++++++++++ .../routes/workspace/infrastructure/mod.rs | 3 + hosted-frontend/src/routes/workspace/mod.rs | 5 + .../src/routes/workspace/runner.rs | 34 +++++ .../src/routes/workspace/workspace/mod.rs | 7 + 9 files changed, 268 insertions(+), 46 deletions(-) create mode 100644 hosted-frontend/src/routes/profile/mod.rs create mode 100644 hosted-frontend/src/routes/workspace/infrastructure/deployment.rs create mode 100644 hosted-frontend/src/routes/workspace/infrastructure/mod.rs create mode 100644 hosted-frontend/src/routes/workspace/mod.rs create mode 100644 hosted-frontend/src/routes/workspace/runner.rs create mode 100644 hosted-frontend/src/routes/workspace/workspace/mod.rs diff --git a/hosted-frontend/src/app.rs b/hosted-frontend/src/app.rs index 567f5b70f..febc4006d 100644 --- a/hosted-frontend/src/app.rs +++ b/hosted-frontend/src/app.rs @@ -3,9 +3,12 @@ use leptos_router::{Outlet, ProtectedRoute, Route, Router, Routes}; use crate::{pages::*, prelude::*, utils::AuthState}; +/// The View for the App Component, it encapsulates the whole application, and +/// adds the sidebar or headedr if necessary #[component] pub fn AppOutletView() -> impl IntoView { let (state, _) = AuthState::load(); + let app_type = expect_context::(); view! { {move || match state.get() { @@ -14,57 +17,30 @@ pub fn AppOutletView() -> impl IntoView { }.into_view(), - AuthState::LoggedIn { access_token: _, refresh_token: _, last_used_workspace_id } => { - if last_used_workspace_id.is_some() { - view! { -
- -
-
-
-
+ AuthState::LoggedIn {..} => { + view! { +
+ + { + app_type.is_managed().then(|| view! { + + + + }) + } + - -
-
- } - .into_view() - } else { - view! { -
"No workspace exists. Create workspace"
- } - .into_view() +
+ +
+
} + .into_view() } }} } } -#[component] -pub fn AppOutlet() -> impl IntoView { - let app_type = expect_context::(); - - view! { -
- - { - match app_type { - AppType::SelfHosted => view! {}.into_view(), - AppType::Managed => view! { - - - - } - } - } - -
- -
-
- } -} - /// The main application component. This is the root component of the /// application. It contains the main router and all the routes. #[component] @@ -85,7 +61,7 @@ pub fn App() -> impl IntoView { // Logged in routes diff --git a/hosted-frontend/src/routes/auth/verify_signup.rs b/hosted-frontend/src/routes/auth/verify_signup.rs index e8e8f79d4..d04870035 100644 --- a/hosted-frontend/src/routes/auth/verify_signup.rs +++ b/hosted-frontend/src/routes/auth/verify_signup.rs @@ -1,7 +1,7 @@ macros::declare_app_route! { /// Route for verifying a signup with a token VerifySignUp, - "/verify-signup", + "/confirm-signup", requires_login = false, query = { /// The userId to prefill the forgot password form with diff --git a/hosted-frontend/src/routes/mod.rs b/hosted-frontend/src/routes/mod.rs index 79348b2a7..1e542be7b 100644 --- a/hosted-frontend/src/routes/mod.rs +++ b/hosted-frontend/src/routes/mod.rs @@ -1,14 +1,43 @@ mod auth; +mod profile; +mod workspace; mod logged_in_routes; mod logged_out_routes; mod not_workspaced_content; mod workspaced_content; +use models::prelude::*; +use serde::{Deserialize, Serialize}; + pub use self::{ auth::*, logged_in_routes::*, logged_out_routes::*, not_workspaced_content::*, + profile::*, + workspace::*, workspaced_content::*, }; + +#[derive( + Debug, Clone, Serialize, Deserialize, PartialEq, Eq, strum::Display, strum::EnumString, +)] +#[strum(serialize_all = "camelCase")] +pub enum SortDirection { + Ascending, + Descending, +} + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)] +pub struct CommonQueryParams { + /// The Page number to fetch + #[serde(skip_serializing_if = "Option::is_none")] + pub page: Option, + /// The Sorting order of the deployments + #[serde(skip_serializing_if = "Option::is_none")] + pub order: Option, + /// Filter the deployments by date + #[serde(skip_serializing_if = "Option::is_none")] + pub query: Option>, +} diff --git a/hosted-frontend/src/routes/profile/mod.rs b/hosted-frontend/src/routes/profile/mod.rs new file mode 100644 index 000000000..d623bd806 --- /dev/null +++ b/hosted-frontend/src/routes/profile/mod.rs @@ -0,0 +1,35 @@ +use models::utils::Uuid; + +macros::declare_app_route! { + /// Route for Manage Profile Page + ManageProfile, + "/user", + requires_login = true, + query = {} +} + +macros::declare_app_route! { + /// Route for Api Tokens Page + ApiTokens, + "/user/api-tokens", + requires_login = true, + query = {} +} + +macros::declare_app_route! { + /// Route for Create Api Tokens Page + CreateApiToken, + "/user/api-tokens/create", + requires_login = true, + query = {} +} + +macros::declare_app_route! { + /// Route for Edit Api Tokens Page + EditApiToken, + "/user/api-tokens/:token_id" { + pub token_id: Uuid + }, + requires_login = true, + query = {} +} diff --git a/hosted-frontend/src/routes/workspace/infrastructure/deployment.rs b/hosted-frontend/src/routes/workspace/infrastructure/deployment.rs new file mode 100644 index 000000000..fd8e7afef --- /dev/null +++ b/hosted-frontend/src/routes/workspace/infrastructure/deployment.rs @@ -0,0 +1,133 @@ +use models::{api::workspace::deployment::DeploymentStatus, prelude::*}; +use serde::{Deserialize, Serialize}; + +use crate::CommonQueryParams; + +#[derive( + Debug, Clone, Serialize, Deserialize, PartialEq, Eq, strum::Display, strum::EnumString, +)] +#[strum(serialize_all = "camelCase")] +pub enum FilterableColumns { + Name, + RunnerName, + Status, + Created, + LastUpdated, + ImageName, + ImageTag, +} + +#[derive( + Debug, Clone, Serialize, Deserialize, PartialEq, Eq, strum::Display, strum::EnumString, +)] +#[strum(serialize_all = "camelCase")] +pub enum SortableColumns { + Name, + RunnerName, + Created, + LastUpdated, + Status, +} + +macros::declare_app_route! { + /// Route for Deployments Dashboard Page + ListDeployments, + "/deployment", + requires_login = true, + query = { + /// Common Query Parameters + #[serde(flatten)] + pub common: CommonQueryParams, + /// The Column to sort by + #[serde(skip_serializing_if = "Option::is_none")] + pub sort: Option, + /// Filter the deployments by the status + #[serde(skip_serializing_if = "Option::is_none")] + pub status: Option>, + /// The Column to filter query by + #[serde(skip_serializing_if = "Option::is_none")] + pub filter_by: Option, + } +} + +macros::declare_app_route! { + /// Route for Deployments Create Page + CreateDeployment, + "/deployment/create", + requires_login = true, + query = { } +} + +macros::declare_app_route! { + /// Route for Deployments Details Page + ManageDeploymentDetailsTab, + "/deployment/:deployment_id" { + /// The id of the deployment + pub deployment_id: Uuid, + }, + requires_login = true, + query = {} +} + +macros::declare_app_route! { + /// Route for Deployments History Page + ManageDeploymentImageHistory, + "/deployment/:deployment_id/history" { + /// The id of the deployment + pub deployment_id: Uuid, + }, + requires_login = true, + query = { + /// Common Query Parameters + #[serde(flatten)] + pub common: CommonQueryParams, + } +} + +macros::declare_app_route! { + /// Route for Deployments Logs Page + ManageDeploymentsLogs, + "/deployment/:deployment_id/logs" { + /// The id of the deployment + pub deployment_id: Uuid, + }, + requires_login = true, + query = { + /// Common Query Parameters + #[serde(flatten)] + pub common: CommonQueryParams, + } +} + +macros::declare_app_route! { + /// Route for Deployments Monitoring Page + ManageDeploymentsMonitoring, + "/deployment/:deployment_id/monitor" { + /// The id of the deployment + pub deployment_id: Uuid, + }, + requires_login = true, + query = {} +} + +macros::declare_app_route! { + /// Route for Deployments Scaling Page + ManageDeploymentScaling, + "/deployment/:deployment_id/scaling" { + /// The id of the deployment + pub deployment_id: Uuid, + }, + requires_login = true, + query = {} +} + +macros::declare_app_route! { + /// Route for Deployments URLs Page + ManageDeploymentUrls, + "/deployment/:deployment_id/urls" { + /// The id of the deployment + pub deployment_id: Uuid, + }, + requires_login = true, + query = {} +} diff --git a/hosted-frontend/src/routes/workspace/infrastructure/mod.rs b/hosted-frontend/src/routes/workspace/infrastructure/mod.rs new file mode 100644 index 000000000..7851dedad --- /dev/null +++ b/hosted-frontend/src/routes/workspace/infrastructure/mod.rs @@ -0,0 +1,3 @@ +mod deployment; + +pub use self::deployment::*; diff --git a/hosted-frontend/src/routes/workspace/mod.rs b/hosted-frontend/src/routes/workspace/mod.rs new file mode 100644 index 000000000..6ee303024 --- /dev/null +++ b/hosted-frontend/src/routes/workspace/mod.rs @@ -0,0 +1,5 @@ +mod infrastructure; +mod runner; +mod workspace; + +pub use self::{infrastructure::*, runner::*, workspace::*}; diff --git a/hosted-frontend/src/routes/workspace/runner.rs b/hosted-frontend/src/routes/workspace/runner.rs new file mode 100644 index 000000000..d2355b6e6 --- /dev/null +++ b/hosted-frontend/src/routes/workspace/runner.rs @@ -0,0 +1,34 @@ +use models::utils::Uuid; + +use crate::CommonQueryParams; + +macros::declare_app_route! { + /// Route for Runners Dashboard Page + RunnerDashboard, + "/runner", + requires_login = true, + query = { + /// Common Query Parameters + #[serde(flatten)] + pub common: CommonQueryParams, + } +} + +macros::declare_app_route! { + /// Route for Runners Create Page + CreateRunner, + "/runner/create", + requires_login = true, + query = {} +} + +macros::declare_app_route! { + /// Route for Runners Details Page + ManageRunner, + "/runner/:runner_id" { + /// The id of the runner + pub runner_id: Uuid, + }, + requires_login = true, + query = {} +} diff --git a/hosted-frontend/src/routes/workspace/workspace/mod.rs b/hosted-frontend/src/routes/workspace/workspace/mod.rs new file mode 100644 index 000000000..347355adc --- /dev/null +++ b/hosted-frontend/src/routes/workspace/workspace/mod.rs @@ -0,0 +1,7 @@ +macros::declare_app_route! { + /// Route for Workspace Page + CreateWorkspace, + "/workspace/create", + requires_login = true, + query = {} +} From c28a7a97f16c6dcb86ce6261849993eb44937360 Mon Sep 17 00:00:00 2001 From: Argha Date: Fri, 27 Sep 2024 22:58:59 +0530 Subject: [PATCH 3/7] added documentation to some components --- hosted-frontend/src/pages/domain/mod.rs | 1 + hosted-frontend/src/pages/infrastructure/mod.rs | 3 +++ hosted-frontend/src/routes/mod.rs | 10 +++++++--- hosted-frontend/src/utils/routes.rs | 3 +++ 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/hosted-frontend/src/pages/domain/mod.rs b/hosted-frontend/src/pages/domain/mod.rs index 3402add5a..f21534ad6 100644 --- a/hosted-frontend/src/pages/domain/mod.rs +++ b/hosted-frontend/src/pages/domain/mod.rs @@ -2,6 +2,7 @@ use leptos_router::*; use crate::prelude::*; +/// The Routes for the Domain Configuration #[component(transparent)] pub fn DomainConfigurationRoutes() -> impl IntoView { view! { diff --git a/hosted-frontend/src/pages/infrastructure/mod.rs b/hosted-frontend/src/pages/infrastructure/mod.rs index 413dc1d16..36575f2cc 100644 --- a/hosted-frontend/src/pages/infrastructure/mod.rs +++ b/hosted-frontend/src/pages/infrastructure/mod.rs @@ -2,6 +2,9 @@ use leptos_router::*; use crate::prelude::*; +/// The Routes for the Infrastructure Pages, +/// Contains Secrets, Databases, Deployments, Static Sites, Repository, and +/// Container Registry #[component(transparent)] pub fn InfrastructureRoutes() -> impl IntoView { view! { diff --git a/hosted-frontend/src/routes/mod.rs b/hosted-frontend/src/routes/mod.rs index 1e542be7b..070d9d855 100644 --- a/hosted-frontend/src/routes/mod.rs +++ b/hosted-frontend/src/routes/mod.rs @@ -20,24 +20,28 @@ pub use self::{ workspaced_content::*, }; +/// The direction of the sort #[derive( Debug, Clone, Serialize, Deserialize, PartialEq, Eq, strum::Display, strum::EnumString, )] #[strum(serialize_all = "camelCase")] pub enum SortDirection { + /// Sort in ascending order Ascending, + /// Sort in descending order Descending, } +/// Common query parameters for all routes #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)] pub struct CommonQueryParams { /// The Page number to fetch #[serde(skip_serializing_if = "Option::is_none")] pub page: Option, - /// The Sorting order of the deployments + /// The Sorting order of the resource #[serde(skip_serializing_if = "Option::is_none")] pub order: Option, - /// Filter the deployments by date + /// Filter the resource by the given query #[serde(skip_serializing_if = "Option::is_none")] - pub query: Option>, + pub query: Option, } diff --git a/hosted-frontend/src/utils/routes.rs b/hosted-frontend/src/utils/routes.rs index c3a6302c2..9f001ac99 100644 --- a/hosted-frontend/src/utils/routes.rs +++ b/hosted-frontend/src/utils/routes.rs @@ -8,6 +8,8 @@ pub enum AppRoutes { /// The Empty Route, Used for fallback routes. #[default] Empty, + /// The Not Found Route + NotFound, /// The routes that can be taken when the user is logged out. LoggedOutRoute(LoggedOutRoute), /// The routes that can be taken when the user is logged in. @@ -76,6 +78,7 @@ pub enum LoggedOutRoute { impl Display for AppRoutes { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { + Self::NotFound => write!(f, "/*any"), Self::Empty => write!(f, "/"), Self::LoggedInRoute(logged_in_routes) => { write!(f, "{}", logged_in_routes) From 08d83359a75fee2cb369155c6068331d2ad74301 Mon Sep 17 00:00:00 2001 From: Argha Date: Fri, 27 Sep 2024 23:08:02 +0530 Subject: [PATCH 4/7] added sidebar items to sidebar --- components/src/sidebar/sidebar.rs | 87 +--------- .../src/routes/workspaced_content.rs | 4 +- hosted-frontend/src/utils/sidebar_items.rs | 158 ++++++++++++++++++ 3 files changed, 164 insertions(+), 85 deletions(-) create mode 100644 hosted-frontend/src/utils/sidebar_items.rs diff --git a/components/src/sidebar/sidebar.rs b/components/src/sidebar/sidebar.rs index 8bd7fcc3c..b7df28599 100644 --- a/components/src/sidebar/sidebar.rs +++ b/components/src/sidebar/sidebar.rs @@ -20,90 +20,9 @@ pub struct LinkItem { pub fn Sidebar( /// Workspace Card children: ChildrenFn, + /// The Sidebar Items + sidebar_items: Vec, ) -> impl IntoView { - let links: Vec = vec![ - LinkItem { - title: "Home".to_owned(), - path: "/".to_owned(), - icon_src: "/images/sidebar/home.svg".to_owned(), - subtitle: None, - items: None, - }, - LinkItem { - title: "Runners".to_owned(), - path: "/runners".to_owned(), - icon_src: "/images/sidebar/runner.svg".to_owned(), - subtitle: None, - items: None, - }, - LinkItem { - title: "Infrastructure".to_owned(), - path: "".to_owned(), - icon_src: "/images/sidebar/infrastructure.svg".to_owned(), - subtitle: None, - items: Some(vec![ - LinkItem { - title: "Deployments".to_owned(), - path: "/deployment".to_owned(), - subtitle: None, - icon_src: "/images/sidebar/deployment.svg".to_owned(), - items: None, - }, - LinkItem { - title: "Databases".to_owned(), - path: "/database".to_owned(), - subtitle: None, - icon_src: "/images/sidebar/database.svg".to_owned(), - items: None, - }, - ]), - }, - LinkItem { - title: "Domain Configuration".to_owned(), - path: "".to_owned(), - icon_src: "/images/sidebar/domains.svg".to_owned(), - subtitle: None, - items: Some(vec![ - LinkItem { - title: "Domains".to_owned(), - path: "/domain".to_owned(), - subtitle: None, - icon_src: "/images/sidebar/domains.svg".to_owned(), - items: None, - }, - LinkItem { - title: "Managed URLs".to_owned(), - icon_src: "/images/sidebar/managed-url.svg".to_owned(), - subtitle: None, - path: "/managed-url".to_owned(), - items: None, - }, - ]), - }, - LinkItem { - title: "User".to_owned(), - path: "/user".to_owned(), - icon_src: "/images/sidebar/workspace.svg".to_owned(), - subtitle: None, - items: Some(vec![ - LinkItem { - title: "Workspace".to_owned(), - icon_src: "/images/sidebar/workspace.svg".to_owned(), - subtitle: None, - path: "/workspace".to_owned(), - items: None, - }, - LinkItem { - title: "API Tokens".to_owned(), - icon_src: "/images/sidebar/secrets.svg".to_owned(), - subtitle: None, - path: "/user/api-tokens".to_owned(), - items: None, - }, - ]), - }, - ]; - view! {