@@ -3,19 +3,17 @@ module Page.Deployments
33
44import Control.Lens
55import Control.Monad
6−import Data.ByteString (ByteString)
76import Data.Coerce
87import Data.Generics.Product (field)
98import Data.List as L (null)
109import Data.Map as M (Map, fromList, partition, toList, filter)
11−import Data.Text as T (Text, pack, toCaseFold, isPrefixOf)
12−import Data.Time
13−import Data.Time.Clock.POSIX
10+import Data.Text as T (Text, toCaseFold, isPrefixOf)
1411import Obelisk.Route.Frontend
1512import Reflex.Dom
1613import Servant.Reflex
1714
1815import Common.Types as CT
16+import Common.Utils
1917import Frontend.API
2018import Frontend.Route
2119import Page.ClassicPopup
@@ -28,22 +26,9 @@ deploymentsPage
2826 ( MonadWidget t m
2927 , RouteToUrl (R Routes) m
3028 , SetRoute t (R Routes) m )
31− => m ()
32−deploymentsPage = do
33− headWidget
34− deploymentsWidget
35−
36−headWidget :: MonadWidget t m => m ()
37−headWidget =
38− elClass "header" "header" $
39− divClass "header__wrap container" $ do
40− elClass "b" "header__logo" $
41− text "Deployment Manager"
42− elClass "div" "header__project" $ do
43− pb <- getPostBuild
44− respEv <- projectName pb
45− nameDyn <- holdDyn "" $ uProjectName <$> fmapMaybe reqSuccess respEv
46− dynText nameDyn
29+ => Event t ()
30+ -> m ()
31+deploymentsPage = deploymentsWidget
4732
4833deploymentsWidgetWrapper :: MonadWidget t m => m a -> m a
4934deploymentsWidgetWrapper m =
@@ -55,11 +40,12 @@ deploymentsWidget
5540 ( MonadWidget t m
5641 , RouteToUrl (R Routes) m
5742 , SetRoute t (R Routes) m )
58− => m ()
59−deploymentsWidget = do
43+ => Event t ()
44+ -> m ()
45+deploymentsWidget updAllEv = do
6046 showNewStagingEv <- deploymentsWidgetWrapper $ mdo
6147 (showNewStagingEv', termDyn) <- deploymentsHeadWidget
62− initDeploymentsListWidget termDyn
48+ initDeploymentsListWidget updAllEv termDyn
6349 pure showNewStagingEv'
6450 void $ newStagingPopup showNewStagingEv never
6551
@@ -68,7 +54,7 @@ deploymentsHeadWidget =
6854 divClass "page__head" $ do
6955 elClass "h1" "page__heading title" $ text "All stagings"
7056 divClass "page__note" $ text "Updated <n> mins ago"
71− termDyn <- divClass "page__search input input--search input--has-clear-type" $ mdo
57+ termDyn <- divClass "page__action input input--search input--has-clear-type page__action--search" $ mdo
7258 termDyn' <- inputElement $ def
7359 & initialAttributes .~
7460 ( "type" =: "text"
@@ -79,7 +65,7 @@ deploymentsHeadWidget =
7965 text "Delete"
8066 pure termDyn'
8167 (nsEl, _) <- elClass' "a"
82− "page__add-staging button button--add popup-handler" $ text "New staging"
68+ "page__action button button--add popup-handler" $ text "New staging"
8369 pure $ (domEvent Click nsEl, value termDyn)
8470
8571initDeploymentsListWidget
@@ -87,47 +73,38 @@ initDeploymentsListWidget
8773 ( MonadWidget t m
8874 , RouteToUrl (R Routes) m
8975 , SetRoute t (R Routes) m )
90− => Dynamic t Text -> m ()
91−initDeploymentsListWidget termDyn = dataWidgetWrapper $ do
76+ => Event t ()
77+ -> Dynamic t Text
78+ -> m ()
79+initDeploymentsListWidget updAllEv termDyn = dataWidgetWrapper $ do
9280 pb <- getPostBuild
9381 respEv <- listEndpoint pb
9482 let
9583 okEv = fmapMaybe reqSuccess respEv
9684 errEv = fmapMaybe reqFailure respEv
9785 widgetHold_ loadingDeploymentsWidget $ leftmost
98− [ deploymentsListWidget termDyn <$> okEv
86+ [ deploymentsListWidget updAllEv termDyn <$> okEv
9987 , errDeploymentsWidget <$ errEv ]
10088
101−wsUpdate :: forall t m . MonadWidget t m => m (Event t ())
102−wsUpdate = do
103− let
104− wsConfig = WebSocketConfig
105− { _webSocketConfig_send = (never :: Event t [ByteString])
106− , _webSocketConfig_close = never
107− , _webSocketConfig_reconnect = True
108− , _webSocketConfig_protocols = []
109− }
110− ws <- webSocket "wss://dm-genfly-ws.stage.thebestagent.pro/event" wsConfig
111− pure $ () <$ _webSocket_recv ws
112−
11389deploymentsListWidget
11490 ::
11591 ( MonadWidget t m
11692 , RouteToUrl (R Routes) m
11793 , SetRoute t (R Routes) m )
118− => Dynamic t Text
94+ => Event t ()
95+ -> Dynamic t Text
11996 -> [DeploymentFullInfo]
12097 -> m ()
121−deploymentsListWidget termDyn ds = mdo
122− updAllEv <- wsUpdate
98+deploymentsListWidget updAllEv termDyn ds = mdo
12399 updRespEv <- listEndpoint updAllEv
124100 let
125101 okUpdEv = fmapMaybe reqSuccess updRespEv
126− mkMap = M.fromList . fmap (\x -> (x ^. field @"deployment" . field @"name" , x) )
102+ mkMap = M.fromList . fmap (\x -> (x ^. dfiName , x) )
127103 dsDyn <- fmap mkMap <$> holdDyn ds okUpdEv
128104 stsDyn <- listWithKey dsDyn $ \k d -> do
129105 pb <- getPostBuild
130− respEv <- statusEndpoint (constDyn $ Right k) $ leftmost [pb, () <$ updated d]
106+ respEv <- statusEndpoint (constDyn $ Right k)
107+ $ leftmost [pb, () <$ updated d]
131108 let stEv = fmapMaybe reqSuccess respEv
132109 stDyn <- holdDyn Nothing $ Just <$> stEv
133110 pure $ (, stDyn) <$> d
@@ -150,7 +127,7 @@ searchDeployments term d = term' `isPrefixOf` dname
150127 where
151128 term' = toCaseFold term
152129 dtag = d ^. field @"deployment" . field @"tag" . coerced . to toCaseFold
153− dname = d ^. field @"deployment" . field @"name" . coerced . to toCaseFold
130+ dname = d ^. dfiName . coerced . to toCaseFold
154131
155132flatDynMapDyn
156133 :: (Reflex t, Ord k)
@@ -180,15 +157,6 @@ activeDeploymentsWidget clickedEv dsDyn =
180157 False -> void $ listWithKey dsDyn (activeDeploymentWidget clickedEv)
181158 True -> emptyTableBody $ noDeploymentsWidget
182159
183−statusWidget :: MonadWidget t m => Dynamic t (Maybe DeploymentStatus) -> m ()
184−statusWidget stDyn = do
185− stDyn' <- holdUniqDyn stDyn
186− dyn_ $ stDyn' <&> \case
187− Nothing -> divClass "loading loading--status-alike" $ text "Loading"
188− Just st -> case status st of
189− CT.Ok -> divClass "status status--success" $ text "Success"
190− CT.Error -> divClass "status status--failure" $ text "Failure"
191−
192160activeDeploymentWidget
193161 ::
194162 ( MonadWidget t m
@@ -202,17 +170,15 @@ activeDeploymentWidget clickedEv dname dDyn' = do
202170 dDyn <- holdUniqDyn $ fst <$> dDyn'
203171 let stDyn = join $ snd <$> dDyn'
204172 dyn_ $ ffor dDyn $ \DeploymentFullInfo{..} -> do
205− el "tr" $ do
206− (linkEl, _) <- el' "td" $ do
173+ (linkEl, _) <- el' "tr" $ do
174+ el "td" $ do
207175 text $ coerce dname
208176 statusWidget stDyn
209− let route = DashboardRoute :/ Just dname
210− setRoute $ route <$ domEvent Click linkEl
211177 el "td" $ do
212178 divClass "listing" $
213179 forM_ urls $ \(_, url) ->
214− elAttr "a"
215− ( "class" =: "listing__item external bar"
180+ void $ elDynAttrWithStopPropagationEvent' Click "a"
181+ ( constDyn $ "class" =: "listing__item external bar"
216182 <> "href" =: ("https://" <> url)
217183 <> "target" =: "_blank") $ text url
218184 el "td" $
@@ -224,11 +190,9 @@ activeDeploymentWidget clickedEv dname dDyn' = do
224190 el "b" $ text $ var <> ": "
225191 text val
226192 el "td" $
227− text $ pack $ formatTime defaultTimeLocale (iso8601DateFormat Nothing)
228− $ intToUTCTime createdAt
193+ text $ formatPosixToDate createdAt
229194 el "td" $
230− text $ pack $ formatTime defaultTimeLocale (iso8601DateFormat Nothing)
231− $ intToUTCTime updatedAt
195+ text $ formatPosixToDate updatedAt
232196 el "td" $ do
233197 let
234198 elId = "deployment_row_" <> (coerce $ deployment ^. field @"name")
@@ -247,6 +211,9 @@ activeDeploymentWidget clickedEv dname dDyn' = do
247211 text $ coerce dname <> " staging?"
248212 void $ deleteEndpoint (constDyn $ Right $ dname) delEv
249213 blank
214+ let route = DashboardRoute :/ Just dname
215+ setRoute $ route <$ domEvent Click linkEl
216+ blank
250217
251218archivedDeploymentsWidget
252219 :: MonadWidget t m
@@ -308,11 +275,9 @@ archivedDeploymentWidget clickedEv dDyn' = do
308275 el "b" $ text $ var <> ": "
309276 text val
310277 el "td" $
311− text $ pack $ formatTime defaultTimeLocale (iso8601DateFormat Nothing)
312− $ intToUTCTime createdAt
278+ text $ formatPosixToDate createdAt
313279 el "td" $
314− text $ pack $ formatTime defaultTimeLocale (iso8601DateFormat Nothing)
315− $ intToUTCTime updatedAt
280+ text $ formatPosixToDate updatedAt
316281 el "td" $ do
317282 let
318283 elId = "deployment_row_" <> (coerce $ deployment ^. field @"name")
@@ -327,12 +292,9 @@ archivedDeploymentWidget clickedEv dDyn' = do
327292 pure never
328293 dropdownWidget' clickedEv btn body
329294
330−intToUTCTime :: Int -> UTCTime
331−intToUTCTime = posixSecondsToUTCTime . realToFrac
332−
333295tableWrapper :: MonadWidget t m => m a -> m a
334296tableWrapper ma =
335− divClass "stagings-table" $
297+ divClass "table table--stagings table--clickable" $
336298 el "table" $ do
337299 tableHeader
338300 el "tbody" ma
@@ -379,7 +341,7 @@ _badSearchWidget = do
379341
380342emptyTableBody :: MonadWidget t m => m () -> m ()
381343emptyTableBody msg =
382− elClass "tr" "no-stagings-table" $
344+ elClass "tr" "no-table" $
383345 elAttr "td" ("colspan" =: "7") msg
384346
385347dataWidgetWrapper :: MonadWidget t m => m a -> m a