WIP: Bulma module now has modal capabilities.
parent
f579353d11
commit
047c21103f
|
@ -3,11 +3,14 @@
|
||||||
-- | This interface allows to:
|
-- | This interface allows to:
|
||||||
-- | - display all resource records of a zone
|
-- | - display all resource records of a zone
|
||||||
-- | - * DONE: SOA, NS, A, AAAA, CNAME, TXT, MX, SRV
|
-- | - * DONE: SOA, NS, A, AAAA, CNAME, TXT, MX, SRV
|
||||||
-- | - add new resource records
|
-- | - DONE: add new resource records
|
||||||
-- | - TODO: modify resource records
|
-- | - DONE: modify resource records
|
||||||
-- | - remove resource records
|
-- | - DONE: remove resource records
|
||||||
-- | - ask for confirmation on deletion
|
-- | - 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: do not allow for the modification of read-only resource records.
|
||||||
-- |
|
-- |
|
||||||
-- | TODO: move all serialization code to a single module.
|
-- | 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.Messages.DNSManagerDaemon as DNSManager
|
||||||
import App.Validation as Validation
|
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
|
-- | `App.ZoneInterface` can send messages through websocket interface
|
||||||
-- | connected to dnsmanagerd. See `App.WS`.
|
-- | connected to dnsmanagerd. See `App.WS`.
|
||||||
-- |
|
-- |
|
||||||
|
@ -118,6 +132,8 @@ data Update_Local_Form
|
||||||
data Action
|
data Action
|
||||||
= DeleteRRModal RRId
|
= DeleteRRModal RRId
|
||||||
| CancelModal
|
| CancelModal
|
||||||
|
| NewRRModal AcceptedRRTypes
|
||||||
|
-- | NewAModal
|
||||||
|
|
||||||
| Initialize
|
| Initialize
|
||||||
|
|
||||||
|
@ -145,6 +161,9 @@ type State =
|
||||||
, wsUp :: Boolean
|
, wsUp :: Boolean
|
||||||
, active_modal :: Maybe Int
|
, active_modal :: Maybe Int
|
||||||
|
|
||||||
|
-- A modal to present a form for adding a new RR.
|
||||||
|
, active_new_rr_modal :: Maybe AcceptedRRTypes
|
||||||
|
|
||||||
-- current entries
|
-- current entries
|
||||||
, _soa :: Maybe (SOARR ())
|
, _soa :: Maybe (SOARR ())
|
||||||
, _srr :: Array (SimpleRR ())
|
, _srr :: Array (SimpleRR ())
|
||||||
|
@ -182,6 +201,7 @@ initialState :: Input -> State
|
||||||
initialState domain =
|
initialState domain =
|
||||||
{ wsUp: true
|
{ wsUp: true
|
||||||
, active_modal: Nothing
|
, active_modal: Nothing
|
||||||
|
, active_new_rr_modal: Nothing
|
||||||
|
|
||||||
, _domain: domain
|
, _domain: domain
|
||||||
|
|
||||||
|
@ -204,10 +224,11 @@ type SortableRecord l = Record (rrtype :: String, rrid :: Int | l)
|
||||||
render :: forall m. State -> H.ComponentHTML Action () m
|
render :: forall m. State -> H.ComponentHTML Action () m
|
||||||
render state
|
render state
|
||||||
= Bulma.section_small
|
= Bulma.section_small
|
||||||
[ case state.wsUp, state.active_modal of
|
[ case state.wsUp, state.active_modal, state.active_new_rr_modal of
|
||||||
false, _ -> Bulma.p "You are disconnected."
|
false, _, _ -> Bulma.p "You are disconnected."
|
||||||
true, Just rr_id -> modal_rr_delete rr_id
|
true, Just rr_id, _ -> modal_rr_delete rr_id
|
||||||
true, Nothing -> HH.div_ [ Bulma.h1 state._domain
|
true, Nothing, Just t -> modal_add_new_rr t
|
||||||
|
true, Nothing, Nothing -> HH.div_ [ Bulma.h1 state._domain
|
||||||
, Bulma.hr
|
, Bulma.hr
|
||||||
, render_soa state._soa
|
, render_soa state._soa
|
||||||
, render_records state._errors $ sorted state._srr
|
, render_records state._errors $ sorted state._srr
|
||||||
|
@ -223,44 +244,67 @@ render state
|
||||||
$ map NonEmpty.toArray
|
$ map NonEmpty.toArray
|
||||||
$ A.groupAllBy (comparing (_.rrtype)) array
|
$ 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 :: forall w. Int -> HH.HTML w Action
|
||||||
modal_rr_delete rr_id =
|
modal_rr_delete rr_id =
|
||||||
modal
|
Bulma.modal
|
||||||
[ modal_background
|
[ Bulma.modal_background
|
||||||
, modal_card [modal_header, modal_body]
|
, Bulma.modal_card [Bulma.modal_header "Deleting a resource record", modal_body]
|
||||||
, modal_foot [modal_delete_button, modal_cancel_button]
|
, Bulma.modal_foot [modal_delete_button, Bulma.modal_cancel_button CancelModal]
|
||||||
]
|
]
|
||||||
where
|
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_body = HH.section [HP.classes C.modal_card_body] [ warning_message ]
|
||||||
modal_foot = HH.div [HP.classes C.modal_card_foot]
|
|
||||||
modal_delete_button
|
modal_delete_button
|
||||||
= HH.button [ HP.classes (C.button <> C.is_success)
|
= HH.button [ HP.classes (C.button <> C.is_success)
|
||||||
, HE.onClick \_ -> RemoveRR rr_id
|
, HE.onClick \_ -> RemoveRR rr_id
|
||||||
] [HH.text "Delete the resource record."]
|
] [HH.text "Delete the resource record."]
|
||||||
modal_cancel_button
|
|
||||||
= HH.button [ HP.classes C.button
|
|
||||||
, HE.onClick \_ -> CancelModal
|
|
||||||
] [HH.text "Cancel"]
|
|
||||||
warning_message
|
warning_message
|
||||||
= HH.p [] [ HH.text $ "You are about to delete a resource record, this actions is "
|
= HH.p [] [ HH.text $ "You are about to delete a resource record, this actions is "
|
||||||
, HH.strong_ [ HH.text "irreversible" ]
|
, HH.strong_ [ HH.text "irreversible" ]
|
||||||
, HH.text "."
|
, 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 :: forall m. MonadAff m => Action -> H.HalogenM State Action () Output m Unit
|
||||||
handleAction = case _ of
|
handleAction = case _ of
|
||||||
|
-- Works for both modals.
|
||||||
CancelModal -> do
|
CancelModal -> do
|
||||||
H.modify_ _ { active_modal = Nothing }
|
H.modify_ _ { active_modal = Nothing, active_new_rr_modal = Nothing }
|
||||||
|
|
||||||
DeleteRRModal rr_id -> do
|
DeleteRRModal rr_id -> do
|
||||||
H.modify_ _ { active_modal = Just rr_id }
|
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
|
Initialize -> do
|
||||||
{ _domain } <- H.get
|
{ _domain } <- H.get
|
||||||
H.raise $ Log $ SimpleLog $ "Asking the server for the zone" <> _domain
|
H.raise $ Log $ SimpleLog $ "Asking the server for the zone" <> _domain
|
||||||
|
@ -739,6 +783,13 @@ render_new_records state
|
||||||
= Bulma.hdiv
|
= Bulma.hdiv
|
||||||
[ Bulma.h1 "Adding new records"
|
[ Bulma.h1 "Adding new records"
|
||||||
, Bulma.hr
|
, 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 []
|
, Bulma.columns []
|
||||||
[ render_new_record_column_simple state._newSRR state._errors
|
[ render_new_record_column_simple state._newSRR state._errors
|
||||||
, render_new_record_colunm_mx state._newMXRR state._errors
|
, render_new_record_colunm_mx state._newMXRR state._errors
|
||||||
|
|
|
@ -292,26 +292,23 @@ btn_delete action
|
||||||
btn_add :: forall w i. i -> i -> Boolean -> HH.HTML w i
|
btn_add :: forall w i. i -> i -> Boolean -> HH.HTML w i
|
||||||
btn_add action1 action2 validity
|
btn_add action1 action2 validity
|
||||||
= HH.button
|
= HH.button
|
||||||
[ btn_add_action validity
|
[ if validity then (HE.onClick \_ -> action1) else (HE.onClick \_ -> action2)
|
||||||
, HP.classes $ btn_classes validity
|
, HP.classes $ btn_classes validity
|
||||||
] [ HH.text "Add" ]
|
] [ 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 :: forall w action. String -> action -> action -> Boolean -> HH.HTML w action
|
||||||
btn title action1 action2 validity
|
btn title action1 action2 validity
|
||||||
= HH.button
|
= HH.button
|
||||||
[ btn_add_action validity
|
[ if validity then (HE.onClick \_ -> action1) else (HE.onClick \_ -> action2)
|
||||||
, HP.classes $ btn_classes validity
|
, HP.classes $ btn_classes validity
|
||||||
] [ HH.text title ]
|
] [ HH.text title ]
|
||||||
where
|
|
||||||
btn_add_action = case _ of
|
|
||||||
true -> HE.onClick \_ -> action1
|
|
||||||
_ -> HE.onClick \_ -> action2
|
|
||||||
|
|
||||||
render_input :: forall w i.
|
render_input :: forall w i.
|
||||||
Boolean -> String -> String -> (String -> i) -> String -> Boolean -> (HP.IProp DHI.HTMLinput i) -> HH.HTML 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 :: forall r i. String -> HP.IProp r i
|
||||||
data_target = HP.attr (AttrName "data-target")
|
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 :: forall w i. String -> HH.HTML w i
|
||||||
modal_domain_delete domain =
|
modal_domain_delete domain =
|
||||||
modal
|
modal
|
||||||
[ modal_background
|
[ 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]
|
, modal_foot [modal_delete_button, modal_cancel_button]
|
||||||
]
|
]
|
||||||
where
|
where
|
||||||
modal = HH.div [HP.classes (C.modal <> C.is_active)]
|
-- modal_header = HH.header [HP.classes C.modal_card_head]
|
||||||
modal_background = HH.div [HP.classes C.modal_background] []
|
-- [ HH.p [HP.classes C.modal_card_title] [HH.text "Deleting a domain"]
|
||||||
modal_card = HH.div [HP.classes C.modal_card]
|
-- --, 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_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_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"]
|
modal_cancel_button = HH.button [HP.classes C.button] [HH.text "Cancel"]
|
||||||
warning_message
|
warning_message
|
||||||
|
|
Loading…
Reference in New Issue