This commit is contained in:
Joey Hess 2012-11-25 00:26:46 -04:00
parent 3bd354ab84
commit 59733456ed
15 changed files with 129 additions and 172 deletions

View file

@ -22,48 +22,9 @@ import Data.Text (Text)
import Control.Concurrent.STM
import Control.Concurrent
data NavBarItem = DashBoard | Config | About
deriving (Eq)
navBarName :: NavBarItem -> Text
navBarName DashBoard = "Dashboard"
navBarName Config = "Configuration"
navBarName About = "About"
navBarRoute :: NavBarItem -> Route WebApp
navBarRoute DashBoard = HomeR
navBarRoute Config = ConfigR
navBarRoute About = AboutR
defaultNavBar :: [NavBarItem]
defaultNavBar = [DashBoard, Config, About]
firstRunNavBar :: [NavBarItem]
firstRunNavBar = [Config, About]
selectNavBar :: Handler [NavBarItem]
selectNavBar = ifM (inFirstRun) (return firstRunNavBar, return defaultNavBar)
inFirstRun :: Handler Bool
inFirstRun = isNothing . relDir <$> getYesod
{- Used instead of defaultContent; highlights the current page if it's
- on the navbar. -}
bootstrap :: Maybe NavBarItem -> Widget -> Handler RepHtml
bootstrap navbaritem content = do
webapp <- getYesod
navbar <- map navdetails <$> selectNavBar
page <- widgetToPageContent $ do
addStylesheet $ StaticR css_bootstrap_css
addStylesheet $ StaticR css_bootstrap_responsive_css
addScript $ StaticR jquery_full_js
addScript $ StaticR js_bootstrap_dropdown_js
addScript $ StaticR js_bootstrap_modal_js
$(widgetFile "page")
hamletToRepHtml $(hamletFile $ hamletTemplate "bootstrap")
where
navdetails i = (navBarName i, navBarRoute i, Just i == navbaritem)
newWebAppState :: IO (TMVar WebAppState)
newWebAppState = do
otherrepos <- listOtherRepos
@ -156,12 +117,12 @@ listOtherRepos = do
return $ sort $ zip names dirs
htmlIcon :: AlertIcon -> GWidget sub master ()
htmlIcon ActivityIcon = bootStrapIcon "refresh"
htmlIcon InfoIcon = bootStrapIcon "info-sign"
htmlIcon SuccessIcon = bootStrapIcon "ok"
htmlIcon ErrorIcon = bootStrapIcon "exclamation-sign"
htmlIcon ActivityIcon = bootstrapIcon "refresh"
htmlIcon InfoIcon = bootstrapIcon "info-sign"
htmlIcon SuccessIcon = bootstrapIcon "ok"
htmlIcon ErrorIcon = bootstrapIcon "exclamation-sign"
-- utf-8 umbrella (utf-8 cloud looks too stormy)
htmlIcon TheCloud = [whamlet|&#9730;|]
bootStrapIcon :: Text -> GWidget sub master ()
bootStrapIcon name = [whamlet|<i .icon-#{name}></i>|]
bootstrapIcon :: Text -> GWidget sub master ()
bootstrapIcon name = [whamlet|<i .icon-#{name}></i>|]

View file

@ -0,0 +1,17 @@
{- git-annex assistant webapp, common imports
-
- Copyright 2012 Joey Hess <joey@kitenet.net>
-
- Licensed under the GNU AGPL version 3 or higher.
-}
module Assistant.WebApp.Common (module X) where
import Assistant.Common as X
import Assistant.WebApp as X
import Assistant.WebApp.Page as X
import Assistant.WebApp.Types as X
import Utility.Yesod as X
import Data.Text as X (Text)

View file

@ -9,15 +9,11 @@
module Assistant.WebApp.Configurators where
import Assistant.Common
import Assistant.WebApp.Common
import Assistant.DaemonStatus
import Assistant.WebApp
import Assistant.WebApp.Types
import Assistant.WebApp.SideBar
import Assistant.WebApp.Notifications
import Assistant.WebApp.Utility
import Assistant.WebApp.Configurators.Local
import Utility.Yesod
import qualified Remote
import qualified Types.Remote as Remote
import Annex.UUID (getUUID)
@ -30,21 +26,18 @@ import Assistant.XMPP.Client
#endif
import Yesod
import Data.Text (Text)
import qualified Data.Map as M
{- The main configuration screen. -}
getConfigR :: Handler RepHtml
getConfigR = ifM (inFirstRun)
( getFirstRepositoryR
, bootstrap (Just Config) $ do
, page "Configuration" (Just Config) $ do
#ifdef WITH_XMPP
xmppconfigured <- lift $ runAnnex False $ isJust <$> getXMPPCreds
#else
let xmppconfigured = False
#endif
sideBarDisplay
setTitle "Configuration"
$(widgetFile "configurators/main")
)
@ -70,9 +63,7 @@ makeCloudRepositories = $(widgetFile "configurators/repositories/cloud")
{- Lists known repositories, followed by options to add more. -}
getRepositoriesR :: Handler RepHtml
getRepositoriesR = bootstrap (Just Config) $ do
sideBarDisplay
setTitle "Repositories"
getRepositoriesR = page "Repositories" (Just Config) $ do
let repolist = repoListDisplay $ RepoSelector
{ onlyCloud = False
, onlyConfigured = False
@ -120,8 +111,8 @@ notSyncing _ = True
getRepoListR :: RepoListNotificationId -> Handler RepHtml
getRepoListR (RepoListNotificationId nid reposelector) = do
waitNotifier getRepoListBroadcaster nid
page <- widgetToPageContent $ repoListDisplay reposelector
hamletToRepHtml $ [hamlet|^{pageBody page}|]
p <- widgetToPageContent $ repoListDisplay reposelector
hamletToRepHtml $ [hamlet|^{pageBody p}|]
repoListDisplay :: RepoSelector -> Widget
repoListDisplay reposelector = do

View file

@ -9,13 +9,9 @@
module Assistant.WebApp.Configurators.AWS where
import Assistant.Common
import Assistant.WebApp.Common
import Assistant.MakeRemote
import Assistant.Sync
import Assistant.WebApp
import Assistant.WebApp.Types
import Assistant.WebApp.SideBar
import Utility.Yesod
#ifdef WITH_S3
import qualified Remote.S3 as S3
#endif
@ -28,15 +24,11 @@ import Types.StandardGroups
import Logs.PreferredContent
import Yesod
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Map as M
awsConfigurator :: Widget -> Handler RepHtml
awsConfigurator a = bootstrap (Just Config) $ do
sideBarDisplay
setTitle "Add an Amazon repository"
a
awsConfigurator = page "Add an Amazon repository" (Just Config)
glacierConfigurator :: Widget -> Handler RepHtml
glacierConfigurator a = do

View file

@ -9,15 +9,11 @@
module Assistant.WebApp.Configurators.Edit where
import Assistant.Common
import Assistant.WebApp
import Assistant.WebApp.Types
import Assistant.WebApp.SideBar
import Assistant.WebApp.Common
import Assistant.WebApp.Utility
import Assistant.DaemonStatus
import Assistant.MakeRemote (uniqueRemoteName)
import Assistant.WebApp.Configurators.XMPP (xmppNeeded)
import Utility.Yesod
import qualified Remote
import qualified Remote.List as Remote
import Logs.UUID
@ -30,7 +26,6 @@ import qualified Git.Command
import qualified Git.Config
import Yesod
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Map as M
import qualified Data.Set as S
@ -116,10 +111,7 @@ getEditNewCloudRepositoryR :: UUID -> Handler RepHtml
getEditNewCloudRepositoryR uuid = xmppNeeded >> editForm True uuid
editForm :: Bool -> UUID -> Handler RepHtml
editForm new uuid = bootstrap (Just Config) $ do
sideBarDisplay
setTitle "Configure repository"
editForm new uuid = page "Configure repository" (Just Config) $ do
(repo, mremote) <- lift $ runAnnex undefined $ Remote.repoFromUUID uuid
curr <- lift $ runAnnex undefined $ getRepoConfig uuid repo mremote
lift $ checkarchivedirectory curr

View file

@ -9,13 +9,9 @@
module Assistant.WebApp.Configurators.Local where
import Assistant.Common
import Assistant.WebApp
import Assistant.WebApp.Types
import Assistant.WebApp.SideBar
import Assistant.WebApp.Common
import Assistant.WebApp.Utility
import Assistant.MakeRemote
import Utility.Yesod
import Init
import qualified Git
import qualified Git.Construct
@ -35,7 +31,6 @@ import Logs.PreferredContent
import Utility.UserInfo
import Yesod
import Data.Text (Text)
import qualified Data.Text as T
import Data.Char
import System.Posix.Directory
@ -133,9 +128,7 @@ newRepositoryForm defpath msg = do
{- Making the first repository, when starting the webapp for the first time. -}
getFirstRepositoryR :: Handler RepHtml
getFirstRepositoryR = bootstrap (Just Config) $ do
sideBarDisplay
setTitle "Getting started"
getFirstRepositoryR = page "Getting started" (Just Config) $ do
path <- liftIO . defaultRepositoryPath =<< lift inFirstRun
((res, form), enctype) <- lift $ runFormGet $ newRepositoryForm path
case res of
@ -145,9 +138,7 @@ getFirstRepositoryR = bootstrap (Just Config) $ do
{- Adding a new, separate repository. -}
getNewRepositoryR :: Handler RepHtml
getNewRepositoryR = bootstrap (Just Config) $ do
sideBarDisplay
setTitle "Add another repository"
getNewRepositoryR = page "Add another repository" (Just Config) $ do
home <- liftIO myHomeDir
((res, form), enctype) <- lift $ runFormGet $ newRepositoryForm home
case res of
@ -184,9 +175,7 @@ selectDriveForm drives def = renderBootstrap $ RemovableDrive
{- Adding a removable drive. -}
getAddDriveR :: Handler RepHtml
getAddDriveR = bootstrap (Just Config) $ do
sideBarDisplay
setTitle "Add a removable drive"
getAddDriveR = page "AAdd a removable drive" (Just Config) $ do
removabledrives <- liftIO $ driveList
writabledrives <- liftIO $
filterM (canWrite . T.unpack . mountPoint) removabledrives
@ -226,9 +215,7 @@ getAddDriveR = bootstrap (Just Config) $ do
addRemote $ makeGitRemote name dir
getEnableDirectoryR :: UUID -> Handler RepHtml
getEnableDirectoryR uuid = bootstrap (Just Config) $ do
sideBarDisplay
setTitle "Enable a repository"
getEnableDirectoryR uuid = page "Enable a repository" (Just Config) $ do
description <- lift $ runAnnex "" $
T.pack . concat <$> prettyListUUIDs [uuid]
$(widgetFile "configurators/enabledirectory")

View file

@ -11,13 +11,9 @@
module Assistant.WebApp.Configurators.Pairing where
import Assistant.Pairing
import Assistant.WebApp
import Assistant.WebApp.Types
import Assistant.WebApp.SideBar
import Assistant.WebApp.Common
import Assistant.Types.Buddies
import Utility.Yesod
#ifdef WITH_PAIRING
import Assistant.Common
import Assistant.Pairing.Network
import Assistant.Pairing.MakeRemote
import Assistant.Ssh
@ -42,7 +38,6 @@ import Utility.UserInfo
import Git
import Yesod
import Data.Text (Text)
#ifdef WITH_PAIRING
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
@ -293,10 +288,7 @@ sampleQuote = T.unwords
#endif
pairPage :: Widget -> Handler RepHtml
pairPage w = bootstrap (Just Config) $ do
sideBarDisplay
setTitle "Pairing"
w
pairPage = page "Pairing" (Just Config)
noPairing :: Text -> Handler RepHtml
noPairing pairingtype = pairPage $

View file

@ -9,13 +9,9 @@
module Assistant.WebApp.Configurators.Ssh where
import Assistant.Common
import Assistant.WebApp.Common
import Assistant.Ssh
import Assistant.MakeRemote
import Assistant.WebApp
import Assistant.WebApp.Types
import Assistant.WebApp.SideBar
import Utility.Yesod
import Utility.Rsync (rsyncUrlIsShell)
import Logs.Remote
import Remote
@ -24,16 +20,12 @@ import Types.StandardGroups
import Utility.UserInfo
import Yesod
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Map as M
import Network.Socket
sshConfigurator :: Widget -> Handler RepHtml
sshConfigurator a = bootstrap (Just Config) $ do
sideBarDisplay
setTitle "Add a remote server"
a
sshConfigurator = page "Add a remote server" (Just Config)
data SshInput = SshInput
{ hostname :: Maybe Text
@ -291,10 +283,7 @@ getAddRsyncNetR = do
((result, form), enctype) <- runFormGet $
renderBootstrap $ sshInputAForm $
SshInput Nothing Nothing Nothing
let showform status = bootstrap (Just Config) $ do
sideBarDisplay
setTitle "Add a Rsync.net repository"
let authtoken = webAppFormAuthToken
let showform status = page "Add a Rsync.net repository" (Just Config) $
$(widgetFile "configurators/addrsync.net")
case result of
FormSuccess sshinput

View file

@ -9,13 +9,9 @@
module Assistant.WebApp.Configurators.WebDAV where
import Assistant.Common
import Assistant.WebApp.Common
import Assistant.MakeRemote
import Assistant.Sync
import Assistant.WebApp
import Assistant.WebApp.Types
import Assistant.WebApp.SideBar
import Utility.Yesod
import qualified Remote.WebDAV as WebDAV
import qualified Remote
import Types.Remote (RemoteConfig)
@ -24,21 +20,14 @@ import Logs.PreferredContent
import Logs.Remote
import Yesod
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Map as M
webDAVConfigurator :: Widget -> Handler RepHtml
webDAVConfigurator a = bootstrap (Just Config) $ do
sideBarDisplay
setTitle "Add a WebDAV repository"
a
webDAVConfigurator = page "Add a WebDAV repository" (Just Config)
boxConfigurator :: Widget -> Handler RepHtml
boxConfigurator a = bootstrap (Just Config) $ do
sideBarDisplay
setTitle "Add a Box.com repository"
a
boxConfigurator = page "Add a Box.com repository" (Just Config)
data WebDAVInput = WebDAVInput
{ user :: Text

View file

@ -10,14 +10,10 @@
module Assistant.WebApp.Configurators.XMPP where
import Assistant.WebApp
import Assistant.WebApp.Types
import Assistant.WebApp.Common
import Assistant.WebApp.Notifications
import Assistant.WebApp.SideBar
import Utility.Yesod
import Utility.NotificationBroadcaster
#ifdef WITH_XMPP
import Assistant.Common
import Assistant.XMPP.Client
import Assistant.XMPP.Buddies
import Assistant.Types.Buddies
@ -31,7 +27,6 @@ import Yesod
#ifdef WITH_XMPP
import Network
import Network.Protocol.XMPP
import Data.Text (Text)
import qualified Data.Text as T
import Control.Exception (SomeException)
#endif
@ -97,8 +92,8 @@ getBuddyListR :: NotificationId -> Handler RepHtml
getBuddyListR nid = do
waitNotifier getBuddyListBroadcaster nid
page <- widgetToPageContent buddyListDisplay
hamletToRepHtml $ [hamlet|^{pageBody page}|]
p <- widgetToPageContent buddyListDisplay
hamletToRepHtml $ [hamlet|^{pageBody p}|]
buddyListDisplay :: Widget
buddyListDisplay = do
@ -163,7 +158,4 @@ testXMPP creds = either Left (const $ Right creds)
#endif
xmppPage :: Widget -> Handler RepHtml
xmppPage w = bootstrap (Just Config) $ do
sideBarDisplay
setTitle "Jabber"
w
xmppPage = page "Jabber" (Just Config)

View file

@ -9,16 +9,12 @@
module Assistant.WebApp.DashBoard where
import Assistant.Common
import Assistant.WebApp
import Assistant.WebApp.Types
import Assistant.WebApp.Common
import Assistant.WebApp.Utility
import Assistant.WebApp.SideBar
import Assistant.WebApp.Notifications
import Assistant.WebApp.Configurators
import Assistant.TransferQueue
import Utility.NotificationBroadcaster
import Utility.Yesod
import Logs.Transfer
import Utility.Percentage
import Utility.DataUnits
@ -73,20 +69,19 @@ getTransfersR :: NotificationId -> Handler RepHtml
getTransfersR nid = do
waitNotifier getTransferBroadcaster nid
page <- widgetToPageContent $ transfersDisplay False
hamletToRepHtml $ [hamlet|^{pageBody page}|]
p <- widgetToPageContent $ transfersDisplay False
hamletToRepHtml $ [hamlet|^{pageBody p}|]
{- The main dashboard. -}
dashboard :: Bool -> Widget
dashboard warnNoScript = do
sideBarDisplay
let content = transfersDisplay warnNoScript
$(widgetFile "dashboard/main")
getHomeR :: Handler RepHtml
getHomeR = ifM (inFirstRun)
( redirect ConfigR
, bootstrap (Just DashBoard) $ dashboard True
, page "" (Just DashBoard) $ dashboard True
)
{- Used to test if the webapp is running. -}
@ -95,11 +90,11 @@ headHomeR = noop
{- Same as HomeR, except no autorefresh at all (and no noscript warning). -}
getNoScriptR :: Handler RepHtml
getNoScriptR = bootstrap (Just DashBoard) $ dashboard False
getNoScriptR = page "" (Just DashBoard) $ dashboard False
{- Same as HomeR, except with autorefreshing via meta refresh. -}
getNoScriptAutoR :: Handler RepHtml
getNoScriptAutoR = bootstrap (Just DashBoard) $ do
getNoScriptAutoR = page "" (Just DashBoard) $ do
let ident = NoScriptR
let delayseconds = 3 :: Int
let this = NoScriptAutoR

View file

@ -9,12 +9,8 @@
module Assistant.WebApp.Documentation where
import Assistant.Common
import Assistant.WebApp
import Assistant.WebApp.Types
import Assistant.WebApp.SideBar
import Assistant.WebApp.Common
import Assistant.Install (standaloneAppBase)
import Utility.Yesod
import Build.SysConfig (packageversion)
import Yesod
@ -27,9 +23,7 @@ licenseFile = do
return $ (</> "LICENSE") <$> base
getAboutR :: Handler RepHtml
getAboutR = bootstrap (Just About) $ do
sideBarDisplay
setTitle "About git-annex"
getAboutR = page "About git-annex" (Just About) $ do
builtinlicense <- isJust <$> liftIO licenseFile
$(widgetFile "documentation/about")
@ -38,7 +32,7 @@ getLicenseR = do
v <- liftIO licenseFile
case v of
Nothing -> redirect AboutR
Just f -> bootstrap (Just About) $ do
Just f -> customPage (Just About) $ do
-- no sidebar, just pages of legalese..
setTitle "License"
license <- liftIO $ readFile f

66
Assistant/WebApp/Page.hs Normal file
View file

@ -0,0 +1,66 @@
{- git-annex assistant webapp page display
-
- Copyright 2012 Joey Hess <joey@kitenet.net>
-
- Licensed under the GNU AGPL version 3 or higher.
-}
{-# LANGUAGE TypeFamilies, QuasiQuotes, MultiParamTypeClasses, TemplateHaskell, OverloadedStrings, RankNTypes #-}
module Assistant.WebApp.Page where
import Assistant.Common
import Assistant.WebApp
import Assistant.WebApp.Types
import Assistant.WebApp.SideBar
import Utility.Yesod
import Yesod
import Text.Hamlet
import Data.Text (Text)
data NavBarItem = DashBoard | Config | About
deriving (Eq)
navBarName :: NavBarItem -> Text
navBarName DashBoard = "Dashboard"
navBarName Config = "Configuration"
navBarName About = "About"
navBarRoute :: NavBarItem -> Route WebApp
navBarRoute DashBoard = HomeR
navBarRoute Config = ConfigR
navBarRoute About = AboutR
defaultNavBar :: [NavBarItem]
defaultNavBar = [DashBoard, Config, About]
firstRunNavBar :: [NavBarItem]
firstRunNavBar = [Config, About]
selectNavBar :: Handler [NavBarItem]
selectNavBar = ifM (inFirstRun) (return firstRunNavBar, return defaultNavBar)
{- A standard page of the webapp, with a title, a sidebar, and that may
- be highlighted on the navbar. -}
page :: Html -> Maybe NavBarItem -> Widget -> Handler RepHtml
page title navbaritem content = customPage navbaritem $ do
setTitle title
sideBarDisplay
content
{- A custom page, with no title or sidebar set. -}
customPage :: Maybe NavBarItem -> Widget -> Handler RepHtml
customPage navbaritem content = do
webapp <- getYesod
navbar <- map navdetails <$> selectNavBar
pageinfo <- widgetToPageContent $ do
addStylesheet $ StaticR css_bootstrap_css
addStylesheet $ StaticR css_bootstrap_responsive_css
addScript $ StaticR jquery_full_js
addScript $ StaticR js_bootstrap_dropdown_js
addScript $ StaticR js_bootstrap_modal_js
$(widgetFile "page")
hamletToRepHtml $(hamletFile $ hamletTemplate "bootstrap")
where
navdetails i = (navBarName i, navBarRoute i, Just i == navbaritem)

View file

@ -3,12 +3,12 @@ $doctype 5
<head>
<title>
$maybe reldir <- relDir webapp
#{reldir} #{pageTitle page}
#{reldir} #{pageTitle pageinfo}
$nothing
#{pageTitle page}
#{pageTitle pageinfo}
<link rel="icon" href=@{StaticR favicon_ico} type="image/x-icon">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
^{pageHead page}
^{pageHead pageinfo}
<body>
^{pageBody page}
^{pageBody pageinfo}
<div #modal></div>

View file

@ -28,7 +28,7 @@
<form .form-horizontal enctype=#{enctype}>
<fieldset>
^{form}
^{authtoken}
^{webAppFormAuthToken}
<div .form-actions>
<button .btn .btn-primary type=submit onclick="$('#testmodal').modal('show');">
Use this rsync.net repository