82 lines
3.7 KiB
Rust
82 lines
3.7 KiB
Rust
use gloo::net::http::Request;
|
|
use wasm_bindgen_futures::spawn_local;
|
|
use yew::prelude::*;
|
|
|
|
use crate::{api::APIEndpoints, components::refresh_button::RefreshButton};
|
|
|
|
use base64::{Engine as _, engine::general_purpose};
|
|
|
|
fn string_to_base64_data_url(data: &str, content_type: &str) -> String {
|
|
let mut buf = String::new();
|
|
general_purpose::STANDARD.encode_string(data, &mut buf);
|
|
format!("data:{};base64,{}", content_type, buf)
|
|
}
|
|
|
|
#[derive(Properties, PartialEq)]
|
|
pub struct ConfigProps {
|
|
pub dir: AttrValue,
|
|
pub file_name: AttrValue,
|
|
#[prop_or("".into())]
|
|
pub contents: AttrValue,
|
|
}
|
|
|
|
#[function_component(Config)]
|
|
pub fn config(props: &ConfigProps) -> Html {
|
|
let dir_name = props.dir.clone();
|
|
let file_name = props.file_name.clone();
|
|
let contents = use_state(|| props.contents.to_string());
|
|
|
|
let get_contents = {
|
|
let contents = contents.clone();
|
|
Callback::from(move |_| {
|
|
let url =
|
|
APIEndpoints::get_contents(dir_name.clone().as_str(), file_name.clone().as_str());
|
|
let contents = contents.clone();
|
|
spawn_local(async move {
|
|
match Request::get(&url).send().await {
|
|
Ok(response) if response.ok() => {
|
|
if let Ok(text) = response.text().await {
|
|
contents.set(text);
|
|
}
|
|
}
|
|
_ => contents.set("...Ошибка загрузки содержимого...".into()),
|
|
}
|
|
})
|
|
})
|
|
};
|
|
|
|
{
|
|
let get_contents_clone = get_contents.clone();
|
|
let is_contents_empty = props.contents.is_empty();
|
|
use_effect_with((), move |_| {
|
|
if is_contents_empty {
|
|
get_contents_clone.emit(());
|
|
}
|
|
});
|
|
}
|
|
|
|
html! {
|
|
<div class="w-full">
|
|
<RefreshButton onclick={get_contents.reform(|_| ())} />
|
|
<div class="mb-2 flex justify-between items-center">
|
|
<p class="text-sm font-medium text-gray-900">{"Конфигурация "}<b>{&props.file_name}</b>{" для "}<b>{&props.dir}</b>{":"}</p>
|
|
</div>
|
|
<div class="relative bg-gray-50 rounded-lg dark:bg-gray-700 p-4">
|
|
<div class="overflow-scroll max-h-full">
|
|
<pre><code id="code-block" class="text-sm text-gray-500 dark:text-gray-400 whitespace-pre">{&*contents}</code></pre>
|
|
</div>
|
|
<div class="absolute top-2 end-2 bg-gray-50 dark:bg-gray-700">
|
|
<a href={string_to_base64_data_url(&contents, "application/octet-stream")} download={&props.file_name}>
|
|
<button type="button" class="text-white bg-gradient-to-br from-purple-600 to-blue-500 hover:bg-gradient-to-bl focus:ring-4 focus:outline-none focus:ring-blue-300 dark:focus:ring-blue-800 font-medium rounded-lg text-sm px-5 py-2.5 text-center me-2 mb-2">
|
|
<svg class="w-6 h-6 text-gray-800 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 24 24">
|
|
<path fill-rule="evenodd" d="M13 11.15V4a1 1 0 1 0-2 0v7.15L8.78 8.374a1 1 0 1 0-1.56 1.25l4 5a1 1 0 0 0 1.56 0l4-5a1 1 0 1 0-1.56-1.25L13 11.15Z" clip-rule="evenodd"/>
|
|
<path fill-rule="evenodd" d="M9.657 15.874 7.358 13H5a2 2 0 0 0-2 2v4a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-4a2 2 0 0 0-2-2h-2.358l-2.3 2.874a3 3 0 0 1-4.685 0ZM17 16a1 1 0 1 0 0 2h.01a1 1 0 1 0 0-2H17Z" clip-rule="evenodd"/>
|
|
</svg>{"Скачать"}
|
|
</button>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
}
|