diff options
author | Sébastien Dailly <sebastien@chimrod.com> | 2021-06-01 13:11:58 +0200 |
---|---|---|
committer | Sébastien Dailly <sebastien@dailly.me> | 2022-02-07 16:43:33 +0100 |
commit | 72e3b16bbd258e63f047392c973ba5e8f0a823c8 (patch) | |
tree | 67f75383a9d20590587c648ecb5e3c78f6bd0044 | |
parent | 54f6e68c051afec0d20c349352feee5356e11b35 (diff) |
Added export button in editor
-rwxr-xr-x | editor/actions/delete_page.ml | 7 | ||||
-rwxr-xr-x | editor/actions/dune | 3 | ||||
-rwxr-xr-x | editor/actions/editor_actions.ml (renamed from editor/actions/actions.ml) | 59 | ||||
-rwxr-xr-x | editor/actions/export.ml | 46 | ||||
-rwxr-xr-x | editor/dune | 6 | ||||
-rwxr-xr-x | editor/editor.ml | 6 | ||||
-rwxr-xr-x | editor/forms/delete_page.ml | 18 | ||||
-rwxr-xr-x | editor/forms/delete_page.mli | 5 | ||||
-rwxr-xr-x | editor/forms/dune | 4 | ||||
-rwxr-xr-x | editor/forms/validation.ml | 13 | ||||
-rwxr-xr-x | editor/forms/validation.mli | 5 | ||||
-rwxr-xr-x | editor/state/storage.ml | 21 | ||||
-rwxr-xr-x | editor/state/storage.mli | 3 |
13 files changed, 136 insertions, 60 deletions
diff --git a/editor/actions/delete_page.ml b/editor/actions/delete_page.ml index 9086fc3..fb600bd 100755 --- a/editor/actions/delete_page.ml +++ b/editor/actions/delete_page.ml @@ -17,10 +17,13 @@ end let create : unit -> State.event Note.event = fun () -> - let title = Jstr.v "Confirmation" in + let title = Jstr.v "Confirmation" + and message = + Jstr.v "La page sera définitivement supprimée" + in let ev = Elements.Popup.create ~title - ~form:(Some (Forms.Delete_page.create () )) + ~form:(Some (Forms.Validation.create message )) in Note.E.map (fun v -> State.E diff --git a/editor/actions/dune b/editor/actions/dune index 5d269c4..4044b52 100755 --- a/editor/actions/dune +++ b/editor/actions/dune @@ -1,11 +1,10 @@ (library - (name actions) + (name editor_actions) (libraries brr brr.note elements blog - js_lib forms state ) diff --git a/editor/actions/actions.ml b/editor/actions/editor_actions.ml index f35beef..8c47363 100755 --- a/editor/actions/actions.ml +++ b/editor/actions/editor_actions.ml @@ -3,14 +3,8 @@ open Js_of_ocaml open Brr open Brr_note -type button_actions = - { delete : State.event Note.event - ; redirect : State.event Note.event - ; add: State.event Note.event - } - let populate_menu - : unit -> button_actions option + : unit -> State.event Note.event option = fun () -> match Blog.Sidebar.get () with | None -> None @@ -38,6 +32,24 @@ let populate_menu ~at:At.[ class' (Jstr.v "fa") ; class' (Jstr.v "fa-2x") ; class' (Jstr.v "fa-plus") ] ] + + and export_button = El.button + ~at:At.[class' (Jstr.v "action-button")] + [ El.i + [] + ~at:At.[ class' (Jstr.v "fa") + ; class' (Jstr.v "fa-2x") + ; class' (Jstr.v "fa-download") ] + ] + + and load_button = El.button + ~at:At.[class' (Jstr.v "action-button")] + [ El.i + [] + ~at:At.[ class' (Jstr.v "fa") + ; class' (Jstr.v "fa-2x") + ; class' (Jstr.v "fa-upload") ] + ] in (* We are waiting for event inside another event ( form validation inside @@ -57,7 +69,15 @@ let populate_menu Evr.on_el Ev.click (fun _ -> Add_page.create ()) - add_button) in + add_button) + + and export_event = + Note.E.join ( + Evr.on_el + Ev.click + (fun _ -> Export.create ()) + export_button) + in let stored_pages = State.Storage.get_ids () in @@ -103,14 +123,8 @@ let populate_menu let childs = [ home_button ; add_button - ; El.button - ~at:At.[class' (Jstr.v "action-button")] - [ El.i - [] - ~at:At.[ class' (Jstr.v "fa") - ; class' (Jstr.v "fa-2x") - ; class' (Jstr.v "fa-download") ] - ] + ; export_button + ; load_button ; delete_button ; El.button ~at:At.[class' (Jstr.v "action-button")] @@ -126,8 +140,11 @@ let populate_menu ] in let () = El.append_children element childs in - Some - { delete = delete_event - ; redirect = redirect_event - ; add = add_event - } + + Some ( + Note.E.select + [ delete_event + ; redirect_event + ; add_event + ; export_event + ]) diff --git a/editor/actions/export.ml b/editor/actions/export.ml new file mode 100755 index 0000000..a97eeac --- /dev/null +++ b/editor/actions/export.ml @@ -0,0 +1,46 @@ +module Js = Js_of_ocaml.Js + +module M = struct + + type t = unit + + let update + : t -> State.t -> State.t + = fun _ state -> + + (* Save this as a json element. The text may contains UTF-16 characters, + which will raise an error in the btoa function. + + As an easy solution, we convert them into UTF-8 through the native + OCaml representation of string. + *) + let json = State.Storage.to_json () + |> Jstr.to_string (* Encode into UTF-8 *) + |> Obj.magic (* Then type the element again as a string. *) + in + Elements.Transfert.send + ~mime_type:(Jstr.v "application/json") + ~filename:(Jstr.v "export.json") + json; + + (* The function does not actually update the state, and return it + unchanged *) + state + +end + +(** Create a new element *) +let create + : unit -> State.event Note.event + = fun () -> + let title = Jstr.v "Confirmation" + and message = Jstr.v "Exporter les notes" in + let ev = Elements.Popup.create + ~title + ~form:(Some (Forms.Validation.create message )) + in + Note.E.map + (fun v -> State.E + ( v + , (module M : State.Event with type t = M.t ))) + (Note.E.Option.on_some ev) diff --git a/editor/dune b/editor/dune index 8f2e3d1..6b13228 100755 --- a/editor/dune +++ b/editor/dune @@ -3,15 +3,11 @@ (libraries brr brr.note - elements - js_lib prosemirror blog - application state plugins - forms - actions + editor_actions ) (modes js) (preprocess (pps js_of_ocaml-ppx)) diff --git a/editor/editor.ml b/editor/editor.ml index 79ad54a..c80b426 100755 --- a/editor/editor.ml +++ b/editor/editor.ml @@ -2,6 +2,8 @@ open Brr module PM = Prosemirror module Js = Js_of_ocaml.Js +module Actions = Editor_actions + (** Create a new editor view [build_view element state] will create the editor and attach it to [element]. @@ -131,9 +133,7 @@ let app id content = (State.E ( () , (module Store:State.Event with type t = Store.t)))) editor - ; Note.E.map (fun ev -> ev) btn_events.Actions.delete - ; Note.E.map (fun ev -> ev) btn_events.Actions.add - ; Note.E.map (fun v -> v) btn_events.Actions.redirect + ; btn_events ]) in let () = diff --git a/editor/forms/delete_page.ml b/editor/forms/delete_page.ml deleted file mode 100755 index 37b1c32..0000000 --- a/editor/forms/delete_page.ml +++ /dev/null @@ -1,18 +0,0 @@ -open Brr -open Note - -type t = unit - -let create - : unit -> t Note.signal * El.t - = fun () -> - let state = S.const () in - - let message = begin - let open Jstr in - - (v "La page sera définitivement supprimée") - end in - - ( state - , El.txt message ) diff --git a/editor/forms/delete_page.mli b/editor/forms/delete_page.mli deleted file mode 100755 index 0a3d9f9..0000000 --- a/editor/forms/delete_page.mli +++ /dev/null @@ -1,5 +0,0 @@ -type t = unit - -val create - : unit -> t Note.signal * Brr.El.t - diff --git a/editor/forms/dune b/editor/forms/dune index 124ce01..5aaf249 100755 --- a/editor/forms/dune +++ b/editor/forms/dune @@ -3,10 +3,6 @@ (libraries brr brr.note - elements - js_lib - blog - application state ) (preprocess (pps js_of_ocaml-ppx)) diff --git a/editor/forms/validation.ml b/editor/forms/validation.ml new file mode 100755 index 0000000..cda7db8 --- /dev/null +++ b/editor/forms/validation.ml @@ -0,0 +1,13 @@ +open Brr +open Note + +type t = unit + +let create + : Jstr.t -> t Note.signal * El.t + = fun message -> + let state = S.const () in + + + ( state + , El.txt message ) diff --git a/editor/forms/validation.mli b/editor/forms/validation.mli new file mode 100755 index 0000000..680b3ed --- /dev/null +++ b/editor/forms/validation.mli @@ -0,0 +1,5 @@ +type t = unit + +val create + : Jstr.t -> t Note.signal * Brr.El.t + diff --git a/editor/state/storage.ml b/editor/state/storage.ml index b0c00de..a790a9d 100755 --- a/editor/state/storage.ml +++ b/editor/state/storage.ml @@ -1,4 +1,5 @@ open Brr +open StdLabels module Js = Js_of_ocaml.Js let storage_key = (Jstr.v "editor") @@ -136,3 +137,23 @@ let get_ids in add_element [] items + +let save_for_id + : Jstr.t option -> 'a Js.t + = fun id -> + let element = load id in + object%js + val title = element##.title + val content = element##.content + val date = element##.date + val id = id + end + +let to_json + : unit -> Jstr.t + = fun () -> + let keys = get_ids () in + let pages = List.map ~f:(fun id -> save_for_id (Some id)) keys in + (* Also add the home page *) + let pages = Array.of_list @@ (save_for_id None)::pages in + Brr.Json.encode (Jv.Id.to_jv pages) diff --git a/editor/state/storage.mli b/editor/state/storage.mli index 5b7e0a0..50e164e 100755 --- a/editor/state/storage.mli +++ b/editor/state/storage.mli @@ -34,3 +34,6 @@ val delete (** Collect all the keys to the existing pages *) val get_ids : unit -> Jstr.t list + +val to_json + : unit -> Jstr.t |