WIP: Bulma module now has modal capabilities.

beta
Philippe Pittoli 2024-01-21 02:47:12 +01:00
parent f579353d11
commit 047c21103f
2 changed files with 108 additions and 44 deletions

View File

@ -3,11 +3,14 @@
-- | This interface allows to:
-- | - display all resource records of a zone
-- | - * DONE: SOA, NS, A, AAAA, CNAME, TXT, MX, SRV
-- | - add new resource records
-- | - TODO: modify resource records
-- | - remove resource records
-- | - ask for confirmation on deletion
-- | - DONE: add new resource records
-- | - DONE: modify resource records
-- | - DONE: remove resource records
-- | - DONE: ask for confirmation on deletion
-- |
-- | WIP: adding a new record should be through a modal presenting a specific form for each RR.
-- | This allows to present relevant information, such as use cases.
-- | Also, errors could be shown and further explained with more available screen space.
-- | TODO: do not allow for the modification of read-only resource records.
-- |
-- | TODO: move all serialization code to a single module.
@ -47,6 +50,17 @@ import App.LogMessage (LogMessage(..))
import App.Messages.DNSManagerDaemon as DNSManager
import App.Validation as Validation
-- | `App.ZoneInterface` accepts to add a few new entry types.
-- | Each entry type has a specific form in a modal, with relevant and dedicated information.
data AcceptedRRTypes
= A
| AAAA
| TXT
| CNAME
| NS
| MX
| SRV
-- | `App.ZoneInterface` can send messages through websocket interface
-- | connected to dnsmanagerd. See `App.WS`.
-- |
@ -118,6 +132,8 @@ data Update_Local_Form
data Action
= DeleteRRModal RRId
| CancelModal
| NewRRModal AcceptedRRTypes
-- | NewAModal
| Initialize
@ -145,6 +161,9 @@ type State =
, wsUp :: Boolean
, active_modal :: Maybe Int
-- A modal to present a form for adding a new RR.
, active_new_rr_modal :: Maybe AcceptedRRTypes
-- current entries
, _soa :: Maybe (SOARR ())
, _srr :: Array (SimpleRR ())
@ -182,6 +201,7 @@ initialState :: Input -> State
initialState domain =
{ wsUp: true
, active_modal: Nothing
, active_new_rr_modal: Nothing
, _domain: domain
@ -204,10 +224,11 @@ type SortableRecord l = Record (rrtype :: String, rrid :: Int | l)
render :: forall m. State -> H.ComponentHTML Action () m
render state
= Bulma.section_small
[ case state.wsUp, state.active_modal of
false, _ -> Bulma.p "You are disconnected."
true, Just rr_id -> modal_rr_delete rr_id
true, Nothing -> HH.div_ [ Bulma.h1 state._domain
[ case state.wsUp, state.active_modal, state.active_new_rr_modal of
false, _, _ -> Bulma.p "You are disconnected."
true, Just rr_id, _ -> modal_rr_delete rr_id
true, Nothing, Just t -> modal_add_new_rr t
true, Nothing, Nothing -> HH.div_ [ Bulma.h1 state._domain
, Bulma.hr
, render_soa state._soa
, render_records state._errors $ sorted state._srr
@ -223,44 +244,67 @@ render state
$ map NonEmpty.toArray
$ A.groupAllBy (comparing (_.rrtype)) array
-- TODO: these components can have a broader use.
-- generic_modal_header :: forall w. String -> HH.HTML w Action
-- generic_modal_header t = HH.header [HP.classes C.modal_card_head]
-- [ HH.p [HP.classes C.modal_card_title] [HH.text t]
-- ]
-- generic_modal_body x = HH.section [HP.classes C.modal_card_body] [ x ]
modal_rr_delete :: forall w. Int -> HH.HTML w Action
modal_rr_delete rr_id =
modal
[ modal_background
, modal_card [modal_header, modal_body]
, modal_foot [modal_delete_button, modal_cancel_button]
Bulma.modal
[ Bulma.modal_background
, Bulma.modal_card [Bulma.modal_header "Deleting a resource record", modal_body]
, Bulma.modal_foot [modal_delete_button, Bulma.modal_cancel_button CancelModal]
]
where
modal = HH.div [HP.classes (C.modal <> C.is_active)]
modal_background = HH.div [HP.classes C.modal_background] []
modal_card = HH.div [HP.classes C.modal_card]
modal_header = HH.header [HP.classes C.modal_card_head]
[ HH.p [HP.classes C.modal_card_title] [HH.text "Deleting a resource record"]
]
modal_body = HH.section [HP.classes C.modal_card_body] [ warning_message ]
modal_foot = HH.div [HP.classes C.modal_card_foot]
modal_delete_button
= HH.button [ HP.classes (C.button <> C.is_success)
, HE.onClick \_ -> RemoveRR rr_id
] [HH.text "Delete the resource record."]
modal_cancel_button
= HH.button [ HP.classes C.button
, HE.onClick \_ -> CancelModal
] [HH.text "Cancel"]
warning_message
= HH.p [] [ HH.text $ "You are about to delete a resource record, this actions is "
, HH.strong_ [ HH.text "irreversible" ]
, HH.text "."
]
modal_add_new_rr :: forall w. AcceptedRRTypes -> HH.HTML w Action
modal_add_new_rr = case _ of
A ->
Bulma.modal
[ Bulma.modal_background
, Bulma.modal_card [Bulma.modal_header "New A resource record"
, modal_body $ Bulma.p "hello, new A RR!"]
, Bulma.modal_foot [Bulma.modal_cancel_button CancelModal]
]
_ ->
Bulma.modal
[ Bulma.modal_background
, Bulma.modal_card [Bulma.modal_header "New ?? resource record"
, modal_body $ Bulma.p "hello, new ?? RR!"]
, Bulma.modal_foot [Bulma.modal_cancel_button CancelModal]
]
where
modal_body x = HH.section [HP.classes C.modal_card_body] [ x ]
-- modal_foot = HH.div [HP.classes C.modal_card_foot]
handleAction :: forall m. MonadAff m => Action -> H.HalogenM State Action () Output m Unit
handleAction = case _ of
-- Works for both modals.
CancelModal -> do
H.modify_ _ { active_modal = Nothing }
H.modify_ _ { active_modal = Nothing, active_new_rr_modal = Nothing }
DeleteRRModal rr_id -> do
H.modify_ _ { active_modal = Just rr_id }
NewRRModal t -> do
H.modify_ _ { active_new_rr_modal = Just t }
-- NewAModal -> do
-- H.modify_ _ { active_modal = Just rr_id }
Initialize -> do
{ _domain } <- H.get
H.raise $ Log $ SimpleLog $ "Asking the server for the zone" <> _domain
@ -739,6 +783,13 @@ render_new_records state
= Bulma.hdiv
[ Bulma.h1 "Adding new records"
, Bulma.hr
, Bulma.columns [] [
Bulma.column_ [
Bulma.p "List of buttons:"
, Bulma.btn_add_new_rr (NewRRModal A) "A"
, Bulma.btn_add_new_rr (NewRRModal AAAA) "AAAA"
]
]
, Bulma.columns []
[ render_new_record_column_simple state._newSRR state._errors
, render_new_record_colunm_mx state._newMXRR state._errors

View File

@ -292,26 +292,23 @@ btn_delete action
btn_add :: forall w i. i -> i -> Boolean -> HH.HTML w i
btn_add action1 action2 validity
= HH.button
[ btn_add_action validity
[ if validity then (HE.onClick \_ -> action1) else (HE.onClick \_ -> action2)
, HP.classes $ btn_classes validity
] [ HH.text "Add" ]
where
btn_add_action = case _ of
true -> HE.onClick \_ -> action1
_ -> HE.onClick \_ -> action2
btn_add_new_rr :: forall w i. i -> String -> HH.HTML w i
btn_add_new_rr action title
= HH.button
[ HE.onClick \_ -> action
, HP.classes $ C.button <> C.is_small <> C.is_info
] [ HH.text title ]
btn :: forall w action. String -> action -> action -> Boolean -> HH.HTML w action
btn title action1 action2 validity
= HH.button
[ btn_add_action validity
[ if validity then (HE.onClick \_ -> action1) else (HE.onClick \_ -> action2)
, HP.classes $ btn_classes validity
] [ HH.text title ]
where
btn_add_action = case _ of
true -> HE.onClick \_ -> action1
_ -> HE.onClick \_ -> action2
render_input :: forall w i.
Boolean -> String -> String -> (String -> i) -> String -> Boolean -> (HP.IProp DHI.HTMLinput i) -> HH.HTML w i
@ -446,23 +443,39 @@ container = HH.div [HP.classes (C.container <> C.is_info)]
data_target :: forall r i. String -> HP.IProp r i
data_target = HP.attr (AttrName "data-target")
modal :: forall w i. Array (HH.HTML w i) -> HH.HTML w i
modal = HH.div [HP.classes (C.modal <> C.is_active)]
modal_background :: forall w i. HH.HTML w i
modal_background = HH.div [HP.classes C.modal_background] []
modal_card :: forall w i. Array (HH.HTML w i) -> HH.HTML w i
modal_card = HH.div [HP.classes C.modal_card]
modal_header :: forall w i. String -> HH.HTML w i
modal_header title = HH.header [HP.classes C.modal_card_head]
[ HH.p [HP.classes C.modal_card_title] [HH.text title]
]
modal_foot :: forall w i. Array (HH.HTML w i) -> HH.HTML w i
modal_foot = HH.div [HP.classes C.modal_card_foot]
modal_cancel_button :: forall w i. i -> HH.HTML w i
modal_cancel_button action
= HH.button [ HP.classes C.button
, HE.onClick \_ -> action
] [HH.text "Cancel"]
modal_domain_delete :: forall w i. String -> HH.HTML w i
modal_domain_delete domain =
modal
[ modal_background
, modal_card [modal_header, modal_body]
, modal_card [modal_header "Deleting a domain", modal_body]
, modal_foot [modal_delete_button, modal_cancel_button]
]
where
modal = HH.div [HP.classes (C.modal <> C.is_active)]
modal_background = HH.div [HP.classes C.modal_background] []
modal_card = HH.div [HP.classes C.modal_card]
modal_header = HH.header [HP.classes C.modal_card_head]
[ HH.p [HP.classes C.modal_card_title] [HH.text "Deleting a domain"]
--, HH.button [HP.classes C.delete, ARIA.label "close"] []
]
-- modal_header = HH.header [HP.classes C.modal_card_head]
-- [ HH.p [HP.classes C.modal_card_title] [HH.text "Deleting a domain"]
-- --, HH.button [HP.classes C.delete, ARIA.label "close"] []
-- ]
modal_body = HH.section [HP.classes C.modal_card_body] [ warning_message ]
modal_foot = HH.div [HP.classes C.modal_card_foot]
-- modal_foot = HH.div [HP.classes C.modal_card_foot]
modal_delete_button = HH.button [HP.classes (C.button <> C.is_success)] [HH.text "Delete the domain."]
modal_cancel_button = HH.button [HP.classes C.button] [HH.text "Cancel"]
warning_message