diff --git a/remote_backend/src/controllers/mod.rs b/remote_backend/src/controllers/mod.rs
index 1bf9cbd..c0d541f 100644
--- a/remote_backend/src/controllers/mod.rs
+++ b/remote_backend/src/controllers/mod.rs
@@ -7,9 +7,9 @@ use std::io::ErrorKind;
pub mod auth_controller;
pub mod server_controller;
+pub mod static_controller;
pub mod sys_info_controller;
pub mod vm_controller;
-pub mod static_controller;
/// Custom error to ease controller writing
#[derive(Debug)]
diff --git a/remote_backend/src/main.rs b/remote_backend/src/main.rs
index 3e3e84e..f6fc36e 100644
--- a/remote_backend/src/main.rs
+++ b/remote_backend/src/main.rs
@@ -11,7 +11,9 @@ use actix_web::{web, App, HttpServer};
use light_openid::basic_state_manager::BasicStateManager;
use remote_backend::app_config::AppConfig;
use remote_backend::constants;
-use remote_backend::controllers::{auth_controller, server_controller, static_controller, sys_info_controller, vm_controller};
+use remote_backend::controllers::{
+ auth_controller, server_controller, static_controller, sys_info_controller, vm_controller,
+};
use remote_backend::middlewares::auth_middleware::AuthChecker;
use std::time::Duration;
@@ -108,7 +110,7 @@ async fn main() -> std::io::Result<()> {
"/api/sysinfo/status",
web::get().to(sys_info_controller::status),
)
- // Static assets
+ // Static assets
.route("/", web::get().to(static_controller::root_index))
.route(
"/{tail:.*}",
diff --git a/remote_frontend/src/widgets/VirtualMachinesWidget.tsx b/remote_frontend/src/widgets/VirtualMachinesWidget.tsx
index 6f01f6c..982d1f9 100644
--- a/remote_frontend/src/widgets/VirtualMachinesWidget.tsx
+++ b/remote_frontend/src/widgets/VirtualMachinesWidget.tsx
@@ -25,6 +25,7 @@ import { useToast } from "../hooks/providers/ToastProvider";
import { AsyncWidget } from "./AsyncWidget";
import { SectionContainer } from "./SectionContainer";
import { VMLiveScreenshot } from "./VMLiveScreenshot";
+import { useConfirm } from "../hooks/providers/ConfirmDialogProvider";
const useStyles = makeStyles({
body1Stronger: typographyStyles.body1Stronger,
@@ -151,6 +152,7 @@ function VMWidget(p: { vm: VMInfo }): React.ReactElement {
onClick={VMApi.SuspendVM}
/>
}
@@ -160,6 +162,7 @@ function VMWidget(p: { vm: VMInfo }): React.ReactElement {
onClick={VMApi.ShutdownVM}
/>
}
@@ -174,6 +177,7 @@ function VMWidget(p: { vm: VMInfo }): React.ReactElement {
onClick={VMApi.KillVM}
/>
}
@@ -213,6 +217,7 @@ function VMPreview(p: { vm: VMInfo; state?: VMState }): React.ReactElement {
}
function VMAction(p: {
+ confirmAction?: boolean;
vm: VMInfo;
label: string;
primary?: boolean;
@@ -223,11 +228,20 @@ function VMAction(p: {
onClick: (vm: VMInfo) => Promise;
}): React.ReactElement {
const toast = useToast();
+ const confirm = useConfirm();
const [loading, setLoading] = React.useState(false);
const onClick = async () => {
try {
+ if (
+ p.confirmAction &&
+ !(await confirm(
+ `Do you really want to ${p.label} the VM '${p.vm.name}'?`
+ ))
+ )
+ return;
+
setLoading(true);
await p.onClick(p.vm);