First version of new ui based on tailwind

This drops fomantic-ui as css toolkit and introduces tailwindcss. With
tailwind there are no predefined components, but it's very easy to
create those. So customizing the look&feel is much simpler, most of
the time no additional css is needed.

This requires a complete rewrite of the markup + styles. Luckily all
logic can be kept as is. The now old ui is not removed, it is still
available by using a request header `Docspell-Ui` with a value of `1`
for the old ui and `2` for the new ui.

Another addition is "dev mode", where docspell serves assets with a
no-cache header, to disable browser caching. This makes developing a
lot easier.
This commit is contained in:
Eike Kettner
2021-01-29 20:48:27 +01:00
parent 442b76c5af
commit dd935454c9
140 changed files with 15077 additions and 214 deletions

View File

@ -40,6 +40,7 @@ case class Duration(nanos: Long) {
}
object Duration {
val zero = Duration(0L)
def apply(d: SDur): Duration =
Duration(d.toNanos)

View File

@ -0,0 +1,49 @@
package docspell.common
import cats.implicits._
sealed trait EnvMode { self: Product =>
val name: String =
productPrefix.toLowerCase
def isDev: Boolean
def isProd: Boolean
}
object EnvMode {
private val sysProp = "docspell.env"
private val envName = "DOCSPELL_ENV"
case object Dev extends EnvMode {
val isDev = true
val isProd = false
}
case object Prod extends EnvMode {
val isDev = false
val isProd = true
}
def dev: EnvMode = Dev
def prod: EnvMode = Prod
def fromString(s: String): Either[String, EnvMode] =
s.toLowerCase match {
case s if s.startsWith("dev") => Right(Dev)
case s if s.startsWith("prod") => Right(Prod)
case _ => Left(s"Invalid env mode: $s")
}
def read: Either[String, Option[EnvMode]] = {
def normalize(str: String): Option[String] =
Option(str).map(_.trim).filter(_.nonEmpty)
normalize(System.getProperty(sysProp))
.orElse(normalize(System.getenv(envName)))
.traverse(fromString)
}
lazy val current: EnvMode =
read.toOption.flatten.getOrElse(prod)
}