mirror of
https://code.sup39.dev/repos/Wqawg
synced 2024-12-29 01:54:50 +09:00
Repo settings page, allow repos to move between projects
This commit is contained in:
parent
72def092b2
commit
5305caf0b0
7 changed files with 126 additions and 11 deletions
|
@ -68,7 +68,8 @@
|
||||||
|
|
||||||
/s/#ShrIdent/r ReposR GET POST
|
/s/#ShrIdent/r ReposR GET POST
|
||||||
/s/#ShrIdent/r/!new RepoNewR GET
|
/s/#ShrIdent/r/!new RepoNewR GET
|
||||||
/s/#ShrIdent/r/#RpIdent RepoR GET DELETE POST
|
/s/#ShrIdent/r/#RpIdent RepoR GET PUT DELETE POST
|
||||||
|
/s/#ShrIdent/r/#RpIdent/edit RepoEditR GET
|
||||||
/s/#ShrIdent/r/#RpIdent/s/+Texts RepoSourceR GET
|
/s/#ShrIdent/r/#RpIdent/s/+Texts RepoSourceR GET
|
||||||
/s/#ShrIdent/r/#RpIdent/c RepoHeadChangesR GET
|
/s/#ShrIdent/r/#RpIdent/c RepoHeadChangesR GET
|
||||||
/s/#ShrIdent/r/#RpIdent/c/#Text RepoChangesR GET
|
/s/#ShrIdent/r/#RpIdent/c/#Text RepoChangesR GET
|
||||||
|
|
|
@ -15,17 +15,21 @@
|
||||||
|
|
||||||
module Vervis.Field.Repo
|
module Vervis.Field.Repo
|
||||||
( mkIdentField
|
( mkIdentField
|
||||||
|
, selectProjectForNew
|
||||||
|
, selectProjectForExisting
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
import Vervis.Import hiding ((==.))
|
import Vervis.Import hiding ((==.), on, isNothing)
|
||||||
|
|
||||||
import Data.Char (isDigit)
|
import Data.Char (isDigit)
|
||||||
import Data.Char.Local (isAsciiLetter)
|
import Data.Char.Local (isAsciiLetter)
|
||||||
import Data.Text (split)
|
import Data.Text (split)
|
||||||
import Database.Esqueleto
|
import Database.Esqueleto
|
||||||
|
|
||||||
import Vervis.Model.Ident (text2rp)
|
import qualified Database.Persist as P ((==.))
|
||||||
|
|
||||||
|
import Vervis.Model.Ident (text2rp, prj2text)
|
||||||
|
|
||||||
checkIdentTemplate :: Field Handler Text -> Field Handler Text
|
checkIdentTemplate :: Field Handler Text -> Field Handler Text
|
||||||
checkIdentTemplate =
|
checkIdentTemplate =
|
||||||
|
@ -54,3 +58,38 @@ checkIdentUnique sid = checkM $ \ ident -> do
|
||||||
|
|
||||||
mkIdentField :: SharerId -> Field Handler Text
|
mkIdentField :: SharerId -> Field Handler Text
|
||||||
mkIdentField sid = checkIdentUnique sid . checkIdentTemplate $ textField
|
mkIdentField sid = checkIdentUnique sid . checkIdentTemplate $ textField
|
||||||
|
|
||||||
|
-- | Select a project for a new repository to belong to. It can be any project
|
||||||
|
-- of the same sharer who's sharing the repo.
|
||||||
|
selectProjectForNew :: SharerId -> Field Handler ProjectId
|
||||||
|
selectProjectForNew sid =
|
||||||
|
selectField $
|
||||||
|
optionsPersistKey [ProjectSharer P.==. sid] [] $
|
||||||
|
prj2text . projectIdent
|
||||||
|
|
||||||
|
-- | Select a project for a repository to belong to. It can be any project of
|
||||||
|
-- the same sharer who's sharing the repo.
|
||||||
|
--
|
||||||
|
-- However, there's an additional requirement that all repo collaborators are
|
||||||
|
-- also project collaborators. I'm not sure I want this requirement, but it's
|
||||||
|
-- easier to require it now and remove later, than require it later when the DB
|
||||||
|
-- is already full of live repos and projects.
|
||||||
|
--
|
||||||
|
-- Also, a repo that is the wiki of the project can't be moved, but this is NOT
|
||||||
|
-- CHECKED HERE. That's something to check before running the form, i.e. in the
|
||||||
|
-- handler itself.
|
||||||
|
selectProjectForExisting :: SharerId -> RepoId -> Field Handler ProjectId
|
||||||
|
selectProjectForExisting sid rid = checkMembers $ selectProjectForNew sid
|
||||||
|
where
|
||||||
|
checkMembers = checkM $ \ jid -> do
|
||||||
|
l <- runDB $ select $ from $ \ (rc `LeftOuterJoin` pc) -> do
|
||||||
|
on $
|
||||||
|
rc ^. RepoCollabRepo ==. val rid &&.
|
||||||
|
pc ?. ProjectCollabProject ==. just (val jid) &&.
|
||||||
|
pc ?. ProjectCollabPerson ==. just (rc ^. RepoCollabPerson)
|
||||||
|
where_ $ isNothing $ pc ?. ProjectCollabId
|
||||||
|
limit 1
|
||||||
|
return ()
|
||||||
|
return $ if null l
|
||||||
|
then Right jid
|
||||||
|
else Left ("Some repo members aren't project members" :: Text)
|
||||||
|
|
|
@ -77,10 +77,10 @@ editProjectAForm :: Entity Project -> AForm Handler Project
|
||||||
editProjectAForm (Entity jid project) = Project
|
editProjectAForm (Entity jid project) = Project
|
||||||
<$> pure (projectIdent project)
|
<$> pure (projectIdent project)
|
||||||
<*> pure (projectSharer project)
|
<*> pure (projectSharer project)
|
||||||
<*> aopt textField "Name*" (Just $ projectName project)
|
<*> aopt textField "Name" (Just $ projectName project)
|
||||||
<*> aopt textField "Description*" (Just $ projectDesc project)
|
<*> aopt textField "Description" (Just $ projectDesc project)
|
||||||
<*> pure (projectNextTicket project)
|
<*> pure (projectNextTicket project)
|
||||||
<*> aopt selectWiki "Wiki*" (Just $ projectWiki project)
|
<*> aopt selectWiki "Wiki" (Just $ projectWiki project)
|
||||||
where
|
where
|
||||||
selectWiki =
|
selectWiki =
|
||||||
selectField $
|
selectField $
|
||||||
|
|
|
@ -18,6 +18,7 @@ module Vervis.Form.Repo
|
||||||
, newRepoForm
|
, newRepoForm
|
||||||
, NewRepoCollab (..)
|
, NewRepoCollab (..)
|
||||||
, newRepoCollabForm
|
, newRepoCollabForm
|
||||||
|
, editRepoForm
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
|
@ -46,7 +47,7 @@ newRepoAForm
|
||||||
newRepoAForm pid sid mpid = NewRepo
|
newRepoAForm pid sid mpid = NewRepo
|
||||||
<$> (text2rp <$> areq (mkIdentField sid) "Identifier*" Nothing)
|
<$> (text2rp <$> areq (mkIdentField sid) "Identifier*" Nothing)
|
||||||
<*> areq (selectFieldList vcsList) "Version control system*" Nothing
|
<*> areq (selectFieldList vcsList) "Version control system*" Nothing
|
||||||
<*> aopt selectProject "Project" (Just mpid)
|
<*> aopt (selectProjectForNew sid) "Project" (Just mpid)
|
||||||
<*> aopt textField "Description" Nothing
|
<*> aopt textField "Description" Nothing
|
||||||
<*> areq selectRole "Your role*" Nothing
|
<*> areq selectRole "Your role*" Nothing
|
||||||
where
|
where
|
||||||
|
@ -55,10 +56,6 @@ newRepoAForm pid sid mpid = NewRepo
|
||||||
[ ("Darcs", VCSDarcs)
|
[ ("Darcs", VCSDarcs)
|
||||||
, ("Git" , VCSGit)
|
, ("Git" , VCSGit)
|
||||||
]
|
]
|
||||||
selectProject =
|
|
||||||
selectField $
|
|
||||||
optionsPersistKey [ProjectSharer ==. sid] [Asc ProjectIdent] $
|
|
||||||
prj2text . projectIdent
|
|
||||||
selectRole =
|
selectRole =
|
||||||
selectField $
|
selectField $
|
||||||
optionsPersistKey [RepoRolePerson ==. pid] [] $
|
optionsPersistKey [RepoRolePerson ==. pid] [] $
|
||||||
|
@ -113,3 +110,20 @@ newRepoCollabAForm pid mjid rid = NewRepoCollab
|
||||||
newRepoCollabForm
|
newRepoCollabForm
|
||||||
:: PersonId -> Maybe ProjectId -> RepoId -> Form NewRepoCollab
|
:: PersonId -> Maybe ProjectId -> RepoId -> Form NewRepoCollab
|
||||||
newRepoCollabForm pid mjid rid = renderDivs $ newRepoCollabAForm pid mjid rid
|
newRepoCollabForm pid mjid rid = renderDivs $ newRepoCollabAForm pid mjid rid
|
||||||
|
|
||||||
|
editRepoAForm :: Entity Repo -> AForm Handler Repo
|
||||||
|
editRepoAForm (Entity rid repo) = Repo
|
||||||
|
<$> pure (repoIdent repo)
|
||||||
|
<*> pure (repoSharer repo)
|
||||||
|
<*> pure (repoVcs repo)
|
||||||
|
<*> aopt selectProject' "Project" (Just $ repoProject repo)
|
||||||
|
<*> aopt textField "Description" (Just $ repoDesc repo)
|
||||||
|
<*> let b = repoMainBranch repo
|
||||||
|
in case repoVcs repo of
|
||||||
|
VCSDarcs -> pure b
|
||||||
|
VCSGit -> areq textField "Main branch*" (Just b)
|
||||||
|
where
|
||||||
|
selectProject' = selectProjectForExisting (repoSharer repo) rid
|
||||||
|
|
||||||
|
editRepoForm :: Entity Repo -> Form Repo
|
||||||
|
editRepoForm r = renderDivs $ editRepoAForm r
|
||||||
|
|
|
@ -144,6 +144,7 @@ instance Yesod App where
|
||||||
(ReposR shar , True) -> person shar
|
(ReposR shar , True) -> person shar
|
||||||
(RepoNewR user , _ ) -> person user
|
(RepoNewR user , _ ) -> person user
|
||||||
(RepoR shar _ , True) -> person shar
|
(RepoR shar _ , True) -> person shar
|
||||||
|
(RepoEditR shr _rp , _ ) -> person shr
|
||||||
(RepoDevsR shr _rp , _ ) -> person shr
|
(RepoDevsR shr _rp , _ ) -> person shr
|
||||||
(RepoDevNewR shr _rp , _ ) -> person shr
|
(RepoDevNewR shr _rp , _ ) -> person shr
|
||||||
(RepoDevR shr _rp _dev , _ ) -> person shr
|
(RepoDevR shr _rp _dev , _ ) -> person shr
|
||||||
|
@ -329,6 +330,7 @@ instance YesodBreadcrumbs App where
|
||||||
ReposR shar -> ("Repos", Just $ PersonR shar)
|
ReposR shar -> ("Repos", Just $ PersonR shar)
|
||||||
RepoNewR shar -> ("New", Just $ ReposR shar)
|
RepoNewR shar -> ("New", Just $ ReposR shar)
|
||||||
RepoR shar repo -> (rp2text repo, Just $ ReposR shar)
|
RepoR shar repo -> (rp2text repo, Just $ ReposR shar)
|
||||||
|
RepoEditR shr rp -> ("Edit", Just $ RepoR shr rp)
|
||||||
RepoSourceR shar repo [] -> ("Files", Just $ RepoR shar repo)
|
RepoSourceR shar repo [] -> ("Files", Just $ RepoR shar repo)
|
||||||
RepoSourceR shar repo refdir -> ( last refdir
|
RepoSourceR shar repo refdir -> ( last refdir
|
||||||
, Just $
|
, Just $
|
||||||
|
|
|
@ -18,8 +18,10 @@ module Vervis.Handler.Repo
|
||||||
, postReposR
|
, postReposR
|
||||||
, getRepoNewR
|
, getRepoNewR
|
||||||
, getRepoR
|
, getRepoR
|
||||||
|
, putRepoR
|
||||||
, deleteRepoR
|
, deleteRepoR
|
||||||
, postRepoR
|
, postRepoR
|
||||||
|
, getRepoEditR
|
||||||
, getRepoSourceR
|
, getRepoSourceR
|
||||||
, getRepoHeadChangesR
|
, getRepoHeadChangesR
|
||||||
, getRepoChangesR
|
, getRepoChangesR
|
||||||
|
@ -51,6 +53,7 @@ import Data.List (inits)
|
||||||
import Data.Text (Text, unpack)
|
import Data.Text (Text, unpack)
|
||||||
import Data.Text.Encoding (decodeUtf8With)
|
import Data.Text.Encoding (decodeUtf8With)
|
||||||
import Data.Text.Encoding.Error (lenientDecode)
|
import Data.Text.Encoding.Error (lenientDecode)
|
||||||
|
import Data.Traversable (for)
|
||||||
import Database.Esqueleto hiding (delete, (%))
|
import Database.Esqueleto hiding (delete, (%))
|
||||||
import Database.Persist (delete)
|
import Database.Persist (delete)
|
||||||
import Data.Hourglass (timeConvert)
|
import Data.Hourglass (timeConvert)
|
||||||
|
@ -170,6 +173,35 @@ getRepoR shar repo = do
|
||||||
getGitRepoSource
|
getGitRepoSource
|
||||||
repository shar repo (repoMainBranch repository) []
|
repository shar repo (repoMainBranch repository) []
|
||||||
|
|
||||||
|
putRepoR :: ShrIdent -> RpIdent -> Handler Html
|
||||||
|
putRepoR shr rp = do
|
||||||
|
mer <- runDB $ do
|
||||||
|
Entity sid _ <- getBy404 $ UniqueSharer shr
|
||||||
|
er@(Entity rid r) <- getBy404 $ UniqueRepo rp sid
|
||||||
|
mwiki <- for (repoProject r) $ \ jid -> do
|
||||||
|
project <- getJust jid
|
||||||
|
return $ (== rid) <$> projectWiki project
|
||||||
|
return $ case mwiki of
|
||||||
|
Just (Just True) -> Nothing
|
||||||
|
_ -> Just er
|
||||||
|
case mer of
|
||||||
|
Nothing -> do
|
||||||
|
setMessage "Repo used as a wiki, can't move between projects."
|
||||||
|
redirect $ RepoR shr rp
|
||||||
|
Just er@(Entity rid _) -> do
|
||||||
|
((result, widget), enctype) <- runFormPost $ editRepoForm er
|
||||||
|
case result of
|
||||||
|
FormSuccess repository' -> do
|
||||||
|
runDB $ replace rid repository'
|
||||||
|
setMessage "Repository updated."
|
||||||
|
redirect $ RepoR shr rp
|
||||||
|
FormMissing -> do
|
||||||
|
setMessage "Field(s) missing."
|
||||||
|
defaultLayout $(widgetFile "repo/edit")
|
||||||
|
FormFailure _l -> do
|
||||||
|
setMessage "Repository update failed, see errors below."
|
||||||
|
defaultLayout $(widgetFile "repo/edit")
|
||||||
|
|
||||||
deleteRepoR :: ShrIdent -> RpIdent -> Handler Html
|
deleteRepoR :: ShrIdent -> RpIdent -> Handler Html
|
||||||
deleteRepoR shar repo = do
|
deleteRepoR shar repo = do
|
||||||
runDB $ do
|
runDB $ do
|
||||||
|
@ -193,9 +225,18 @@ postRepoR :: ShrIdent -> RpIdent -> Handler Html
|
||||||
postRepoR shar repo = do
|
postRepoR shar repo = do
|
||||||
mmethod <- lookupPostParam "_method"
|
mmethod <- lookupPostParam "_method"
|
||||||
case mmethod of
|
case mmethod of
|
||||||
|
Just "PUT" -> putRepoR shar repo
|
||||||
Just "DELETE" -> deleteRepoR shar repo
|
Just "DELETE" -> deleteRepoR shar repo
|
||||||
_ -> notFound
|
_ -> notFound
|
||||||
|
|
||||||
|
getRepoEditR :: ShrIdent -> RpIdent -> Handler Html
|
||||||
|
getRepoEditR shr rp = do
|
||||||
|
er <- runDB $ do
|
||||||
|
Entity s _ <- getBy404 $ UniqueSharer shr
|
||||||
|
getBy404 $ UniqueRepo rp s
|
||||||
|
((_result, widget), enctype) <- runFormPost $ editRepoForm er
|
||||||
|
defaultLayout $(widgetFile "repo/edit")
|
||||||
|
|
||||||
getRepoSourceR :: ShrIdent -> RpIdent -> [Text] -> Handler Html
|
getRepoSourceR :: ShrIdent -> RpIdent -> [Text] -> Handler Html
|
||||||
getRepoSourceR shar repo refdir = do
|
getRepoSourceR shar repo refdir = do
|
||||||
repository <- runDB $ selectRepo shar repo
|
repository <- runDB $ selectRepo shar repo
|
||||||
|
|
18
templates/repo/edit.hamlet
Normal file
18
templates/repo/edit.hamlet
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
$# This file is part of Vervis.
|
||||||
|
$#
|
||||||
|
$# Written in 2016 by fr33domlover <fr33domlover@riseup.net>.
|
||||||
|
$#
|
||||||
|
$# ♡ Copying is an act of love. Please copy, reuse and share.
|
||||||
|
$#
|
||||||
|
$# The author(s) have dedicated all copyright and related and neighboring
|
||||||
|
$# rights to this software to the public domain worldwide. This software is
|
||||||
|
$# distributed without any warranty.
|
||||||
|
$#
|
||||||
|
$# You should have received a copy of the CC0 Public Domain Dedication along
|
||||||
|
$# with this software. If not, see
|
||||||
|
$# <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||||
|
|
||||||
|
<form method=POST action=@{RepoR shr rp} enctype=#{enctype}>
|
||||||
|
<input type=hidden name=_method value=PUT>
|
||||||
|
^{widget}
|
||||||
|
<input type=submit>
|
Loading…
Reference in a new issue