* [pdm-devel] [PATCH yew-widget-toolkit/proxmox-api-types/pdm] overhaul remote wizard
@ 2024-12-19 12:09 Dominik Csapak
2024-12-19 12:09 ` [pdm-devel] [PATCH yew-widget-toolkit 1/1] widget: input panel: use correct column for custom childs Dominik Csapak
` (5 more replies)
0 siblings, 6 replies; 11+ messages in thread
From: Dominik Csapak @ 2024-12-19 12:09 UTC (permalink / raw)
To: pdm-devel
reorganize how the wizard is setup, by
* first only requiring hostname (+ fingerprint)
* then require a name + credentials
* then the endpoint list as before
* then the summary as before
Not super sure about the name for the 'realms' api endpoint, maybe
'scan-realms' or something would be better?
The widget toolkit patch is not strictly required, but the layout with
the radio buttons is slightly incorrect without it.
promxox-yew-widget-toolkit:
Dominik Csapak (1):
widget: input panel: use correct column for custom childs
src/widget/input_panel.rs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
promxox-api-types:
Dominik Csapak (1):
add /access/domains GET call
pve-api-types/generate.pl | 7 +++-
pve-api-types/src/generated/code.rs | 12 ++++++-
pve-api-types/src/generated/types.rs | 51 ++++++++++++++++++++++++++++
3 files changed, 68 insertions(+), 2 deletions(-)
proxmox-datacenter-manager:
Dominik Csapak (3):
server: api: add 'realms' add point for PVE
pdm-client: expose `ListRealm` type
ui: restructure wizard to have a better flow
lib/pdm-client/src/lib.rs | 2 +
server/src/api/pve/mod.rs | 52 +++-
ui/src/remotes/add_wizard.rs | 37 ++-
ui/src/remotes/mod.rs | 5 +-
ui/src/remotes/wizard_page_connect.rs | 115 ++++-----
ui/src/remotes/wizard_page_info.rs | 336 ++++++++++++++++++++++----
6 files changed, 415 insertions(+), 132 deletions(-)
--
2.39.5
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 11+ messages in thread
* [pdm-devel] [PATCH yew-widget-toolkit 1/1] widget: input panel: use correct column for custom childs
2024-12-19 12:09 [pdm-devel] [PATCH yew-widget-toolkit/proxmox-api-types/pdm] overhaul remote wizard Dominik Csapak
@ 2024-12-19 12:09 ` Dominik Csapak
2024-12-19 12:22 ` [pdm-devel] applied: " Thomas Lamprecht
2024-12-19 12:09 ` [pdm-devel] [PATCH proxmox-api-types 1/1] add /access/domains GET call Dominik Csapak
` (4 subsequent siblings)
5 siblings, 1 reply; 11+ messages in thread
From: Dominik Csapak @ 2024-12-19 12:09 UTC (permalink / raw)
To: pdm-devel
we added a 'padding column' recently, and we forgot to adapt
the custom childs for that.
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
technically not required, but otherwise the radiobuttons
in pdm ui patch are not properly placed.
src/widget/input_panel.rs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/widget/input_panel.rs b/src/widget/input_panel.rs
index b69579e..5f2868f 100644
--- a/src/widget/input_panel.rs
+++ b/src/widget/input_panel.rs
@@ -133,12 +133,12 @@ impl InputPanel {
let (row, start, span) = match column {
FieldPosition::Left => {
self.left_count += 1;
- (self.left_count, 1, 3)
+ (self.left_count, 1, 4)
}
FieldPosition::Right => {
self.two_column = true;
self.right_count += 1;
- (self.right_count, 3, -1)
+ (self.right_count, 4, -1)
}
FieldPosition::Large => {
self.two_column = true;
--
2.39.5
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 11+ messages in thread
* [pdm-devel] [PATCH proxmox-api-types 1/1] add /access/domains GET call
2024-12-19 12:09 [pdm-devel] [PATCH yew-widget-toolkit/proxmox-api-types/pdm] overhaul remote wizard Dominik Csapak
2024-12-19 12:09 ` [pdm-devel] [PATCH yew-widget-toolkit 1/1] widget: input panel: use correct column for custom childs Dominik Csapak
@ 2024-12-19 12:09 ` Dominik Csapak
2024-12-19 12:22 ` [pdm-devel] applied: " Thomas Lamprecht
2024-12-19 12:09 ` [pdm-devel] [PATCH datacenter-manager 1/3] server: api: add 'realms' add point for PVE Dominik Csapak
` (3 subsequent siblings)
5 siblings, 1 reply; 11+ messages in thread
From: Dominik Csapak @ 2024-12-19 12:09 UTC (permalink / raw)
To: pdm-devel
so we can query remote realms
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
pve-api-types/generate.pl | 7 +++-
pve-api-types/src/generated/code.rs | 12 ++++++-
pve-api-types/src/generated/types.rs | 51 ++++++++++++++++++++++++++++
3 files changed, 68 insertions(+), 2 deletions(-)
diff --git a/pve-api-types/generate.pl b/pve-api-types/generate.pl
index e72898e..4c8e164 100644
--- a/pve-api-types/generate.pl
+++ b/pve-api-types/generate.pl
@@ -280,7 +280,12 @@ Schema2Rust::register_api_extensions('ClusterJoinInfo', {
api(GET => '/cluster/config/join', 'cluster_config_join', 'return-name' => 'ClusterJoinInfo');
# api(GET => '/storage', 'list_storages', 'return-name' => 'StorageList');
-# api(GET => '/access/domains', 'list_domains', 'return-name' => 'ListRealm');
+Schema2Rust::register_api_extensions('ListRealm', {
+ '/properties/realm' => { description => sq("FIXME: Missing description in PVE.") },
+ '/properties/type' => { description => sq("FIXME: Missing description in PVE.") },
+});
+api(GET => '/access/domains', 'list_domains', 'return-name' => 'ListRealm');
+Schema2Rust::derive('ListRealm' => 'Clone', 'PartialEq');
# api(GET => '/access/groups', 'list_groups', 'return-name' => 'ListGroups');
# api(GET => '/access/groups/{groupid}', 'get_group', 'return-name' => 'Group');
# api(GET => '/access/users', 'list_users', 'return-name' => 'ListUsers');
diff --git a/pve-api-types/src/generated/code.rs b/pve-api-types/src/generated/code.rs
index 33317a3..dc17cd9 100644
--- a/pve-api-types/src/generated/code.rs
+++ b/pve-api-types/src/generated/code.rs
@@ -4,7 +4,6 @@
/// ```text
/// - /access
/// - /access/acl
-/// - /access/domains
/// - /access/domains/{realm}
/// - /access/domains/{realm}/sync
/// - /access/groups
@@ -438,6 +437,11 @@ pub trait PveClient {
Err(Error::Other("get_task_status not implemented"))
}
+ /// Authentication domain index.
+ async fn list_domains(&self) -> Result<Vec<ListRealm>, Error> {
+ Err(Error::Other("list_domains not implemented"))
+ }
+
/// LXC container index (per node).
async fn list_lxc(&self, node: &str) -> Result<Vec<LxcEntry>, Error> {
Err(Error::Other("list_lxc not implemented"))
@@ -758,6 +762,12 @@ where
Ok(self.0.get(&url).await?.expect_json()?.data)
}
+ /// Authentication domain index.
+ async fn list_domains(&self) -> Result<Vec<ListRealm>, Error> {
+ let url = format!("/api2/extjs/access/domains");
+ Ok(self.0.get(&url).await?.expect_json()?.data)
+ }
+
/// LXC container index (per node).
async fn list_lxc(&self, node: &str) -> Result<Vec<LxcEntry>, Error> {
let url = format!("/api2/extjs/nodes/{node}/lxc");
diff --git a/pve-api-types/src/generated/types.rs b/pve-api-types/src/generated/types.rs
index 06d9fe3..76c66b5 100644
--- a/pve-api-types/src/generated/types.rs
+++ b/pve-api-types/src/generated/types.rs
@@ -969,6 +969,57 @@ pub enum ListNetworksType {
serde_plain::derive_display_from_serialize!(ListNetworksType);
serde_plain::derive_fromstr_from_deserialize!(ListNetworksType);
+#[api(
+ properties: {
+ comment: {
+ optional: true,
+ type: String,
+ },
+ realm: {
+ type: String,
+ description: "FIXME: Missing description in PVE.",
+ },
+ tfa: {
+ optional: true,
+ type: ListRealmTfa,
+ },
+ type: {
+ type: String,
+ description: "FIXME: Missing description in PVE.",
+ },
+ },
+)]
+/// Object.
+#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
+pub struct ListRealm {
+ /// A comment. The GUI use this text when you select a domain (Realm) on the
+ /// login window.
+ #[serde(default, skip_serializing_if = "Option::is_none")]
+ pub comment: Option<String>,
+
+ pub realm: String,
+
+ #[serde(default, skip_serializing_if = "Option::is_none")]
+ pub tfa: Option<ListRealmTfa>,
+
+ #[serde(rename = "type")]
+ pub ty: String,
+}
+
+#[api]
+/// Two-factor authentication provider.
+#[derive(Clone, Copy, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
+pub enum ListRealmTfa {
+ #[serde(rename = "yubico")]
+ /// yubico.
+ Yubico,
+ #[serde(rename = "oath")]
+ /// oath.
+ Oath,
+}
+serde_plain::derive_display_from_serialize!(ListRealmTfa);
+serde_plain::derive_fromstr_from_deserialize!(ListRealmTfa);
+
const_regex! {
LIST_TASKS_STATUSFILTER_RE = r##"^(?i:ok|error|warning|unknown)$"##;
--
2.39.5
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 11+ messages in thread
* [pdm-devel] [PATCH datacenter-manager 1/3] server: api: add 'realms' add point for PVE
2024-12-19 12:09 [pdm-devel] [PATCH yew-widget-toolkit/proxmox-api-types/pdm] overhaul remote wizard Dominik Csapak
2024-12-19 12:09 ` [pdm-devel] [PATCH yew-widget-toolkit 1/1] widget: input panel: use correct column for custom childs Dominik Csapak
2024-12-19 12:09 ` [pdm-devel] [PATCH proxmox-api-types 1/1] add /access/domains GET call Dominik Csapak
@ 2024-12-19 12:09 ` Dominik Csapak
2024-12-19 12:09 ` [pdm-devel] [PATCH datacenter-manager 2/3] pdm-client: expose `ListRealm` type Dominik Csapak
` (2 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Dominik Csapak @ 2024-12-19 12:09 UTC (permalink / raw)
To: pdm-devel
similar to 'scan' where we can scan the realms of a 'not-yet' remote host
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
server/src/api/pve/mod.rs | 52 +++++++++++++++++++++++++++++++++++++--
1 file changed, 50 insertions(+), 2 deletions(-)
diff --git a/server/src/api/pve/mod.rs b/server/src/api/pve/mod.rs
index 7ab529c..81fdf76 100644
--- a/server/src/api/pve/mod.rs
+++ b/server/src/api/pve/mod.rs
@@ -23,7 +23,8 @@ use pdm_api_types::{
use pve_api_types::client::PveClient;
use pve_api_types::{
- ClusterResourceKind, ClusterResourceType, QemuMigratePreconditions, StartQemuMigrationType,
+ ClusterResourceKind, ClusterResourceType, ListRealm, QemuMigratePreconditions,
+ StartQemuMigrationType,
};
use super::resources::{map_pve_lxc, map_pve_node, map_pve_qemu, map_pve_storage};
@@ -41,7 +42,11 @@ pub const ROUTER: Router = Router::new()
#[sortable]
const SUBDIRS: SubdirMap = &sorted!([
("remotes", &REMOTES_ROUTER),
- ("scan", &Router::new().post(&API_METHOD_SCAN_REMOTE_PVE))
+ ("scan", &Router::new().post(&API_METHOD_SCAN_REMOTE_PVE)),
+ (
+ "realms",
+ &Router::new().post(&API_METHOD_LIST_REALM_REMOTE_PVE)
+ )
]);
pub const REMOTES_ROUTER: Router = Router::new().match_all("remote", &MAIN_ROUTER);
@@ -1338,3 +1343,46 @@ pub async fn scan_remote_pve(
Ok(remote)
}
+
+#[api(
+ input: {
+ properties: {
+ hostname: {
+ type: String,
+ format: &HOST_OPTIONAL_PORT_FORMAT,
+ description: "Hostname (with optional port) of the target remote",
+ },
+ fingerprint: {
+ type: String,
+ description: "Fingerprint of the target remote.",
+ optional: true,
+ },
+ },
+ },
+ access: {
+ permission:
+ &Permission::Privilege(&["/"], PRIV_SYS_MODIFY, false),
+ },
+)]
+/// Scans the given connection info for pve cluster information
+pub async fn list_realm_remote_pve(
+ hostname: String,
+ fingerprint: Option<String>,
+) -> Result<Vec<ListRealm>, Error> {
+ // dummy remote to connect
+ let remote = Remote {
+ ty: RemoteType::Pve,
+ id: String::new(),
+ nodes: vec![PropertyString::new(NodeUrl {
+ hostname,
+ fingerprint,
+ })],
+ authid: "root@pam".parse()?,
+ token: String::new(),
+ };
+
+ let client = connection::make_pve_client(&remote)?;
+ let list = client.list_domains().await?;
+
+ Ok(list)
+}
--
2.39.5
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 11+ messages in thread
* [pdm-devel] [PATCH datacenter-manager 2/3] pdm-client: expose `ListRealm` type
2024-12-19 12:09 [pdm-devel] [PATCH yew-widget-toolkit/proxmox-api-types/pdm] overhaul remote wizard Dominik Csapak
` (2 preceding siblings ...)
2024-12-19 12:09 ` [pdm-devel] [PATCH datacenter-manager 1/3] server: api: add 'realms' add point for PVE Dominik Csapak
@ 2024-12-19 12:09 ` Dominik Csapak
2024-12-19 12:09 ` [pdm-devel] [PATCH datacenter-manager 3/3] ui: restructure wizard to have a better flow Dominik Csapak
2024-12-19 12:31 ` [pdm-devel] applied: [PATCH yew-widget-toolkit/proxmox-api-types/pdm] overhaul remote wizard Thomas Lamprecht
5 siblings, 0 replies; 11+ messages in thread
From: Dominik Csapak @ 2024-12-19 12:09 UTC (permalink / raw)
To: pdm-devel
so we can use it in the ui
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
lib/pdm-client/src/lib.rs | 2 ++
1 file changed, 2 insertions(+)
diff --git a/lib/pdm-client/src/lib.rs b/lib/pdm-client/src/lib.rs
index a2d8ee7..14e6fc8 100644
--- a/lib/pdm-client/src/lib.rs
+++ b/lib/pdm-client/src/lib.rs
@@ -50,6 +50,8 @@ pub mod types {
QemuMigratePreconditions, QemuMigratePreconditionsLocalDisks,
QemuMigratePreconditionsNotAllowedNodes,
};
+
+ pub use pve_api_types::ListRealm;
}
pub struct PdmClient<T: HttpApiClient>(pub T);
--
2.39.5
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 11+ messages in thread
* [pdm-devel] [PATCH datacenter-manager 3/3] ui: restructure wizard to have a better flow
2024-12-19 12:09 [pdm-devel] [PATCH yew-widget-toolkit/proxmox-api-types/pdm] overhaul remote wizard Dominik Csapak
` (3 preceding siblings ...)
2024-12-19 12:09 ` [pdm-devel] [PATCH datacenter-manager 2/3] pdm-client: expose `ListRealm` type Dominik Csapak
@ 2024-12-19 12:09 ` Dominik Csapak
2024-12-19 12:31 ` [pdm-devel] applied: [PATCH yew-widget-toolkit/proxmox-api-types/pdm] overhaul remote wizard Thomas Lamprecht
5 siblings, 0 replies; 11+ messages in thread
From: Dominik Csapak @ 2024-12-19 12:09 UTC (permalink / raw)
To: pdm-devel
instead of entering all connection info on the first page, just require
the hostname/port (+fingerprint). Then on the second page, require an id
and either user/password/realm/new tokenname or existing token/secret.
the third page is then the endpoint list, and the summary stayed the
same.
This requires a bit of restructuring of the place and way we collect the
information.
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
without patch 1 for yew-widget-toolkit, the right radio button is not
correctly placed.
ui/src/remotes/add_wizard.rs | 37 ++-
ui/src/remotes/mod.rs | 5 +-
ui/src/remotes/wizard_page_connect.rs | 115 ++++-----
ui/src/remotes/wizard_page_info.rs | 336 ++++++++++++++++++++++----
4 files changed, 363 insertions(+), 130 deletions(-)
diff --git a/ui/src/remotes/add_wizard.rs b/ui/src/remotes/add_wizard.rs
index f8c9bba..f4bf9a3 100644
--- a/ui/src/remotes/add_wizard.rs
+++ b/ui/src/remotes/add_wizard.rs
@@ -13,7 +13,10 @@ use proxmox_yew_comp::{
};
use yew::virtual_dom::VNode;
-use super::{WizardPageConnect, WizardPageInfo, WizardPageNodes, WizardPageSummary};
+use super::{
+ wizard_page_connect::ConnectParams, WizardPageConnect, WizardPageInfo, WizardPageNodes,
+ WizardPageSummary,
+};
use pwt_macros::builder;
@@ -51,9 +54,11 @@ impl AddWizard {
pub enum Msg {
ServerChange(Option<Remote>),
+ ConnectChange(Option<ConnectParams>),
}
pub struct AddWizardState {
server_info: Option<Remote>,
+ connect_info: Option<ConnectParams>,
}
impl Component for AddWizardState {
@@ -61,7 +66,10 @@ impl Component for AddWizardState {
type Properties = AddWizard;
fn create(_ctx: &Context<Self>) -> Self {
- Self { server_info: None }
+ Self {
+ server_info: None,
+ connect_info: None,
+ }
}
fn update(&mut self, _ctx: &Context<Self>, msg: Self::Message) -> bool {
@@ -69,6 +77,9 @@ impl Component for AddWizardState {
Msg::ServerChange(server_info) => {
self.server_info = server_info;
}
+ Msg::ConnectChange(realms) => {
+ self.connect_info = realms;
+ }
}
true
}
@@ -93,11 +104,21 @@ impl Component for AddWizardState {
let link = ctx.link().clone();
move |p: &WizardPageRenderInfo| {
WizardPageConnect::new(p.clone(), remote_type)
- .on_server_change(link.callback(Msg::ServerChange))
+ .on_connect_change(link.callback(Msg::ConnectChange))
.into()
}
},
- );
+ )
+ .with_page(TabBarItem::new().key("info").label(tr!("Settings")), {
+ let realms = self.connect_info.clone();
+ let link = ctx.link().clone();
+ move |p: &WizardPageRenderInfo| {
+ WizardPageInfo::new(p.clone())
+ .connect_info(realms.clone())
+ .on_server_change(link.callback(Msg::ServerChange))
+ .into()
+ }
+ });
if remote_type == RemoteType::Pve {
wizard = wizard.with_page(TabBarItem::new().key("nodes").label(tr!("Endpoints")), {
@@ -111,14 +132,6 @@ impl Component for AddWizardState {
}
wizard
- .with_page(TabBarItem::new().key("info").label(tr!("Settings")), {
- let server_info = self.server_info.clone();
- move |p: &WizardPageRenderInfo| {
- WizardPageInfo::new(p.clone())
- .server_info(server_info.clone())
- .into()
- }
- })
.with_page(TabBarItem::new().label(tr!("Summary")), {
let server_info = self.server_info.clone();
move |p: &WizardPageRenderInfo| {
diff --git a/ui/src/remotes/mod.rs b/ui/src/remotes/mod.rs
index c9a4e43..cc91b3f 100644
--- a/ui/src/remotes/mod.rs
+++ b/ui/src/remotes/mod.rs
@@ -261,7 +261,10 @@ impl LoadableComponent for PbsRemoteConfigPanel {
ConfirmDialog::new()
.title(tr!("Confirm: Remove Remote"))
.confirm_text(tr!("Remove"))
- .confirm_message(tr!("Are you sure you want to remove the remote '{0}' ?", key))
+ .confirm_message(tr!(
+ "Are you sure you want to remove the remote '{0}' ?",
+ key
+ ))
.on_confirm(ctx.link().callback(|_| Msg::RemoveItem))
.on_done(ctx.link().change_view_callback(|_| None))
.into()
diff --git a/ui/src/remotes/wizard_page_connect.rs b/ui/src/remotes/wizard_page_connect.rs
index ebcae8c..28f14bf 100644
--- a/ui/src/remotes/wizard_page_connect.rs
+++ b/ui/src/remotes/wizard_page_connect.rs
@@ -1,22 +1,21 @@
use std::rc::Rc;
-use anyhow::Error;
+use anyhow::{bail, Error};
use serde::{Deserialize, Serialize};
+use serde_json::json;
use yew::html::IntoEventCallback;
use yew::virtual_dom::{Key, VComp, VNode};
use pwt::css::{AlignItems, FlexFit};
-use pwt::widget::form::{Field, FormContext, FormContextObserver, InputType};
+use pwt::widget::form::{Field, FormContext, FormContextObserver};
use pwt::widget::{error_message, Button, Column, Container, InputPanel, Mask, Row};
use pwt::{prelude::*, AsyncPool};
use proxmox_yew_comp::{SchemaValidation, WizardPageRenderInfo};
-use proxmox_schema::property_string::PropertyString;
-use proxmox_schema::ApiType;
-
-use pdm_api_types::remotes::{NodeUrl, Remote, RemoteType};
+use pdm_api_types::remotes::RemoteType;
use pdm_api_types::CERT_FINGERPRINT_SHA256_SCHEMA;
+use pdm_client::types::ListRealm;
use pwt_macros::builder;
@@ -25,9 +24,9 @@ use pwt_macros::builder;
pub struct WizardPageConnect {
info: WizardPageRenderInfo,
- #[builder_cb(IntoEventCallback, into_event_callback, Option<Remote>)]
+ #[builder_cb(IntoEventCallback, into_event_callback, Option<ConnectParams>)]
#[prop_or_default]
- pub on_server_change: Option<Callback<Option<Remote>>>,
+ pub on_connect_change: Option<Callback<Option<ConnectParams>>>,
remote_type: RemoteType,
}
@@ -38,35 +37,32 @@ impl WizardPageConnect {
}
}
-async fn scan(connect: ConnectParams) -> Result<Remote, Error> {
- let params = serde_json::to_value(&connect)?;
- let mut result: Remote = proxmox_yew_comp::http_post("/pve/scan", Some(params)).await?;
-
- // insert the initial connection too, since we know that works
- result.nodes.insert(
- 0,
- PropertyString::new(NodeUrl {
- hostname: connect.hostname,
- fingerprint: connect.fingerprint,
- }),
- );
-
- result.nodes.sort_by(|a, b| a.hostname.cmp(&b.hostname));
+async fn list_realms(
+ hostname: String,
+ fingerprint: Option<String>,
+) -> Result<Vec<ListRealm>, Error> {
+ let mut params = json!({
+ "hostname": hostname,
+ });
+ if let Some(fp) = fingerprint {
+ params["fingerprint"] = fp.into();
+ }
+ let result: Vec<ListRealm> = proxmox_yew_comp::http_post("/pve/realms", Some(params)).await?;
Ok(result)
}
-#[derive(Deserialize, Serialize)]
+#[derive(PartialEq, Clone, Deserialize, Serialize)]
/// Parameters for connect call.
pub struct ConnectParams {
- hostname: String,
- authid: String,
- token: String,
+ pub hostname: String,
#[serde(skip_serializing_if = "Option::is_none")]
- fingerprint: Option<String>,
+ pub fingerprint: Option<String>,
+ #[serde(default)]
+ pub realms: Vec<ListRealm>,
}
-async fn connect(form_ctx: FormContext, remote_type: RemoteType) -> Result<Remote, Error> {
+async fn connect(form_ctx: FormContext, remote_type: RemoteType) -> Result<ConnectParams, Error> {
let data = form_ctx.get_submit_data();
let mut data: ConnectParams = serde_json::from_value(data.clone())?;
if let Some(hostname) = data.hostname.strip_prefix("http://") {
@@ -79,28 +75,22 @@ async fn connect(form_ctx: FormContext, remote_type: RemoteType) -> Result<Remot
data.hostname = hostname.to_string();
}
- Ok(match remote_type {
- RemoteType::Pve => scan(data).await?,
- RemoteType::Pbs => Remote {
- ty: remote_type,
- id: data.hostname.clone(),
- authid: data.authid.parse()?,
- token: data.token,
- nodes: vec![PropertyString::new(NodeUrl {
- hostname: data.hostname,
- fingerprint: data.fingerprint,
- })],
- },
- })
+ let realms = match remote_type {
+ RemoteType::Pve => list_realms(data.hostname.clone(), data.fingerprint.clone()).await?,
+ RemoteType::Pbs => bail!("not implemented"),
+ };
+
+ data.realms = realms;
+ Ok(data)
}
pub enum Msg {
FormChange,
Connect,
- ConnectResult(Result<Remote, Error>),
+ ConnectResult(Result<ConnectParams, Error>),
}
pub struct PdmWizardPageConnect {
- server_info: Option<Remote>,
+ connect_info: Option<ConnectParams>,
_form_observer: FormContextObserver,
form_valid: bool,
loading: bool,
@@ -109,12 +99,12 @@ pub struct PdmWizardPageConnect {
}
impl PdmWizardPageConnect {
- fn update_server_info(&mut self, ctx: &Context<Self>, server_info: Option<Remote>) {
+ fn update_connect_info(&mut self, ctx: &Context<Self>, info: Option<ConnectParams>) {
let props = ctx.props();
- self.server_info = server_info;
- props.info.page_lock(self.server_info.is_none());
- if let Some(on_server_change) = &props.on_server_change {
- on_server_change.emit(self.server_info.clone());
+ self.connect_info = info.clone();
+ props.info.page_lock(info.is_none());
+ if let Some(on_connect_change) = &props.on_connect_change {
+ on_connect_change.emit(info);
}
}
}
@@ -133,7 +123,7 @@ impl Component for PdmWizardPageConnect {
props.info.page_lock(true);
Self {
- server_info: None,
+ connect_info: None,
_form_observer,
form_valid: false,
loading: false,
@@ -149,7 +139,7 @@ impl Component for PdmWizardPageConnect {
self.form_valid = props.info.form_ctx.read().is_valid();
match props.remote_type {
RemoteType::Pve => {
- self.update_server_info(ctx, None);
+ self.update_connect_info(ctx, None);
}
RemoteType::Pbs => {
return <Self as yew::Component>::update(self, ctx, Msg::Connect)
@@ -158,7 +148,7 @@ impl Component for PdmWizardPageConnect {
}
Msg::Connect => {
let link = ctx.link().clone();
- self.update_server_info(ctx, None);
+ self.update_connect_info(ctx, None);
let form_ctx = props.info.form_ctx.clone();
self.loading = true;
self.last_error = None;
@@ -172,8 +162,8 @@ impl Component for PdmWizardPageConnect {
Msg::ConnectResult(server_info) => {
self.loading = false;
match server_info {
- Ok(server_info) => {
- self.update_server_info(ctx, Some(server_info));
+ Ok(connect_info) => {
+ self.update_connect_info(ctx, Some(connect_info));
}
Err(err) => {
self.last_error = Some(err);
@@ -196,28 +186,13 @@ impl Component for PdmWizardPageConnect {
// FIXME: input panel css style is not optimal here...
.width("auto")
.padding(4)
- .with_field(
+ .with_large_field(
tr!("Server Address"),
Field::new()
.name("hostname")
.placeholder(tr!("<IP/Hostname>:Port"))
.required(true),
)
- .with_right_field(
- tr!("User/Token"),
- Field::new()
- .name("authid")
- .placeholder(tr!("Example: user@pve!tokenid"))
- .schema(&pdm_api_types::Authid::API_SCHEMA)
- .required(true),
- )
- .with_right_field(
- tr!("Password/Secret"),
- Field::new()
- .name("token")
- .input_type(InputType::Password)
- .required(true),
- )
.with_large_field(
tr!("Fingerprint"),
Field::new()
@@ -242,7 +217,7 @@ impl Component for PdmWizardPageConnect {
)
.with_flex_spacer()
.with_optional_child(
- (self.last_error.is_none() && self.server_info.is_some())
+ (self.last_error.is_none() && self.connect_info.is_some())
.then_some(Container::new().with_child(tr!("Connection OK"))),
)
.with_child(
diff --git a/ui/src/remotes/wizard_page_info.rs b/ui/src/remotes/wizard_page_info.rs
index 7874eae..c67be78 100644
--- a/ui/src/remotes/wizard_page_info.rs
+++ b/ui/src/remotes/wizard_page_info.rs
@@ -1,30 +1,41 @@
use std::rc::Rc;
-use yew::virtual_dom::{VComp, VNode};
+use anyhow::Error;
+use html::IntoEventCallback;
+use proxmox_schema::property_string::PropertyString;
+use serde::{Deserialize, Serialize};
+use yew::virtual_dom::{Key, VComp, VNode};
+use proxmox_yew_comp::WizardPageRenderInfo;
use pwt::{
- css::FlexFit,
+ css::{self, FlexFit},
prelude::*,
widget::{
- form::{Checkbox, Field},
- InputPanel,
+ error_message,
+ form::{Combobox, Field, FormContext, FormContextObserver, InputType, RadioButton},
+ Button, Column, Container, InputPanel, Mask, Row,
},
+ AsyncPool,
};
-use proxmox_yew_comp::WizardPageRenderInfo;
-
-use pdm_api_types::{remotes::Remote, Authid};
+use pdm_api_types::remotes::{NodeUrl, Remote};
use pwt_macros::builder;
+use super::wizard_page_connect::ConnectParams;
+
#[derive(Clone, PartialEq, Properties)]
#[builder]
pub struct WizardPageInfo {
info: WizardPageRenderInfo,
+ #[builder_cb(IntoEventCallback, into_event_callback, Option<Remote>)]
+ #[prop_or_default]
+ pub on_server_change: Option<Callback<Option<Remote>>>,
+
#[builder]
#[prop_or_default]
- server_info: Option<Remote>,
+ connect_info: Option<ConnectParams>,
}
impl WizardPageInfo {
@@ -34,11 +45,102 @@ impl WizardPageInfo {
}
pub struct PdmWizardPageInfo {
- create_token: bool,
+ user_mode: bool,
+ realms: Rc<Vec<AttrValue>>,
+ server_info: Option<Remote>,
+ last_error: Option<Error>,
+ credentials: Option<(String, String)>,
+ loading: bool,
+ _form_observer: FormContextObserver,
+ async_pool: AsyncPool,
}
pub enum Msg {
ToggleCreateToken(bool),
+ FormChange,
+ Connect,
+ ConnectResult(Result<Remote, Error>),
+}
+
+#[derive(Deserialize, Serialize)]
+/// Parameters for connect call.
+pub struct ScanParams {
+ hostname: String,
+ authid: String,
+ token: String,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ fingerprint: Option<String>,
+}
+
+fn create_realm_list(props: &WizardPageInfo) -> Rc<Vec<AttrValue>> {
+ if let Some(info) = &props.connect_info {
+ let realms = Rc::new(
+ info.realms
+ .iter()
+ .map(|realm| AttrValue::from(realm.realm.clone()))
+ .collect(),
+ );
+ realms
+ } else {
+ Rc::new(Vec::new())
+ }
+}
+
+async fn scan(connection_params: ConnectParams, form_ctx: FormContext) -> Result<Remote, Error> {
+ let mut data = form_ctx.get_submit_data();
+
+ data["hostname"] = connection_params.hostname.into();
+ if let Some(fp) = connection_params.fingerprint {
+ data["fingerprint"] = fp.into();
+ }
+
+ let data: ScanParams = serde_json::from_value(data.clone())?;
+
+ let params = serde_json::to_value(&data)?;
+ let mut result: Remote = proxmox_yew_comp::http_post("/pve/scan", Some(params)).await?;
+ result.nodes.insert(
+ 0,
+ PropertyString::new(NodeUrl {
+ hostname: data.hostname,
+ fingerprint: data.fingerprint,
+ }),
+ );
+ result.nodes.sort_by(|a, b| a.hostname.cmp(&b.hostname));
+ Ok(result)
+}
+
+impl PdmWizardPageInfo {
+ fn update_credentials(form_ctx: &FormContext) {
+ let user = form_ctx.read().get_field_text("user");
+ let realm = form_ctx.read().get_field_text("realm");
+ let password = form_ctx.read().get_field_text("password");
+
+ let user_mode = form_ctx.read().get_field_text("login-mode") == "login";
+
+ let tokenid = form_ctx.read().get_field_text("tokenid");
+ let secret = form_ctx.read().get_field_text("secret");
+
+ let (authid, token) =
+ if user_mode && !user.is_empty() && !realm.is_empty() && !password.is_empty() {
+ (format!("{user}@{realm}").into(), password.into())
+ } else if !user_mode && !tokenid.is_empty() && !secret.is_empty() {
+ (tokenid.into(), secret.into())
+ } else {
+ (serde_json::Value::Null, serde_json::Value::Null)
+ };
+
+ form_ctx.write().set_field_value("authid", authid);
+ form_ctx.write().set_field_value("token", token);
+ }
+
+ fn update_server_info(&mut self, ctx: &Context<Self>, server_info: Option<Remote>) {
+ let props = ctx.props();
+ self.server_info = server_info;
+ props.info.page_lock(self.server_info.is_none());
+ if let Some(on_server_change) = &props.on_server_change {
+ on_server_change.emit(self.server_info.clone());
+ }
+ }
}
impl Component for PdmWizardPageInfo {
@@ -47,67 +149,207 @@ impl Component for PdmWizardPageInfo {
fn create(ctx: &Context<Self>) -> Self {
let props = ctx.props();
- if props.server_info.is_none() {
- props.info.page_lock(true);
- }
- Self { create_token: true }
+ props.info.page_lock(true);
+
+ let _form_observer = props
+ .info
+ .form_ctx
+ .add_listener(ctx.link().callback(|_| Msg::FormChange));
+
+ Self {
+ server_info: None,
+ user_mode: true,
+ realms: create_realm_list(props),
+ _form_observer,
+ last_error: None,
+ loading: false,
+ credentials: None,
+ async_pool: AsyncPool::new(),
+ }
}
- fn update(&mut self, _ctx: &Context<Self>, msg: Self::Message) -> bool {
+ fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
+ let props = ctx.props();
match msg {
Msg::ToggleCreateToken(create_token) => {
- self.create_token = create_token;
+ self.user_mode = create_token;
+ }
+ Msg::FormChange => {
+ let form_ctx = &props.info.form_ctx;
+ Self::update_credentials(form_ctx);
+ let authid = form_ctx.read().get_field_text("authid");
+ let token = form_ctx.read().get_field_text("token");
+ if !authid.is_empty() && !token.is_empty() {
+ match &self.credentials {
+ Some((old_auth, old_token))
+ if *old_auth == authid && *old_token == token => {}
+ Some(_) | None => {
+ self.credentials = Some((authid, token));
+ self.update_server_info(ctx, None);
+ }
+ }
+ } else {
+ self.credentials = None;
+ }
+ }
+ Msg::Connect => {
+ let link = ctx.link().clone();
+ self.update_server_info(ctx, None);
+ let form_ctx = props.info.form_ctx.clone();
+ self.loading = true;
+ self.last_error = None;
+
+ if let Some(connection_info) = props.connect_info.clone() {
+ self.async_pool.spawn(async move {
+ let result = scan(connection_info, form_ctx).await;
+ link.send_message(Msg::ConnectResult(result));
+ });
+ } else {
+ unreachable!("Settings page must have connection info");
+ }
+ }
+ Msg::ConnectResult(server_info) => {
+ self.loading = false;
+ match server_info {
+ Ok(server_info) => {
+ self.update_server_info(ctx, Some(server_info));
+ }
+ Err(err) => {
+ self.last_error = Some(err);
+ }
+ }
+
+ if let Some(form_ctx) = props.info.lookup_form_context(&Key::from("nodes")) {
+ form_ctx.write().reset_form();
+ }
+ props.info.reset_remaining_valid_pages();
}
}
true
}
+ fn changed(&mut self, ctx: &Context<Self>, _old_props: &Self::Properties) -> bool {
+ self.realms = create_realm_list(ctx.props());
+ true
+ }
+
fn view(&self, ctx: &Context<Self>) -> Html {
- let mut is_user = true;
- if let Some(Some(authid)) = ctx
- .props()
- .info
- .valid_data
- .get("authid")
- .map(|a| a.as_str())
- {
- match authid.parse::<Authid>() {
- Ok(authid) => is_user = !authid.is_token(),
- Err(_) => {}
- }
- }
- let name = ctx
- .props()
- .server_info
- .as_ref()
- .map(|s| s.id.to_string())
- .unwrap_or_default();
- InputPanel::new()
+ let input_panel = InputPanel::new()
.class(FlexFit)
.padding(4)
+ .with_field(tr!("Remote ID"), Field::new().name("id").required(true))
+ .with_custom_child(
+ RadioButton::new("login")
+ .key("login-mode-login")
+ .name("login-mode")
+ .default(true)
+ .box_label(tr!("Login and create Token"))
+ .on_change(
+ ctx.link()
+ .callback(|value| Msg::ToggleCreateToken(value == "login")),
+ ),
+ )
+ .with_field(
+ tr!("User"),
+ Field::new()
+ .name("user")
+ .disabled(!self.user_mode)
+ .required(self.user_mode)
+ .submit(false),
+ )
.with_field(
- tr!("Remote ID"),
- Field::new().default(name).name("id").required(true),
+ tr!("Password"),
+ Field::new()
+ .input_type(InputType::Password)
+ .name("password")
+ .disabled(!self.user_mode)
+ .required(self.user_mode)
+ .submit(false),
)
.with_field(
- tr!("Create API Token"),
- Checkbox::new()
- .key("create-token-cb")
- .submit(false)
- .disabled(is_user)
- .default(self.create_token || is_user)
- .on_change(ctx.link().callback(Msg::ToggleCreateToken)),
+ tr!("Realm"),
+ Combobox::new()
+ .name("realm")
+ .disabled(!self.user_mode)
+ .required(self.user_mode)
+ .items(self.realms.clone())
+ .submit(false),
)
.with_field(
tr!("API Token Name"),
Field::new()
.name("create-token")
- .disabled(!self.create_token && !is_user)
- .required(self.create_token || is_user)
- .submit(self.create_token || is_user)
+ .disabled(!self.user_mode)
+ .required(self.user_mode)
+ .submit(self.user_mode)
.default("pdm-admin"),
)
+ .with_right_custom_child(Container::new().key("spacer")) //spacer
+ .with_right_custom_child(
+ RadioButton::new("token")
+ .key("login-mode-token")
+ .name("login-mode")
+ .box_label(tr!("Use existing Token")),
+ )
+ .with_right_field(
+ tr!("Token"),
+ Field::new()
+ .name("tokenid")
+ .disabled(self.user_mode)
+ .required(!self.user_mode)
+ .submit(false),
+ )
+ .with_right_field(
+ tr!("Secret"),
+ Field::new()
+ .name("secret")
+ .input_type(InputType::Password)
+ .disabled(self.user_mode)
+ .required(!self.user_mode)
+ .submit(false),
+ )
+ .with_field_and_options(
+ pwt::widget::FieldPosition::Left,
+ false,
+ true,
+ tr!(""),
+ Field::new().name("token").required(true),
+ )
+ .with_field_and_options(
+ pwt::widget::FieldPosition::Left,
+ false,
+ true,
+ tr!(""),
+ Field::new().name("authid").required(true),
+ );
+ let content = Column::new()
+ .class(FlexFit)
+ .with_child(input_panel)
+ .with_child(
+ Row::new()
+ .padding(2)
+ .gap(2)
+ .class(css::AlignItems::Center)
+ .with_optional_child(
+ self.last_error
+ .as_deref()
+ .map(|err| error_message(&err.to_string())),
+ )
+ .with_flex_spacer()
+ .with_optional_child(
+ (self.last_error.is_none() && self.server_info.is_some())
+ .then_some(Container::new().with_child(tr!("Scan OK"))),
+ )
+ .with_child(
+ Button::new("Scan")
+ .disabled(self.credentials.is_none())
+ .onclick(ctx.link().callback(|_| Msg::Connect)),
+ ),
+ );
+ Mask::new(content)
+ .class(FlexFit)
+ .visible(self.loading)
.into()
}
}
--
2.39.5
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 11+ messages in thread
* [pdm-devel] applied: [PATCH yew-widget-toolkit 1/1] widget: input panel: use correct column for custom childs
2024-12-19 12:09 ` [pdm-devel] [PATCH yew-widget-toolkit 1/1] widget: input panel: use correct column for custom childs Dominik Csapak
@ 2024-12-19 12:22 ` Thomas Lamprecht
0 siblings, 0 replies; 11+ messages in thread
From: Thomas Lamprecht @ 2024-12-19 12:22 UTC (permalink / raw)
To: Proxmox Datacenter Manager development discussion, Dominik Csapak
Am 19.12.24 um 13:09 schrieb Dominik Csapak:
> we added a 'padding column' recently, and we forgot to adapt
> the custom childs for that.
>
> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
> ---
> technically not required, but otherwise the radiobuttons
> in pdm ui patch are not properly placed.
>
> src/widget/input_panel.rs | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
>
applied, thanks!
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 11+ messages in thread
* [pdm-devel] applied: [PATCH proxmox-api-types 1/1] add /access/domains GET call
2024-12-19 12:09 ` [pdm-devel] [PATCH proxmox-api-types 1/1] add /access/domains GET call Dominik Csapak
@ 2024-12-19 12:22 ` Thomas Lamprecht
0 siblings, 0 replies; 11+ messages in thread
From: Thomas Lamprecht @ 2024-12-19 12:22 UTC (permalink / raw)
To: Proxmox Datacenter Manager development discussion, Dominik Csapak
Am 19.12.24 um 13:09 schrieb Dominik Csapak:
> so we can query remote realms
>
> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
> ---
> pve-api-types/generate.pl | 7 +++-
> pve-api-types/src/generated/code.rs | 12 ++++++-
> pve-api-types/src/generated/types.rs | 51 ++++++++++++++++++++++++++++
> 3 files changed, 68 insertions(+), 2 deletions(-)
>
>
applied, thanks!
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 11+ messages in thread
* [pdm-devel] applied: [PATCH yew-widget-toolkit/proxmox-api-types/pdm] overhaul remote wizard
2024-12-19 12:09 [pdm-devel] [PATCH yew-widget-toolkit/proxmox-api-types/pdm] overhaul remote wizard Dominik Csapak
` (4 preceding siblings ...)
2024-12-19 12:09 ` [pdm-devel] [PATCH datacenter-manager 3/3] ui: restructure wizard to have a better flow Dominik Csapak
@ 2024-12-19 12:31 ` Thomas Lamprecht
2024-12-19 12:35 ` Dominik Csapak
5 siblings, 1 reply; 11+ messages in thread
From: Thomas Lamprecht @ 2024-12-19 12:31 UTC (permalink / raw)
To: Proxmox Datacenter Manager development discussion, Dominik Csapak
Am 19.12.24 um 13:09 schrieb Dominik Csapak:
> reorganize how the wizard is setup, by
> * first only requiring hostname (+ fingerprint)
> * then require a name + credentials
> * then the endpoint list as before
> * then the summary as before
>
> Not super sure about the name for the 'realms' api endpoint, maybe
> 'scan-realms' or something would be better?
>
> The widget toolkit patch is not strictly required, but the layout with
> the radio buttons is slightly incorrect without it.
>
> promxox-yew-widget-toolkit:
>
> Dominik Csapak (1):
> widget: input panel: use correct column for custom childs
>
> src/widget/input_panel.rs | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> promxox-api-types:
>
> Dominik Csapak (1):
> add /access/domains GET call
>
> pve-api-types/generate.pl | 7 +++-
> pve-api-types/src/generated/code.rs | 12 ++++++-
> pve-api-types/src/generated/types.rs | 51 ++++++++++++++++++++++++++++
> 3 files changed, 68 insertions(+), 2 deletions(-)
>
> proxmox-datacenter-manager:
>
> Dominik Csapak (3):
> server: api: add 'realms' add point for PVE
> pdm-client: expose `ListRealm` type
> ui: restructure wizard to have a better flow
>
> lib/pdm-client/src/lib.rs | 2 +
> server/src/api/pve/mod.rs | 52 +++-
> ui/src/remotes/add_wizard.rs | 37 ++-
> ui/src/remotes/mod.rs | 5 +-
> ui/src/remotes/wizard_page_connect.rs | 115 ++++-----
> ui/src/remotes/wizard_page_info.rs | 336 ++++++++++++++++++++++----
> 6 files changed, 415 insertions(+), 132 deletions(-)
>
applied series, thanks!
we might want to place realm and user closer together, maybe besides each
other, not sure though.
As unlike the login window, which you probably used as template, one always
needs to select the realm here (or we auto-select the first/default one too,
then it might be OK as is)
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [pdm-devel] applied: [PATCH yew-widget-toolkit/proxmox-api-types/pdm] overhaul remote wizard
2024-12-19 12:31 ` [pdm-devel] applied: [PATCH yew-widget-toolkit/proxmox-api-types/pdm] overhaul remote wizard Thomas Lamprecht
@ 2024-12-19 12:35 ` Dominik Csapak
2024-12-19 12:40 ` Thomas Lamprecht
0 siblings, 1 reply; 11+ messages in thread
From: Dominik Csapak @ 2024-12-19 12:35 UTC (permalink / raw)
To: Thomas Lamprecht, Proxmox Datacenter Manager development discussion
On 12/19/24 13:31, Thomas Lamprecht wrote:
> Am 19.12.24 um 13:09 schrieb Dominik Csapak:
>> reorganize how the wizard is setup, by
>> * first only requiring hostname (+ fingerprint)
>> * then require a name + credentials
>> * then the endpoint list as before
>> * then the summary as before
>>
>> Not super sure about the name for the 'realms' api endpoint, maybe
>> 'scan-realms' or something would be better?
>>
>> The widget toolkit patch is not strictly required, but the layout with
>> the radio buttons is slightly incorrect without it.
>>
>> promxox-yew-widget-toolkit:
>>
>> Dominik Csapak (1):
>> widget: input panel: use correct column for custom childs
>>
>> src/widget/input_panel.rs | 4 ++--
>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> promxox-api-types:
>>
>> Dominik Csapak (1):
>> add /access/domains GET call
>>
>> pve-api-types/generate.pl | 7 +++-
>> pve-api-types/src/generated/code.rs | 12 ++++++-
>> pve-api-types/src/generated/types.rs | 51 ++++++++++++++++++++++++++++
>> 3 files changed, 68 insertions(+), 2 deletions(-)
>>
>> proxmox-datacenter-manager:
>>
>> Dominik Csapak (3):
>> server: api: add 'realms' add point for PVE
>> pdm-client: expose `ListRealm` type
>> ui: restructure wizard to have a better flow
>>
>> lib/pdm-client/src/lib.rs | 2 +
>> server/src/api/pve/mod.rs | 52 +++-
>> ui/src/remotes/add_wizard.rs | 37 ++-
>> ui/src/remotes/mod.rs | 5 +-
>> ui/src/remotes/wizard_page_connect.rs | 115 ++++-----
>> ui/src/remotes/wizard_page_info.rs | 336 ++++++++++++++++++++++----
>> 6 files changed, 415 insertions(+), 132 deletions(-)
>>
>
>
> applied series, thanks!
>
> we might want to place realm and user closer together, maybe besides each
> other, not sure though.
>
> As unlike the login window, which you probably used as template, one always
> needs to select the realm here (or we auto-select the first/default one too,
> then it might be OK as is)
yeah this was the fastest i could come up with.
I couldn't reuse the realm selector from the login easily
due to that not being able to 'preload' the realms, and i did
not want to query them twice unnecessarily
I'll extend the realm selector from proxmox-yew-comp
with that ability and reuse that then, not sure how long I need for that though...
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [pdm-devel] applied: [PATCH yew-widget-toolkit/proxmox-api-types/pdm] overhaul remote wizard
2024-12-19 12:35 ` Dominik Csapak
@ 2024-12-19 12:40 ` Thomas Lamprecht
0 siblings, 0 replies; 11+ messages in thread
From: Thomas Lamprecht @ 2024-12-19 12:40 UTC (permalink / raw)
To: Proxmox Datacenter Manager development discussion, Dominik Csapak
Am 19.12.24 um 13:35 schrieb Dominik Csapak:
> On 12/19/24 13:31, Thomas Lamprecht wrote:
>> we might want to place realm and user closer together, maybe besides each
>> other, not sure though.
>>
>> As unlike the login window, which you probably used as template, one always
>> needs to select the realm here (or we auto-select the first/default one too,
>> then it might be OK as is)
>
> yeah this was the fastest i could come up with.
> I couldn't reuse the realm selector from the login easily
> due to that not being able to 'preload' the realms, and i did
> not want to query them twice unnecessarily
>
> I'll extend the realm selector from proxmox-yew-comp
> with that ability and reuse that then, not sure how long I need for that though...
>
fyi: no pressure from my side for that for today anymore, can be improved
over the next weeks.
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2024-12-19 12:41 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-12-19 12:09 [pdm-devel] [PATCH yew-widget-toolkit/proxmox-api-types/pdm] overhaul remote wizard Dominik Csapak
2024-12-19 12:09 ` [pdm-devel] [PATCH yew-widget-toolkit 1/1] widget: input panel: use correct column for custom childs Dominik Csapak
2024-12-19 12:22 ` [pdm-devel] applied: " Thomas Lamprecht
2024-12-19 12:09 ` [pdm-devel] [PATCH proxmox-api-types 1/1] add /access/domains GET call Dominik Csapak
2024-12-19 12:22 ` [pdm-devel] applied: " Thomas Lamprecht
2024-12-19 12:09 ` [pdm-devel] [PATCH datacenter-manager 1/3] server: api: add 'realms' add point for PVE Dominik Csapak
2024-12-19 12:09 ` [pdm-devel] [PATCH datacenter-manager 2/3] pdm-client: expose `ListRealm` type Dominik Csapak
2024-12-19 12:09 ` [pdm-devel] [PATCH datacenter-manager 3/3] ui: restructure wizard to have a better flow Dominik Csapak
2024-12-19 12:31 ` [pdm-devel] applied: [PATCH yew-widget-toolkit/proxmox-api-types/pdm] overhaul remote wizard Thomas Lamprecht
2024-12-19 12:35 ` Dominik Csapak
2024-12-19 12:40 ` Thomas Lamprecht
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox