~jan0sch/smederee

Showing details for patch 3767bb58814e7c5e80e513f41805bf3672fc6d2a.
2022-08-06 (Sat), 2:05 PM - Jens Grassel - 3767bb58814e7c5e80e513f41805bf3672fc6d2a

VCS: implement simple create repo form

- nothing created yet
Summary of changes
4 files modified with 46 lines added and 15 lines removed
  • modules/hub/src/main/resources/messages_en.properties with 4 added and 0 removed lines
  • modules/hub/src/main/scala/de/smederee/hub/VcsRepository.scala with 2 added and 2 removed lines
  • modules/hub/src/main/scala/de/smederee/hub/VcsRepositoryRoutes.scala with 32 added and 5 removed lines
  • modules/hub/src/main/twirl/de/smederee/hub/views/createRepository.scala.html with 8 added and 8 removed lines
diff -rN -u old-smederee/modules/hub/src/main/resources/messages_en.properties new-smederee/modules/hub/src/main/resources/messages_en.properties
--- old-smederee/modules/hub/src/main/resources/messages_en.properties	2025-02-02 22:45:01.517825856 +0000
+++ new-smederee/modules/hub/src/main/resources/messages_en.properties	2025-02-02 22:45:01.517825856 +0000
@@ -13,6 +13,10 @@
 errors.forbidden.title = 403 - Forbidden
 
 # Forms
+form.create-repo.button.submit=Create repository
+form.create-repo.name=Name
+form.create-repo.name.placeholder=Please enter a repository name.
+form.create-repo.name.help=A repository name must start with a letter or number and must contain only alphanumeric ASCII characters as well as minus or underscore signs. It must be between 2 and 64 characters long.
 form.login.button.submit=Login
 form.login.password=Password
 form.login.password.placeholder=Please enter your password here.
diff -rN -u old-smederee/modules/hub/src/main/scala/de/smederee/hub/VcsRepositoryRoutes.scala new-smederee/modules/hub/src/main/scala/de/smederee/hub/VcsRepositoryRoutes.scala
--- old-smederee/modules/hub/src/main/scala/de/smederee/hub/VcsRepositoryRoutes.scala	2025-02-02 22:45:01.517825856 +0000
+++ new-smederee/modules/hub/src/main/scala/de/smederee/hub/VcsRepositoryRoutes.scala	2025-02-02 22:45:01.517825856 +0000
@@ -15,6 +15,7 @@
 import de.smederee.darcs._
 import de.smederee.hub.RequestHelpers.instances.given
 import de.smederee.hub.config._
+import de.smederee.hub.forms.types.FormErrors
 import org.http4s._
 import org.http4s.dsl.Http4sDsl
 import org.http4s.implicits._
@@ -36,10 +37,33 @@
 
   private val parseCreateRepositoryForm: AuthedRoutes[Account, F] = AuthedRoutes.of {
     case ar @ POST -> Root / "repo" / "create" as user =>
-      for {
-        csrf <- Sync[F].delay(ar.req.getCsrfToken)
-        resp <- NotImplemented.apply("Not yet implemented!")
-      } yield resp
+      ar.req.decodeStrict[F, UrlForm] { urlForm =>
+        for {
+          csrf <- Sync[F].delay(ar.req.getCsrfToken)
+          formData <- Sync[F].delay {
+            urlForm.values.map { t =>
+              val (key, values) = t
+              (
+                key,
+                values.headOption.getOrElse("")
+              ) // Pick the first value (a field might get submitted multiple times)!
+            }
+          }
+          form <- Sync[F].delay(NewVcsRepositoryForm.validate(formData))
+          resp <- form match {
+            case Validated.Invalid(es) =>
+              BadRequest.apply(
+                views.html
+                  .createRepository()(createRepoPath, csrf, "Smederee - Create a new repository".some, user)(
+                    formData,
+                    FormErrors.fromNel(es)
+                  )
+              )
+            case Validated.Valid(newVcsForm) =>
+              NotImplemented.apply("Not yet implemented!")
+          }
+        } yield resp
+      }
   }
 
   private val showCreateRepositoryForm: AuthedRoutes[Account, F] = AuthedRoutes.of {
@@ -47,7 +71,10 @@
       for {
         csrf <- Sync[F].delay(ar.req.getCsrfToken)
         // output <- darcs.initialize(config.repositoriesDirectory.toPath)("TEST-REPO")(Chain.empty)
-        resp <- Ok(views.html.createRepository()(createRepoPath, csrf, "Create a new repository".some)())
+        resp <- Ok(
+          views.html
+            .createRepository()(createRepoPath, csrf, "Smederee - Create a new repository".some, user)()
+        )
       } yield resp
   }
 
diff -rN -u old-smederee/modules/hub/src/main/scala/de/smederee/hub/VcsRepository.scala new-smederee/modules/hub/src/main/scala/de/smederee/hub/VcsRepository.scala
--- old-smederee/modules/hub/src/main/scala/de/smederee/hub/VcsRepository.scala	2025-02-02 22:45:01.517825856 +0000
+++ new-smederee/modules/hub/src/main/scala/de/smederee/hub/VcsRepository.scala	2025-02-02 22:45:01.517825856 +0000
@@ -17,7 +17,7 @@
 opaque type VcsRepositoryName = String
 object VcsRepositoryName {
 
-  val Format: Regex = "^[a-z0-9][a-z0-9\\-_]{1,63}$".r
+  val Format: Regex = "^[a-zA-Z0-9][a-zA-Z0-9\\-_]{1,63}$".r
 
   /** Create an instance of VcsRepositoryName from the given String type.
     *
@@ -62,7 +62,7 @@
           if (Format.matches(input))
             input.validNel
           else
-            "Repository name must start with a lowercase letter or number and is only allowed to contain lowercase alphanumeric characters plus .".invalidNel
+            "Repository name must start with a letter or number and is only allowed to contain alphanumeric characters plus .".invalidNel
         (miniumLength, maximumLength, validFormat).mapN { case (_, _, name) =>
           name
         }
diff -rN -u old-smederee/modules/hub/src/main/twirl/de/smederee/hub/views/createRepository.scala.html new-smederee/modules/hub/src/main/twirl/de/smederee/hub/views/createRepository.scala.html
--- old-smederee/modules/hub/src/main/twirl/de/smederee/hub/views/createRepository.scala.html	2025-02-02 22:45:01.517825856 +0000
+++ new-smederee/modules/hub/src/main/twirl/de/smederee/hub/views/createRepository.scala.html	2025-02-02 22:45:01.517825856 +0000
@@ -1,11 +1,11 @@
 @import NewVcsRepositoryForm._
 
-@(lang: LanguageCode = LanguageCode("en"), pathPrefix: Option[Uri] = None)(action: Uri, csrf: Option[CsrfToken] = None, title: Option[String] = None)(formData: Map[String, String] = Map.empty, formErrors: FormErrors = FormErrors.empty)
-@main(lang, pathPrefix)()(csrf, title) {
+@(lang: LanguageCode = LanguageCode("en"), pathPrefix: Option[Uri] = None)(action: Uri, csrf: Option[CsrfToken] = None, title: Option[String] = None, user: Account)(formData: Map[String, String] = Map.empty, formErrors: FormErrors = FormErrors.empty)
+@main(lang, pathPrefix)()(csrf, title, user.some) {
 @defining(lang.toLocale) { implicit locale =>
   <div class="content">
     <div class="pure-g">
-      <div class="pure-u-1-1 pure-u-md-1-1 signup">
+      <div class="l-box pure-u-1-1 pure-u-md-1-1">
         <div class="form-errors">
           @formErrors.get(fieldGlobal).map { es =>
             @for(error <- es) {
@@ -17,18 +17,18 @@
             }
           }
         </div>
-        <div class="signup-form">
+        <div class="create-repo-form">
           <form action="@createFullPath(pathPrefix)(action)" method="POST" accept-charset="UTF-8" class="pure-form pure-form-aligned" autocomplete="on">
             <fieldset id="repository-data">
               <div class="pure-control-group">
-                <label for="@{fieldName}">Name</label>
-                <input class="pure-input-1-2" id="@{fieldName}" name="@{fieldName}" placeholder="Please enter a repository name." maxlength="64" required="" type="text" value="@{formData.get(fieldName)}" autocomplete="username">
-                <small class="pure-form-message" id="@{fieldName}.help">A repository name must start with a letter or number and must contain only lowercase alphanumeric ASCII characters as well as minus or underscore signs. It must be between 2 and 64 characters long.</small>
+                <label for="@{fieldName}">@Messages("form.create-repo.name")</label>
+                <input class="pure-input-1-2" id="@{fieldName}" name="@{fieldName}" placeholder="@Messages("form.create-repo.name.placeholder")" maxlength="64" required="" type="text" value="@{formData.get(fieldName)}" autocomplete="username">
+                <small class="pure-form-message" id="@{fieldName}.help">@Messages("form.create-repo.name.help")</small>
                 @renderFormErrors(fieldName, formErrors)
               </div>
               @csrfToken(csrf)
               <div class="pure-controls">
-                <button type="submit" class="pure-button">@Messages("form.signup.button.submit")</button>
+                <button type="submit" class="pure-button">@Messages("form.create-repo.button.submit")</button>
               </div>
             </fieldset>
           </form>