mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-28 16:07:05 +00:00
Add new setting view, component, and router to rustfs-gui (#223)
- Create `SettingViews` component in `views/setting.rs`. - Update `views/mod.rs` to include the new `SettingViews` component. - Update routing in `main.rs` to include the new route for `SettingViews`.
This commit is contained in:
@@ -556,4 +556,401 @@ video {
|
|||||||
|
|
||||||
.static {
|
.static {
|
||||||
position: static;
|
position: static;
|
||||||
|
}
|
||||||
|
|
||||||
|
.absolute {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.relative {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-2 {
|
||||||
|
right: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-6 {
|
||||||
|
right: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-1\/2 {
|
||||||
|
top: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-4 {
|
||||||
|
top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.z-10 {
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb-2 {
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb-4 {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb-6 {
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb-8 {
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ml-2 {
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-16 {
|
||||||
|
height: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-24 {
|
||||||
|
height: 6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-4 {
|
||||||
|
height: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-5 {
|
||||||
|
height: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-6 {
|
||||||
|
height: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.min-h-screen {
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-16 {
|
||||||
|
width: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-20 {
|
||||||
|
width: 5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-24 {
|
||||||
|
width: 6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-4 {
|
||||||
|
width: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-48 {
|
||||||
|
width: 12rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-5 {
|
||||||
|
width: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-6 {
|
||||||
|
width: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-full {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-1 {
|
||||||
|
flex: 1 1 0%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.-translate-y-1\/2 {
|
||||||
|
--tw-translate-y: -50%;
|
||||||
|
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
||||||
|
}
|
||||||
|
|
||||||
|
.transform {
|
||||||
|
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
to {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-spin {
|
||||||
|
animation: spin 1s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-col {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.items-center {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.justify-center {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.space-x-2 > :not([hidden]) ~ :not([hidden]) {
|
||||||
|
--tw-space-x-reverse: 0;
|
||||||
|
margin-right: calc(0.5rem * var(--tw-space-x-reverse));
|
||||||
|
margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
|
||||||
|
}
|
||||||
|
|
||||||
|
.space-x-4 > :not([hidden]) ~ :not([hidden]) {
|
||||||
|
--tw-space-x-reverse: 0;
|
||||||
|
margin-right: calc(1rem * var(--tw-space-x-reverse));
|
||||||
|
margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse)));
|
||||||
|
}
|
||||||
|
|
||||||
|
.space-x-8 > :not([hidden]) ~ :not([hidden]) {
|
||||||
|
--tw-space-x-reverse: 0;
|
||||||
|
margin-right: calc(2rem * var(--tw-space-x-reverse));
|
||||||
|
margin-left: calc(2rem * calc(1 - var(--tw-space-x-reverse)));
|
||||||
|
}
|
||||||
|
|
||||||
|
.space-y-4 > :not([hidden]) ~ :not([hidden]) {
|
||||||
|
--tw-space-y-reverse: 0;
|
||||||
|
margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));
|
||||||
|
margin-bottom: calc(1rem * var(--tw-space-y-reverse));
|
||||||
|
}
|
||||||
|
|
||||||
|
.space-y-6 > :not([hidden]) ~ :not([hidden]) {
|
||||||
|
--tw-space-y-reverse: 0;
|
||||||
|
margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));
|
||||||
|
margin-bottom: calc(1.5rem * var(--tw-space-y-reverse));
|
||||||
|
}
|
||||||
|
|
||||||
|
.rounded {
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rounded-full {
|
||||||
|
border-radius: 9999px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rounded-lg {
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rounded-md {
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border {
|
||||||
|
border-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-b {
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-b-2 {
|
||||||
|
border-bottom-width: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-black {
|
||||||
|
--tw-border-opacity: 1;
|
||||||
|
border-color: rgb(0 0 0 / var(--tw-border-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-gray-200 {
|
||||||
|
--tw-border-opacity: 1;
|
||||||
|
border-color: rgb(229 231 235 / var(--tw-border-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-\[\#111827\] {
|
||||||
|
--tw-bg-opacity: 1;
|
||||||
|
background-color: rgb(17 24 39 / var(--tw-bg-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-gray-100 {
|
||||||
|
--tw-bg-opacity: 1;
|
||||||
|
background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-gray-900 {
|
||||||
|
--tw-bg-opacity: 1;
|
||||||
|
background-color: rgb(17 24 39 / var(--tw-bg-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-red-500 {
|
||||||
|
--tw-bg-opacity: 1;
|
||||||
|
background-color: rgb(239 68 68 / var(--tw-bg-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-white {
|
||||||
|
--tw-bg-opacity: 1;
|
||||||
|
background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-2 {
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-4 {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-8 {
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.px-1 {
|
||||||
|
padding-left: 0.25rem;
|
||||||
|
padding-right: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.px-3 {
|
||||||
|
padding-left: 0.75rem;
|
||||||
|
padding-right: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.px-4 {
|
||||||
|
padding-left: 1rem;
|
||||||
|
padding-right: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.py-0\.5 {
|
||||||
|
padding-top: 0.125rem;
|
||||||
|
padding-bottom: 0.125rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.py-2 {
|
||||||
|
padding-top: 0.5rem;
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.py-4 {
|
||||||
|
padding-top: 1rem;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.py-6 {
|
||||||
|
padding-top: 1.5rem;
|
||||||
|
padding-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pr-10 {
|
||||||
|
padding-right: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-2xl {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
line-height: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-base {
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-sm {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
line-height: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.font-medium {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.font-semibold {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-blue-500 {
|
||||||
|
--tw-text-opacity: 1;
|
||||||
|
color: rgb(59 130 246 / var(--tw-text-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-blue-600 {
|
||||||
|
--tw-text-opacity: 1;
|
||||||
|
color: rgb(37 99 235 / var(--tw-text-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-gray-400 {
|
||||||
|
--tw-text-opacity: 1;
|
||||||
|
color: rgb(156 163 175 / var(--tw-text-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-gray-500 {
|
||||||
|
--tw-text-opacity: 1;
|
||||||
|
color: rgb(107 114 128 / var(--tw-text-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-gray-600 {
|
||||||
|
--tw-text-opacity: 1;
|
||||||
|
color: rgb(75 85 99 / var(--tw-text-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-white {
|
||||||
|
--tw-text-opacity: 1;
|
||||||
|
color: rgb(255 255 255 / var(--tw-text-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.opacity-25 {
|
||||||
|
opacity: 0.25;
|
||||||
|
}
|
||||||
|
|
||||||
|
.opacity-75 {
|
||||||
|
opacity: 0.75;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter {
|
||||||
|
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover\:bg-\[\#1f2937\]:hover {
|
||||||
|
--tw-bg-opacity: 1;
|
||||||
|
background-color: rgb(31 41 55 / var(--tw-bg-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover\:bg-gray-100:hover {
|
||||||
|
--tw-bg-opacity: 1;
|
||||||
|
background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover\:bg-red-600:hover {
|
||||||
|
--tw-bg-opacity: 1;
|
||||||
|
background-color: rgb(220 38 38 / var(--tw-bg-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover\:text-gray-700:hover {
|
||||||
|
--tw-text-opacity: 1;
|
||||||
|
color: rgb(55 65 81 / var(--tw-text-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover\:text-gray-900:hover {
|
||||||
|
--tw-text-opacity: 1;
|
||||||
|
color: rgb(17 24 39 / var(--tw-text-opacity, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.focus\:outline-none:focus {
|
||||||
|
outline: 2px solid transparent;
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.focus\:ring-2:focus {
|
||||||
|
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
||||||
|
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
||||||
|
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
||||||
|
}
|
||||||
|
|
||||||
|
.focus\:ring-blue-500:focus {
|
||||||
|
--tw-ring-opacity: 1;
|
||||||
|
--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity, 1));
|
||||||
}
|
}
|
||||||
@@ -152,7 +152,7 @@ pub fn Home() -> Element {
|
|||||||
// setting button
|
// setting button
|
||||||
Link {
|
Link {
|
||||||
class: "p-2 hover:bg-gray-100 rounded-lg",
|
class: "p-2 hover:bg-gray-100 rounded-lg",
|
||||||
to: Route::HomeViews {},
|
to: Route::SettingViews {},
|
||||||
SettingButton {}
|
SettingButton {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,3 +2,5 @@ mod home;
|
|||||||
pub use home::Home;
|
pub use home::Home;
|
||||||
mod navbar;
|
mod navbar;
|
||||||
pub use navbar::Navbar;
|
pub use navbar::Navbar;
|
||||||
|
mod setting;
|
||||||
|
pub use setting::Setting;
|
||||||
|
|||||||
@@ -0,0 +1,202 @@
|
|||||||
|
use crate::components::navbar::LoadingSpinner;
|
||||||
|
use dioxus::logger::tracing::{debug, error};
|
||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
const SETTINGS_JS: Asset = asset!("/assets/js/sts.js");
|
||||||
|
const TAILWIND_CSS: Asset = asset!("/assets/tailwind.css");
|
||||||
|
#[component]
|
||||||
|
pub fn Setting() -> Element {
|
||||||
|
use crate::utils::{RustFSConfig, ServiceManager};
|
||||||
|
use document::{Meta, Script, Stylesheet, Title};
|
||||||
|
|
||||||
|
#[allow(clippy::redundant_closure)]
|
||||||
|
let service = use_signal(|| ServiceManager::new());
|
||||||
|
let conf = RustFSConfig::load().unwrap_or_else(|e| {
|
||||||
|
error!("load config error: {}", e);
|
||||||
|
RustFSConfig::default_config()
|
||||||
|
});
|
||||||
|
debug!("conf address: {:?}", conf.clone().address);
|
||||||
|
|
||||||
|
let config = use_signal(|| conf.clone());
|
||||||
|
let address_state = use_signal(|| conf.address.to_string());
|
||||||
|
let mut host_state = use_signal(|| conf.host.to_string());
|
||||||
|
let mut port_state = use_signal(|| conf.port.to_string());
|
||||||
|
let mut access_key_state = use_signal(|| conf.access_key.to_string());
|
||||||
|
let mut secret_key_state = use_signal(|| conf.secret_key.to_string());
|
||||||
|
let mut volume_name_state = use_signal(|| conf.volume_name.to_string());
|
||||||
|
let loading = use_signal(|| false);
|
||||||
|
|
||||||
|
let save_and_restart = {
|
||||||
|
let host_state = host_state;
|
||||||
|
let port_state = port_state;
|
||||||
|
let access_key_state = access_key_state;
|
||||||
|
let secret_key_state = secret_key_state;
|
||||||
|
let volume_name_state = volume_name_state;
|
||||||
|
let mut loading = loading;
|
||||||
|
debug!("save_and_restart access_key:{}", access_key_state.read());
|
||||||
|
move |_| {
|
||||||
|
// set the loading status
|
||||||
|
loading.set(true);
|
||||||
|
let mut config = config;
|
||||||
|
config.write().address = format!("{}:{}", host_state.read(), port_state.read());
|
||||||
|
config.write().host = host_state.read().to_string();
|
||||||
|
config.write().port = port_state.read().to_string();
|
||||||
|
config.write().access_key = access_key_state.read().to_string();
|
||||||
|
config.write().secret_key = secret_key_state.read().to_string();
|
||||||
|
config.write().volume_name = volume_name_state.read().to_string();
|
||||||
|
// restart service
|
||||||
|
let service = service;
|
||||||
|
let config = config.read().clone();
|
||||||
|
spawn(async move {
|
||||||
|
if let Err(e) = service.read().restart(config).await {
|
||||||
|
ServiceManager::show_error(&format!("发送重启命令失败:{}", e));
|
||||||
|
}
|
||||||
|
// reset the status when you're done
|
||||||
|
loading.set(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
rsx! {
|
||||||
|
Title { "Settings - RustFS App" }
|
||||||
|
Meta { name: "description", content: "Settings - RustFS App." }
|
||||||
|
// The Stylesheet component inserts a style link into the head of the document
|
||||||
|
Stylesheet { href: TAILWIND_CSS }
|
||||||
|
Script { src: SETTINGS_JS }
|
||||||
|
div { class: "bg-white p-8",
|
||||||
|
h1 { class: "text-2xl font-semibold mb-6", "Settings" }
|
||||||
|
div { class: "border-b border-gray-200 mb-6",
|
||||||
|
nav { class: "flex space-x-8",
|
||||||
|
button {
|
||||||
|
class: "tab-btn px-1 py-4 text-sm font-medium border-b-2 border-black",
|
||||||
|
"data-tab": "service",
|
||||||
|
"onclick": "switchTab('service')",
|
||||||
|
"Service "
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
class: "tab-btn px-1 py-4 text-sm font-medium text-gray-500 hover:text-gray-700",
|
||||||
|
"data-tab": "user",
|
||||||
|
"onclick": "switchTab('user')",
|
||||||
|
"User "
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
class: "tab-btn px-1 py-4 text-sm font-medium text-gray-500 hover:text-gray-700 hidden",
|
||||||
|
"data-tab": "logs",
|
||||||
|
"onclick": "switchTab('logs')",
|
||||||
|
"Logs "
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div { id: "tabContent",
|
||||||
|
div { class: "tab-content", id: "service",
|
||||||
|
div { class: "mb-8",
|
||||||
|
h2 { class: "text-base font-medium mb-2", "Service address" }
|
||||||
|
p { class: "text-gray-600 mb-4",
|
||||||
|
" The service address is the IP address and port number of the service. the default address is "
|
||||||
|
code { class: "bg-gray-100 px-1 py-0.5 rounded", {address_state} }
|
||||||
|
". "
|
||||||
|
}
|
||||||
|
div { class: "flex space-x-2",
|
||||||
|
input {
|
||||||
|
class: "border rounded px-3 py-2 w-48 focus:outline-none focus:ring-2 focus:ring-blue-500",
|
||||||
|
r#type: "text",
|
||||||
|
value: host_state,
|
||||||
|
oninput: move |evt| host_state.set(evt.value().clone()),
|
||||||
|
}
|
||||||
|
span { class: "flex items-center", ":" }
|
||||||
|
input {
|
||||||
|
class: "border rounded px-3 py-2 w-20 focus:outline-none focus:ring-2 focus:ring-blue-500",
|
||||||
|
r#type: "text",
|
||||||
|
value: port_state,
|
||||||
|
oninput: move |evt| port_state.set(evt.value().clone()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div { class: "mb-8",
|
||||||
|
h2 { class: "text-base font-medium mb-2", "Storage path" }
|
||||||
|
p { class: "text-gray-600 mb-4",
|
||||||
|
"Update the storage path of the service. the default path is {volume_name_state}."
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
class: "border rounded px-3 py-2 w-full focus:outline-none focus:ring-2 focus:ring-blue-500",
|
||||||
|
r#type: "text",
|
||||||
|
value: volume_name_state,
|
||||||
|
oninput: move |evt| volume_name_state.set(evt.value().clone()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div { class: "tab-content hidden", id: "user",
|
||||||
|
div { class: "mb-8",
|
||||||
|
h2 { class: "text-base font-medium mb-2", "User" }
|
||||||
|
p { class: "text-gray-600 mb-4",
|
||||||
|
"The user is the owner of the service. the default user is "
|
||||||
|
code { class: "bg-gray-100 px-1 py-0.5 rounded", {access_key_state} }
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
class: "border rounded px-3 py-2 w-full focus:outline-none focus:ring-2 focus:ring-blue-500",
|
||||||
|
r#type: "text",
|
||||||
|
value: access_key_state,
|
||||||
|
oninput: move |evt| access_key_state.set(evt.value().clone()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div { class: "mb-8",
|
||||||
|
h2 { class: "text-base font-medium mb-2", "Password" }
|
||||||
|
p { class: "text-gray-600 mb-4",
|
||||||
|
"The password is the password of the user. the default password is "
|
||||||
|
code { class: "bg-gray-100 px-1 py-0.5 rounded", {secret_key_state} }
|
||||||
|
}
|
||||||
|
div { class: "relative",
|
||||||
|
input {
|
||||||
|
class: "border rounded px-3 py-2 w-full pr-10 focus:outline-none focus:ring-2 focus:ring-blue-500",
|
||||||
|
r#type: "password",
|
||||||
|
value: secret_key_state,
|
||||||
|
oninput: move |evt| secret_key_state.set(evt.value().clone()),
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
class: "absolute right-2 top-1/2 transform -translate-y-1/2 text-gray-500 hover:text-gray-700",
|
||||||
|
"onclick": "togglePassword(this)",
|
||||||
|
svg {
|
||||||
|
class: "h-5 w-5",
|
||||||
|
fill: "currentColor",
|
||||||
|
view_box: "0 0 20 20",
|
||||||
|
xmlns: "http://www.w3.org/2000/svg",
|
||||||
|
path { d: "M10 12a2 2 0 100-4 2 2 0 000 4z" }
|
||||||
|
path {
|
||||||
|
clip_rule: "evenodd",
|
||||||
|
d: "M.458 10C1.732 5.943 5.522 3 10 3s8.268 2.943 9.542 7c-1.274 4.057-5.064 7-9.542 7S1.732 14.057.458 10zM14 10a4 4 0 11-8 0 4 4 0 018 0z",
|
||||||
|
fill_rule: "evenodd",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div { class: "tab-content hidden", id: "logs",
|
||||||
|
div { class: "mb-8",
|
||||||
|
h2 { class: "text-base font-medium mb-2", "Logs storage path" }
|
||||||
|
p { class: "text-gray-600 mb-4",
|
||||||
|
"The logs storage path is the path where the logs are stored. the default path is /var/log/rustfs. "
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
class: "border rounded px-3 py-2 w-full focus:outline-none focus:ring-2 focus:ring-blue-500",
|
||||||
|
r#type: "text",
|
||||||
|
value: "/var/logs/rustfs",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div { class: "flex space-x-4",
|
||||||
|
button {
|
||||||
|
class: "bg-[#111827] text-white px-4 py-2 rounded hover:bg-[#1f2937]",
|
||||||
|
onclick: save_and_restart,
|
||||||
|
" Save and restart "
|
||||||
|
}
|
||||||
|
GoBackButton { "Back" }
|
||||||
|
}
|
||||||
|
LoadingSpinner {
|
||||||
|
loading: loading.read().to_owned(),
|
||||||
|
text: "服务处理中...",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@ use dioxus::logger::tracing::debug;
|
|||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use tracing_appender::rolling::{RollingFileAppender, Rotation};
|
use tracing_appender::rolling::{RollingFileAppender, Rotation};
|
||||||
use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt};
|
use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt};
|
||||||
use views::HomeViews;
|
use views::{HomeViews, SettingViews};
|
||||||
|
|
||||||
mod components;
|
mod components;
|
||||||
mod utils;
|
mod utils;
|
||||||
@@ -20,6 +20,8 @@ enum Route {
|
|||||||
#[layout(Navbar)]
|
#[layout(Navbar)]
|
||||||
#[route("/")]
|
#[route("/")]
|
||||||
HomeViews {},
|
HomeViews {},
|
||||||
|
#[route("/settings")]
|
||||||
|
SettingViews {},
|
||||||
}
|
}
|
||||||
|
|
||||||
const FAVICON: Asset = asset!("/assets/favicon.ico");
|
const FAVICON: Asset = asset!("/assets/favicon.ico");
|
||||||
|
|||||||
@@ -1,2 +1,5 @@
|
|||||||
mod home;
|
mod home;
|
||||||
|
mod setting;
|
||||||
|
|
||||||
pub use home::HomeViews;
|
pub use home::HomeViews;
|
||||||
|
pub use setting::SettingViews;
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
use crate::components::Setting;
|
||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn SettingViews() -> Element {
|
||||||
|
rsx! {
|
||||||
|
Setting {}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user