Allow for deleting scripts from the editor.
This commit is contained in:
parent
c5115993cb
commit
17547c7434
@ -1,4 +1,4 @@
|
|||||||
use std::{ops::Deref, rc::Rc};
|
use std::{ops::Deref, rc::Rc, str::FromStr};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
command_handler::execute_queue, FrameId, GlobalLayoutState, GlobalMemoCell, PanelDirection,
|
command_handler::execute_queue, FrameId, GlobalLayoutState, GlobalMemoCell, PanelDirection,
|
||||||
@ -6,10 +6,12 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
use create_script_dialog::CreateScriptDialog;
|
use create_script_dialog::CreateScriptDialog;
|
||||||
|
use delete_script_dialog::DeleteScriptDialog;
|
||||||
use editor_area::EditorArea;
|
use editor_area::EditorArea;
|
||||||
use editor_nav::EditorNav;
|
use editor_nav::EditorNav;
|
||||||
use storage::fetch_initial_editor_state;
|
use storage::fetch_initial_editor_state;
|
||||||
use web_sys::KeyboardEvent;
|
use wasm_bindgen_futures::js_sys::JsString;
|
||||||
|
use web_sys::{console, KeyboardEvent};
|
||||||
use yew::{
|
use yew::{
|
||||||
function_component, html, use_node_ref, use_state_eq, AttrValue, Callback, Html, Properties,
|
function_component, html, use_node_ref, use_state_eq, AttrValue, Callback, Html, Properties,
|
||||||
UseStateHandle,
|
UseStateHandle,
|
||||||
@ -19,6 +21,7 @@ pub use self::storage::load_extant_file_contents;
|
|||||||
use self::storage::load_file_contents;
|
use self::storage::load_file_contents;
|
||||||
|
|
||||||
mod create_script_dialog;
|
mod create_script_dialog;
|
||||||
|
mod delete_script_dialog;
|
||||||
mod editor_area;
|
mod editor_area;
|
||||||
mod editor_nav;
|
mod editor_nav;
|
||||||
mod storage;
|
mod storage;
|
||||||
@ -44,13 +47,13 @@ fn close_editor(frame: &FrameId, global_layout: &UseStateHandle<Rc<GlobalLayoutS
|
|||||||
global_layout.set(gl_new.into());
|
global_layout.set(gl_new.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
pub struct EditorViewState {
|
pub struct EditorViewState {
|
||||||
error_msg: Option<AttrValue>,
|
error_msg: Option<AttrValue>,
|
||||||
available_files: Vec<AttrValue>,
|
available_files: Vec<AttrValue>,
|
||||||
open_file: AttrValue,
|
open_file: AttrValue,
|
||||||
show_create_dialog: bool,
|
show_create_dialog: bool,
|
||||||
show_delete_dialog: Option<String>,
|
show_delete_dialog: Option<AttrValue>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_run_script(script: &str, global_memo: &GlobalMemoCell) -> anyhow::Result<()> {
|
pub fn try_run_script(script: &str, global_memo: &GlobalMemoCell) -> anyhow::Result<()> {
|
||||||
@ -160,10 +163,14 @@ pub fn editor_view(props: &EditorViewProps) -> Html {
|
|||||||
let global_memo = props.global_memo.clone();
|
let global_memo = props.global_memo.clone();
|
||||||
let kb_editor_state = editor_state.clone();
|
let kb_editor_state = editor_state.clone();
|
||||||
|
|
||||||
|
console::log_1(&JsString::from_str(&format!("{:?}", editor_state.as_ref())).unwrap());
|
||||||
html! {
|
html! {
|
||||||
<div class="w-100 h-100" onkeydown={keyboard_handler(kb_editor_state, global_memo, global_layout, set_err, frame)} ref={editor_ref.clone()}>
|
<div class="w-100 h-100" onkeydown={keyboard_handler(kb_editor_state, global_memo, global_layout, set_err, frame)} ref={editor_ref.clone()}>
|
||||||
{if editor_state.show_create_dialog {
|
{if editor_state.show_create_dialog {
|
||||||
html! { <CreateScriptDialog ..detail_props.clone() /> }
|
html! { <CreateScriptDialog ..detail_props.clone() /> }
|
||||||
|
} else if let Some(ref delete_file) = editor_state.show_delete_dialog {
|
||||||
|
html! { <DeleteScriptDialog editor_state={editor_state.clone()}
|
||||||
|
filename={delete_file.clone()}/> }
|
||||||
} else {
|
} else {
|
||||||
html! { <></> }
|
html! { <></> }
|
||||||
}}
|
}}
|
||||||
|
58
src/editor_view/delete_script_dialog.rs
Normal file
58
src/editor_view/delete_script_dialog.rs
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
use itertools::Itertools;
|
||||||
|
use std::{ops::Deref, rc::Rc};
|
||||||
|
use yew::{function_component, html, AttrValue, Html, Properties, UseStateHandle};
|
||||||
|
|
||||||
|
use super::{close_modals, EditorViewState};
|
||||||
|
|
||||||
|
#[derive(Properties, PartialEq, Clone)]
|
||||||
|
pub(super) struct DeleteScriptProps {
|
||||||
|
pub filename: AttrValue,
|
||||||
|
pub editor_state: UseStateHandle<Rc<EditorViewState>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn delete_script(filename: &AttrValue, state: &UseStateHandle<Rc<EditorViewState>>) {
|
||||||
|
let mut new_state = (*state.deref().deref()).clone();
|
||||||
|
|
||||||
|
if let Some((pos, _)) = new_state
|
||||||
|
.available_files
|
||||||
|
.iter()
|
||||||
|
.find_position(|v| *v == filename)
|
||||||
|
{
|
||||||
|
new_state.available_files.remove(pos);
|
||||||
|
if &new_state.open_file == filename {
|
||||||
|
new_state.open_file = "init.lua".into();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new_state.show_delete_dialog = None;
|
||||||
|
state.set(new_state.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[function_component(DeleteScriptDialog)]
|
||||||
|
pub(super) fn delete_script_dialog(props: &DeleteScriptProps) -> Html {
|
||||||
|
let state_modalclose1 = props.editor_state.clone();
|
||||||
|
let state_modalclose2 = props.editor_state.clone();
|
||||||
|
let state_deletescript = props.editor_state.clone();
|
||||||
|
let filename_deletescript = props.filename.clone();
|
||||||
|
html! { <>
|
||||||
|
<div class="modal-backdrop fade show"/>
|
||||||
|
<div class="modal" tabindex="-1" aria-modal="true" role="dialog" style="display: block">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">{"Delete script"}</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"
|
||||||
|
onclick={move |_ev| close_modals(&state_modalclose1) }></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<p>{format!("Are you sure you wish to permanently delete {}?", props.filename)}</p>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"
|
||||||
|
onclick={move |_ev| close_modals(&state_modalclose2) }>{"Close"}</button>
|
||||||
|
<button type="button" class="btn btn-primary" onclick={move |_ev| delete_script(&filename_deletescript, &state_deletescript) }>{"Delete"}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
use std::{ops::Deref, rc::Rc};
|
use std::{ops::Deref, rc::Rc};
|
||||||
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use web_sys::KeyboardEvent;
|
use web_sys::{KeyboardEvent, MouseEvent};
|
||||||
use yew::{function_component, html, AttrValue, Html, UseStateHandle};
|
use yew::{function_component, html, AttrValue, Html, UseStateHandle};
|
||||||
|
|
||||||
use super::{close_editor, run_script, select_file, EditorViewDetailProps, EditorViewState};
|
use super::{close_editor, run_script, select_file, EditorViewDetailProps, EditorViewState};
|
||||||
@ -49,6 +49,12 @@ fn item_keyboard_handler(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn show_delete_dialog(state: &UseStateHandle<Rc<EditorViewState>>, script: &AttrValue) {
|
||||||
|
let mut new_state = (*state.as_ref()).clone();
|
||||||
|
new_state.show_delete_dialog = Some(script.clone());
|
||||||
|
state.set(new_state.into());
|
||||||
|
}
|
||||||
|
|
||||||
#[function_component(EditorNav)]
|
#[function_component(EditorNav)]
|
||||||
pub(super) fn editor_nav(props: &EditorViewDetailProps) -> Html {
|
pub(super) fn editor_nav(props: &EditorViewDetailProps) -> Html {
|
||||||
let global_memo = props.global_memo.clone();
|
let global_memo = props.global_memo.clone();
|
||||||
@ -82,7 +88,7 @@ pub(super) fn editor_nav(props: &EditorViewDetailProps) -> Html {
|
|||||||
.available_files
|
.available_files
|
||||||
.iter()
|
.iter()
|
||||||
.map(|f| {
|
.map(|f| {
|
||||||
let mut classes = vec!["list-group-item", "pe-auto"];
|
let mut classes = vec!["list-group-item", "d-flex"];
|
||||||
let mut aria_current = None;
|
let mut aria_current = None;
|
||||||
if *f == props.editor_state.open_file {
|
if *f == props.editor_state.open_file {
|
||||||
aria_current = Some("true");
|
aria_current = Some("true");
|
||||||
@ -92,12 +98,24 @@ pub(super) fn editor_nav(props: &EditorViewDetailProps) -> Html {
|
|||||||
let state_for_click = props.editor_state.clone();
|
let state_for_click = props.editor_state.clone();
|
||||||
let filename_for_kb: AttrValue = f.clone();
|
let filename_for_kb: AttrValue = f.clone();
|
||||||
let state_for_kb = props.editor_state.clone();
|
let state_for_kb = props.editor_state.clone();
|
||||||
html! { <li aria-current={aria_current} tabindex={0}
|
let state_for_delscript = state_for_kb.clone();
|
||||||
|
let filename_for_delscript: AttrValue = f.clone();
|
||||||
|
html! { <li aria-current={aria_current}
|
||||||
class={classes.iter().join(" ")}
|
class={classes.iter().join(" ")}
|
||||||
onclick={move |_ev| select_file(&filename_for_click, &state_for_click)}
|
>
|
||||||
onkeydown={item_keyboard_handler(filename_for_kb, state_for_kb)}
|
<div tabindex={0}
|
||||||
style="cursor: pointer"
|
class="pe-auto"
|
||||||
>{f}</li>}
|
onkeydown={item_keyboard_handler(filename_for_kb, state_for_kb)}
|
||||||
|
style="cursor: pointer"
|
||||||
|
onclick={move |_ev| select_file(&filename_for_click, &state_for_click)}>{f}</div>
|
||||||
|
<div class="flex-fill"/>
|
||||||
|
{if f != "init.lua" {
|
||||||
|
html! { <button class="btn" onclick={move |ev: MouseEvent| {
|
||||||
|
show_delete_dialog(&state_for_delscript, &filename_for_delscript);
|
||||||
|
ev.prevent_default();
|
||||||
|
}} aria-label="Delete" title="Delete"><i class="bi bi-trash"></i></button> }
|
||||||
|
} else { html!{<></>} } }
|
||||||
|
</li>}
|
||||||
})
|
})
|
||||||
.collect::<Vec<Html>>()
|
.collect::<Vec<Html>>()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user