mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-06-07 07:35:59 +00:00
commit
5974031ac9
@ -92,11 +92,11 @@ def webjarSettings(queryJS: Project) = Seq(
|
|||||||
}.taskValue,
|
}.taskValue,
|
||||||
Compile / resourceGenerators += Def.task {
|
Compile / resourceGenerators += Def.task {
|
||||||
val logger = streams.value.log
|
val logger = streams.value.log
|
||||||
val out = (queryJS/Compile/fullOptJS).value
|
val out = (queryJS / Compile / fullOptJS).value
|
||||||
logger.info(s"Produced query js file: ${out.data}")
|
logger.info(s"Produced query js file: ${out.data}")
|
||||||
copyWebjarResources(
|
copyWebjarResources(
|
||||||
Seq(out.data),
|
Seq(out.data),
|
||||||
(Compile/resourceManaged).value,
|
(Compile / resourceManaged).value,
|
||||||
name.value,
|
name.value,
|
||||||
version.value,
|
version.value,
|
||||||
logger
|
logger
|
||||||
@ -218,7 +218,9 @@ val openapiScalaSettings = Seq(
|
|||||||
field.copy(typeDef = TypeDef("OrgUse", Imports("docspell.common.OrgUse")))
|
field.copy(typeDef = TypeDef("OrgUse", Imports("docspell.common.OrgUse")))
|
||||||
case "equipmentuse" =>
|
case "equipmentuse" =>
|
||||||
field =>
|
field =>
|
||||||
field.copy(typeDef = TypeDef("EquipmentUse", Imports("docspell.common.EquipmentUse")))
|
field.copy(typeDef =
|
||||||
|
TypeDef("EquipmentUse", Imports("docspell.common.EquipmentUse"))
|
||||||
|
)
|
||||||
}))
|
}))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,14 +1,18 @@
|
|||||||
package docspell.analysis.classifier
|
package docspell.analysis.classifier
|
||||||
|
|
||||||
import munit._
|
|
||||||
import cats.effect._
|
|
||||||
import scala.concurrent.ExecutionContext
|
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
import cats.data.NonEmptyList
|
|
||||||
import docspell.common._
|
import scala.concurrent.ExecutionContext
|
||||||
import fs2.Stream
|
|
||||||
import cats.data.Kleisli
|
import cats.data.Kleisli
|
||||||
import TextClassifier.Data
|
import cats.data.NonEmptyList
|
||||||
|
import cats.effect._
|
||||||
|
import fs2.Stream
|
||||||
|
|
||||||
|
import docspell.analysis.classifier.TextClassifier.Data
|
||||||
|
import docspell.common._
|
||||||
|
|
||||||
|
import munit._
|
||||||
|
|
||||||
class StanfordTextClassifierSuite extends FunSuite {
|
class StanfordTextClassifierSuite extends FunSuite {
|
||||||
val logger = Logger.log4s[IO](org.log4s.getLogger)
|
val logger = Logger.log4s[IO](org.log4s.getLogger)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package docspell.analysis.contact
|
package docspell.analysis.contact
|
||||||
|
|
||||||
import docspell.common.{NerLabel, NerTag}
|
import docspell.common.{NerLabel, NerTag}
|
||||||
|
|
||||||
import munit._
|
import munit._
|
||||||
|
|
||||||
class ContactAnnotateSpec extends FunSuite {
|
class ContactAnnotateSpec extends FunSuite {
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
package docspell.analysis.date
|
package docspell.analysis.date
|
||||||
|
|
||||||
import docspell.files.TestFiles
|
|
||||||
import munit._
|
|
||||||
import docspell.common._
|
|
||||||
import java.time._
|
import java.time._
|
||||||
|
|
||||||
|
import docspell.common._
|
||||||
|
import docspell.files.TestFiles
|
||||||
|
|
||||||
|
import munit._
|
||||||
|
|
||||||
class DateFindSpec extends FunSuite {
|
class DateFindSpec extends FunSuite {
|
||||||
|
|
||||||
test("find simple dates") {
|
test("find simple dates") {
|
||||||
|
@ -2,9 +2,10 @@ package docspell.analysis.nlp
|
|||||||
|
|
||||||
import docspell.analysis.Env
|
import docspell.analysis.Env
|
||||||
import docspell.common.Language.NLPLanguage
|
import docspell.common.Language.NLPLanguage
|
||||||
import munit._
|
|
||||||
import docspell.files.TestFiles
|
|
||||||
import docspell.common._
|
import docspell.common._
|
||||||
|
import docspell.files.TestFiles
|
||||||
|
|
||||||
|
import munit._
|
||||||
|
|
||||||
class BaseCRFAnnotatorSuite extends FunSuite {
|
class BaseCRFAnnotatorSuite extends FunSuite {
|
||||||
|
|
||||||
|
@ -3,12 +3,14 @@ package docspell.analysis.nlp
|
|||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
|
|
||||||
import cats.effect.IO
|
import cats.effect.IO
|
||||||
|
|
||||||
import docspell.analysis.Env
|
import docspell.analysis.Env
|
||||||
import munit._
|
|
||||||
import docspell.files.TestFiles
|
|
||||||
import docspell.common._
|
import docspell.common._
|
||||||
import docspell.common.syntax.FileSyntax._
|
import docspell.common.syntax.FileSyntax._
|
||||||
|
import docspell.files.TestFiles
|
||||||
|
|
||||||
import edu.stanford.nlp.pipeline.StanfordCoreNLP
|
import edu.stanford.nlp.pipeline.StanfordCoreNLP
|
||||||
|
import munit._
|
||||||
|
|
||||||
class StanfordNerAnnotatorSuite extends FunSuite {
|
class StanfordNerAnnotatorSuite extends FunSuite {
|
||||||
lazy val germanClassifier =
|
lazy val germanClassifier =
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
package docspell.common
|
package docspell.common
|
||||||
|
|
||||||
|
import docspell.common.Glob._
|
||||||
|
|
||||||
import munit._
|
import munit._
|
||||||
import Glob._
|
|
||||||
|
|
||||||
class GlobTest extends FunSuite {
|
class GlobTest extends FunSuite {
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package docspell.common
|
package docspell.common
|
||||||
|
|
||||||
import cats.implicits._
|
import cats.implicits._
|
||||||
|
|
||||||
import munit._
|
import munit._
|
||||||
|
|
||||||
class LenientUriTest extends FunSuite {
|
class LenientUriTest extends FunSuite {
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
package docspell.common
|
package docspell.common
|
||||||
|
|
||||||
import munit._
|
|
||||||
import cats.data.NonEmptyList
|
import cats.data.NonEmptyList
|
||||||
|
|
||||||
import docspell.common.MetaProposal.Candidate
|
import docspell.common.MetaProposal.Candidate
|
||||||
|
|
||||||
|
import munit._
|
||||||
|
|
||||||
class MetaProposalListTest extends FunSuite {
|
class MetaProposalListTest extends FunSuite {
|
||||||
|
|
||||||
test("flatten retains order of candidates") {
|
test("flatten retains order of candidates") {
|
||||||
|
@ -3,16 +3,18 @@ package docspell.convert
|
|||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
|
|
||||||
import cats.data.Kleisli
|
import cats.data.Kleisli
|
||||||
import cats.implicits._
|
|
||||||
import cats.effect.IO
|
import cats.effect.IO
|
||||||
|
import cats.implicits._
|
||||||
import fs2.Stream
|
import fs2.Stream
|
||||||
|
|
||||||
import docspell.common._
|
import docspell.common._
|
||||||
import docspell.convert.ConversionResult.Handler
|
import docspell.convert.ConversionResult.Handler
|
||||||
|
import docspell.convert.extern.OcrMyPdfConfig
|
||||||
import docspell.convert.extern.{TesseractConfig, UnoconvConfig, WkHtmlPdfConfig}
|
import docspell.convert.extern.{TesseractConfig, UnoconvConfig, WkHtmlPdfConfig}
|
||||||
import docspell.convert.flexmark.MarkdownConfig
|
import docspell.convert.flexmark.MarkdownConfig
|
||||||
import docspell.files.{ExampleFiles, TestFiles}
|
import docspell.files.{ExampleFiles, TestFiles}
|
||||||
|
|
||||||
import munit._
|
import munit._
|
||||||
import docspell.convert.extern.OcrMyPdfConfig
|
|
||||||
|
|
||||||
class ConversionTest extends FunSuite with FileChecks {
|
class ConversionTest extends FunSuite with FileChecks {
|
||||||
val blocker = TestFiles.blocker
|
val blocker = TestFiles.blocker
|
||||||
|
@ -6,6 +6,7 @@ import java.nio.file.{Files, Path}
|
|||||||
import cats.data.Kleisli
|
import cats.data.Kleisli
|
||||||
import cats.effect.IO
|
import cats.effect.IO
|
||||||
import fs2.{Pipe, Stream}
|
import fs2.{Pipe, Stream}
|
||||||
|
|
||||||
import docspell.common.MimeType
|
import docspell.common.MimeType
|
||||||
import docspell.convert.ConversionResult.Handler
|
import docspell.convert.ConversionResult.Handler
|
||||||
import docspell.files.TikaMimetype
|
import docspell.files.TikaMimetype
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
package docspell.convert.extern
|
package docspell.convert.extern
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets
|
||||||
import java.nio.file.{Path, Paths}
|
import java.nio.file.{Path, Paths}
|
||||||
|
|
||||||
import cats.effect._
|
import cats.effect._
|
||||||
|
|
||||||
import docspell.common._
|
import docspell.common._
|
||||||
import docspell.convert._
|
import docspell.convert._
|
||||||
import docspell.files.{ExampleFiles, TestFiles}
|
import docspell.files.{ExampleFiles, TestFiles}
|
||||||
|
|
||||||
import munit._
|
import munit._
|
||||||
import java.nio.charset.StandardCharsets
|
|
||||||
|
|
||||||
class ExternConvTest extends FunSuite with FileChecks {
|
class ExternConvTest extends FunSuite with FileChecks {
|
||||||
val blocker = TestFiles.blocker
|
val blocker = TestFiles.blocker
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package docspell.extract.ocr
|
package docspell.extract.ocr
|
||||||
|
|
||||||
import cats.effect.IO
|
import cats.effect.IO
|
||||||
|
|
||||||
import docspell.common.Logger
|
import docspell.common.Logger
|
||||||
import docspell.files.TestFiles
|
import docspell.files.TestFiles
|
||||||
|
|
||||||
import munit._
|
import munit._
|
||||||
|
|
||||||
class TextExtractionSuite extends FunSuite {
|
class TextExtractionSuite extends FunSuite {
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package docspell.extract.odf
|
package docspell.extract.odf
|
||||||
|
|
||||||
import cats.effect._
|
import cats.effect._
|
||||||
|
|
||||||
import docspell.files.{ExampleFiles, TestFiles}
|
import docspell.files.{ExampleFiles, TestFiles}
|
||||||
|
|
||||||
import munit._
|
import munit._
|
||||||
|
|
||||||
class OdfExtractTest extends FunSuite {
|
class OdfExtractTest extends FunSuite {
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package docspell.extract.pdfbox
|
package docspell.extract.pdfbox
|
||||||
|
|
||||||
import cats.effect._
|
import cats.effect._
|
||||||
|
|
||||||
import docspell.files.{ExampleFiles, TestFiles}
|
import docspell.files.{ExampleFiles, TestFiles}
|
||||||
|
|
||||||
import munit._
|
import munit._
|
||||||
|
|
||||||
class PdfboxExtractTest extends FunSuite {
|
class PdfboxExtractTest extends FunSuite {
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
package docspell.extract.pdfbox
|
package docspell.extract.pdfbox
|
||||||
|
|
||||||
import cats.effect._
|
|
||||||
import docspell.files.{ExampleFiles, TestFiles}
|
|
||||||
import munit._
|
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
|
||||||
|
import cats.effect._
|
||||||
import fs2.Stream
|
import fs2.Stream
|
||||||
|
|
||||||
|
import docspell.files.{ExampleFiles, TestFiles}
|
||||||
|
|
||||||
|
import munit._
|
||||||
|
|
||||||
class PdfboxPreviewTest extends FunSuite {
|
class PdfboxPreviewTest extends FunSuite {
|
||||||
val blocker = TestFiles.blocker
|
val blocker = TestFiles.blocker
|
||||||
implicit val CS = TestFiles.CS
|
implicit val CS = TestFiles.CS
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package docspell.extract.poi
|
package docspell.extract.poi
|
||||||
|
|
||||||
import cats.effect._
|
import cats.effect._
|
||||||
|
|
||||||
import docspell.common.MimeTypeHint
|
import docspell.common.MimeTypeHint
|
||||||
import docspell.files.{ExampleFiles, TestFiles}
|
import docspell.files.{ExampleFiles, TestFiles}
|
||||||
|
|
||||||
import munit._
|
import munit._
|
||||||
|
|
||||||
class PoiExtractTest extends FunSuite {
|
class PoiExtractTest extends FunSuite {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package docspell.extract.rtf
|
package docspell.extract.rtf
|
||||||
|
|
||||||
import docspell.files.ExampleFiles
|
import docspell.files.ExampleFiles
|
||||||
|
|
||||||
import munit._
|
import munit._
|
||||||
|
|
||||||
class RtfExtractTest extends FunSuite {
|
class RtfExtractTest extends FunSuite {
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
package docspell.files
|
package docspell.files
|
||||||
|
|
||||||
import cats.implicits._
|
|
||||||
import cats.effect.{Blocker, IO}
|
|
||||||
import munit._
|
|
||||||
|
|
||||||
import scala.concurrent.ExecutionContext
|
import scala.concurrent.ExecutionContext
|
||||||
import scala.util.Using
|
import scala.util.Using
|
||||||
|
|
||||||
|
import cats.effect.{Blocker, IO}
|
||||||
|
import cats.implicits._
|
||||||
|
|
||||||
|
import munit._
|
||||||
|
|
||||||
class ImageSizeTest extends FunSuite {
|
class ImageSizeTest extends FunSuite {
|
||||||
val blocker = Blocker.liftExecutionContext(ExecutionContext.global)
|
val blocker = Blocker.liftExecutionContext(ExecutionContext.global)
|
||||||
implicit val CS = IO.contextShift(ExecutionContext.global)
|
implicit val CS = IO.contextShift(ExecutionContext.global)
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
package docspell.files
|
package docspell.files
|
||||||
|
|
||||||
import cats.effect.{Blocker, ExitCode, IO, IOApp}
|
|
||||||
import docspell.common.MimeTypeHint
|
|
||||||
|
|
||||||
import scala.concurrent.ExecutionContext
|
import scala.concurrent.ExecutionContext
|
||||||
|
|
||||||
|
import cats.effect._
|
||||||
|
|
||||||
|
import docspell.common.MimeTypeHint
|
||||||
|
|
||||||
object Playing extends IOApp {
|
object Playing extends IOApp {
|
||||||
val blocker = Blocker.liftExecutionContext(ExecutionContext.global)
|
val blocker = Blocker.liftExecutionContext(ExecutionContext.global)
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package docspell.files
|
package docspell.files
|
||||||
|
|
||||||
|
import scala.concurrent.ExecutionContext
|
||||||
|
|
||||||
import cats.effect.{Blocker, IO}
|
import cats.effect.{Blocker, IO}
|
||||||
import fs2.Stream
|
import fs2.Stream
|
||||||
|
|
||||||
import scala.concurrent.ExecutionContext
|
|
||||||
|
|
||||||
object TestFiles {
|
object TestFiles {
|
||||||
val blocker = Blocker.liftExecutionContext(ExecutionContext.global)
|
val blocker = Blocker.liftExecutionContext(ExecutionContext.global)
|
||||||
implicit val CS = IO.contextShift(ExecutionContext.global)
|
implicit val CS = IO.contextShift(ExecutionContext.global)
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
package docspell.files
|
package docspell.files
|
||||||
|
|
||||||
import munit._
|
import scala.concurrent.ExecutionContext
|
||||||
|
|
||||||
import cats.effect._
|
import cats.effect._
|
||||||
import cats.implicits._
|
import cats.implicits._
|
||||||
import scala.concurrent.ExecutionContext
|
|
||||||
import docspell.common.Glob
|
import docspell.common.Glob
|
||||||
|
|
||||||
|
import munit._
|
||||||
|
|
||||||
class ZipTest extends FunSuite {
|
class ZipTest extends FunSuite {
|
||||||
|
|
||||||
val blocker = Blocker.liftExecutionContext(ExecutionContext.global)
|
val blocker = Blocker.liftExecutionContext(ExecutionContext.global)
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
package docspell.joex.analysis
|
package docspell.joex.analysis
|
||||||
|
|
||||||
import munit._
|
|
||||||
import NerFile.Pattern
|
|
||||||
import java.{util => ju}
|
import java.{util => ju}
|
||||||
|
|
||||||
|
import docspell.joex.analysis.NerFile.Pattern
|
||||||
|
|
||||||
|
import munit._
|
||||||
|
|
||||||
class NerFileTest extends FunSuite {
|
class NerFileTest extends FunSuite {
|
||||||
|
|
||||||
test("create valid case insensitive patterns") {
|
test("create valid case insensitive patterns") {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package docspell.joex.scheduler
|
package docspell.joex.scheduler
|
||||||
|
|
||||||
import docspell.common.Priority
|
import docspell.common.Priority
|
||||||
|
|
||||||
import munit._
|
import munit._
|
||||||
|
|
||||||
class CountingSchemeSpec extends FunSuite {
|
class CountingSchemeSpec extends FunSuite {
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
package docspell.query
|
package docspell.query
|
||||||
|
|
||||||
import cats.implicits._
|
import cats.implicits._
|
||||||
import munit._
|
|
||||||
import docspell.query.FulltextExtract.Result
|
import docspell.query.FulltextExtract.Result
|
||||||
|
|
||||||
|
import munit._
|
||||||
|
|
||||||
class FulltextExtractTest extends FunSuite {
|
class FulltextExtractTest extends FunSuite {
|
||||||
|
|
||||||
def findFts(q: String): Result = {
|
def findFts(q: String): Result = {
|
||||||
|
@ -2,6 +2,7 @@ package docspell.query.internal
|
|||||||
|
|
||||||
import docspell.query.ItemQuery.Attr
|
import docspell.query.ItemQuery.Attr
|
||||||
import docspell.query.internal.AttrParser
|
import docspell.query.internal.AttrParser
|
||||||
|
|
||||||
import munit._
|
import munit._
|
||||||
|
|
||||||
class AttrParserTest extends FunSuite {
|
class AttrParserTest extends FunSuite {
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
package docspell.query.internal
|
package docspell.query.internal
|
||||||
|
|
||||||
import munit._
|
|
||||||
import cats.data.{NonEmptyList => Nel}
|
import cats.data.{NonEmptyList => Nel}
|
||||||
|
|
||||||
import docspell.query.internal.BasicParser
|
import docspell.query.internal.BasicParser
|
||||||
|
|
||||||
|
import munit._
|
||||||
|
|
||||||
class BasicParserTest extends FunSuite {
|
class BasicParserTest extends FunSuite {
|
||||||
test("single string values") {
|
test("single string values") {
|
||||||
val p = BasicParser.singleString
|
val p = BasicParser.singleString
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
package docspell.query.internal
|
package docspell.query.internal
|
||||||
|
|
||||||
import munit._
|
|
||||||
import docspell.query.Date
|
|
||||||
import java.time.Period
|
import java.time.Period
|
||||||
|
|
||||||
|
import docspell.query.Date
|
||||||
|
|
||||||
|
import munit._
|
||||||
|
|
||||||
class DateParserTest extends FunSuite with ValueHelper {
|
class DateParserTest extends FunSuite with ValueHelper {
|
||||||
|
|
||||||
test("local date string") {
|
test("local date string") {
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
package docspell.query.internal
|
package docspell.query.internal
|
||||||
|
|
||||||
import docspell.query.ItemQuery._
|
|
||||||
import munit._
|
|
||||||
import cats.data.{NonEmptyList => Nel}
|
import cats.data.{NonEmptyList => Nel}
|
||||||
|
|
||||||
|
import docspell.query.ItemQuery._
|
||||||
|
|
||||||
|
import munit._
|
||||||
|
|
||||||
class ExprParserTest extends FunSuite with ValueHelper {
|
class ExprParserTest extends FunSuite with ValueHelper {
|
||||||
|
|
||||||
test("simple expr") {
|
test("simple expr") {
|
||||||
|
@ -2,9 +2,10 @@ package docspell.query.internal
|
|||||||
|
|
||||||
import cats.implicits._
|
import cats.implicits._
|
||||||
|
|
||||||
import munit._
|
|
||||||
import docspell.query.ItemQueryParser
|
|
||||||
import docspell.query.ItemQuery
|
import docspell.query.ItemQuery
|
||||||
|
import docspell.query.ItemQueryParser
|
||||||
|
|
||||||
|
import munit._
|
||||||
|
|
||||||
class ItemQueryParserTest extends FunSuite {
|
class ItemQueryParserTest extends FunSuite {
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package docspell.query.internal
|
package docspell.query.internal
|
||||||
|
|
||||||
import munit._
|
|
||||||
//import cats.parse.{Parser => P}
|
|
||||||
import docspell.query.ItemQuery.Expr
|
import docspell.query.ItemQuery.Expr
|
||||||
|
|
||||||
|
import munit._
|
||||||
|
|
||||||
class MacroParserTest extends FunSuite {
|
class MacroParserTest extends FunSuite {
|
||||||
|
|
||||||
test("recognize names shortcut") {
|
test("recognize names shortcut") {
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
package docspell.query.internal
|
package docspell.query.internal
|
||||||
|
|
||||||
import munit._
|
|
||||||
import docspell.query.ItemQuery.{Operator, TagOperator}
|
import docspell.query.ItemQuery.{Operator, TagOperator}
|
||||||
import docspell.query.internal.OperatorParser
|
import docspell.query.internal.OperatorParser
|
||||||
|
|
||||||
|
import munit._
|
||||||
|
|
||||||
class OperatorParserTest extends FunSuite {
|
class OperatorParserTest extends FunSuite {
|
||||||
test("operator values") {
|
test("operator values") {
|
||||||
val p = OperatorParser.op
|
val p = OperatorParser.op
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
package docspell.query.internal
|
package docspell.query.internal
|
||||||
|
|
||||||
import cats.data.{NonEmptyList => Nel}
|
|
||||||
import docspell.query.ItemQuery._
|
|
||||||
import munit._
|
|
||||||
import docspell.query.Date
|
|
||||||
import java.time.Period
|
import java.time.Period
|
||||||
|
|
||||||
|
import cats.data.{NonEmptyList => Nel}
|
||||||
|
|
||||||
|
import docspell.query.Date
|
||||||
|
import docspell.query.ItemQuery._
|
||||||
|
|
||||||
|
import munit._
|
||||||
|
|
||||||
class SimpleExprParserTest extends FunSuite with ValueHelper {
|
class SimpleExprParserTest extends FunSuite with ValueHelper {
|
||||||
|
|
||||||
test("string expr") {
|
test("string expr") {
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
package docspell.query.internal
|
package docspell.query.internal
|
||||||
|
|
||||||
|
import java.time.Period
|
||||||
|
|
||||||
import docspell.query.Date
|
import docspell.query.Date
|
||||||
import docspell.query.ItemQuery._
|
import docspell.query.ItemQuery._
|
||||||
import java.time.Period
|
|
||||||
|
|
||||||
trait ValueHelper {
|
trait ValueHelper {
|
||||||
|
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
package docspell.store
|
package docspell.store
|
||||||
|
|
||||||
|
import scala.concurrent.ExecutionContext
|
||||||
|
|
||||||
import cats.effect._
|
import cats.effect._
|
||||||
|
|
||||||
import docspell.common.LenientUri
|
import docspell.common.LenientUri
|
||||||
import docspell.store.impl.StoreImpl
|
import docspell.store.impl.StoreImpl
|
||||||
|
|
||||||
import doobie._
|
import doobie._
|
||||||
import org.h2.jdbcx.JdbcConnectionPool
|
import org.h2.jdbcx.JdbcConnectionPool
|
||||||
|
|
||||||
import scala.concurrent.ExecutionContext
|
|
||||||
|
|
||||||
trait StoreFixture {
|
trait StoreFixture {
|
||||||
def withStore(db: String)(code: Store[IO] => IO[Unit]): Unit = {
|
def withStore(db: String)(code: Store[IO] => IO[Unit]): Unit = {
|
||||||
//StoreFixture.store(StoreFixture.memoryDB(db)).use(code).unsafeRunSync()
|
//StoreFixture.store(StoreFixture.memoryDB(db)).use(code).unsafeRunSync()
|
||||||
|
@ -2,13 +2,14 @@ package docspell.store.generator
|
|||||||
|
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
|
|
||||||
import docspell.store.records._
|
|
||||||
import munit._
|
|
||||||
import docspell.common._
|
import docspell.common._
|
||||||
import docspell.query.ItemQueryParser
|
import docspell.query.ItemQueryParser
|
||||||
import docspell.store.queries.AttachCountTable
|
|
||||||
import docspell.store.qb.DSL._
|
import docspell.store.qb.DSL._
|
||||||
import docspell.store.qb.generator.{ItemQueryGenerator, Tables}
|
import docspell.store.qb.generator.{ItemQueryGenerator, Tables}
|
||||||
|
import docspell.store.queries.AttachCountTable
|
||||||
|
import docspell.store.records._
|
||||||
|
|
||||||
|
import munit._
|
||||||
|
|
||||||
class ItemQueryGeneratorTest extends FunSuite {
|
class ItemQueryGeneratorTest extends FunSuite {
|
||||||
import docspell.store.impl.DoobieMeta._
|
import docspell.store.impl.DoobieMeta._
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
package docspell.store.qb
|
package docspell.store.qb
|
||||||
|
|
||||||
import munit._
|
|
||||||
import docspell.store.qb.model._
|
|
||||||
import docspell.store.qb.DSL._
|
import docspell.store.qb.DSL._
|
||||||
|
import docspell.store.qb.model._
|
||||||
|
|
||||||
|
import munit._
|
||||||
|
|
||||||
class QueryBuilderTest extends FunSuite {
|
class QueryBuilderTest extends FunSuite {
|
||||||
|
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
package docspell.store.qb.impl
|
package docspell.store.qb.impl
|
||||||
|
|
||||||
import munit._
|
|
||||||
import docspell.store.qb._
|
|
||||||
import docspell.store.qb.DSL._
|
import docspell.store.qb.DSL._
|
||||||
|
import docspell.store.qb._
|
||||||
import docspell.store.qb.model.{CourseRecord, PersonRecord}
|
import docspell.store.qb.model.{CourseRecord, PersonRecord}
|
||||||
|
|
||||||
|
import munit._
|
||||||
|
|
||||||
class ConditionBuilderTest extends FunSuite {
|
class ConditionBuilderTest extends FunSuite {
|
||||||
|
|
||||||
val c = CourseRecord.as("c")
|
val c = CourseRecord.as("c")
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
package docspell.store.qb.impl
|
package docspell.store.qb.impl
|
||||||
|
|
||||||
import munit._
|
|
||||||
import docspell.store.qb._
|
|
||||||
import docspell.store.qb.DSL._
|
import docspell.store.qb.DSL._
|
||||||
|
import docspell.store.qb._
|
||||||
import docspell.store.qb.model.{CourseRecord, PersonRecord}
|
import docspell.store.qb.model.{CourseRecord, PersonRecord}
|
||||||
|
|
||||||
|
import munit._
|
||||||
|
|
||||||
class DSLTest extends FunSuite {
|
class DSLTest extends FunSuite {
|
||||||
|
|
||||||
val course = CourseRecord.as("c")
|
val course = CourseRecord.as("c")
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
package docspell.store.qb.impl
|
package docspell.store.qb.impl
|
||||||
|
|
||||||
import munit._
|
import docspell.store.qb.DSL._
|
||||||
import docspell.store.qb._
|
import docspell.store.qb._
|
||||||
import docspell.store.qb.model._
|
import docspell.store.qb.model._
|
||||||
import docspell.store.qb.DSL._
|
|
||||||
|
import munit._
|
||||||
|
|
||||||
class SelectBuilderTest extends FunSuite {
|
class SelectBuilderTest extends FunSuite {
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package docspell.store.qb.model
|
package docspell.store.qb.model
|
||||||
|
|
||||||
import cats.data.NonEmptyList
|
import cats.data.NonEmptyList
|
||||||
|
|
||||||
import docspell.store.qb._
|
import docspell.store.qb._
|
||||||
|
|
||||||
case class CourseRecord(
|
case class CourseRecord(
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
package docspell.store.qb.model
|
package docspell.store.qb.model
|
||||||
|
|
||||||
import cats.data.NonEmptyList
|
import cats.data.NonEmptyList
|
||||||
import docspell.store.qb._
|
|
||||||
import docspell.common._
|
import docspell.common._
|
||||||
|
import docspell.store.qb._
|
||||||
|
|
||||||
case class PersonRecord(id: Long, name: String, created: Timestamp)
|
case class PersonRecord(id: Long, name: String, created: Timestamp)
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ module App.Data exposing
|
|||||||
( Model
|
( Model
|
||||||
, Msg(..)
|
, Msg(..)
|
||||||
, defaultPage
|
, defaultPage
|
||||||
|
, getUiLanguage
|
||||||
, init
|
, init
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -13,6 +14,7 @@ import Data.Flags exposing (Flags)
|
|||||||
import Data.UiSettings exposing (UiSettings)
|
import Data.UiSettings exposing (UiSettings)
|
||||||
import Data.UiTheme exposing (UiTheme)
|
import Data.UiTheme exposing (UiTheme)
|
||||||
import Http
|
import Http
|
||||||
|
import Messages.UiLanguage exposing (UiLanguage)
|
||||||
import Page exposing (Page(..))
|
import Page exposing (Page(..))
|
||||||
import Page.CollectiveSettings.Data
|
import Page.CollectiveSettings.Data
|
||||||
import Page.Home.Data
|
import Page.Home.Data
|
||||||
@ -48,6 +50,8 @@ type alias Model =
|
|||||||
, uiSettings : UiSettings
|
, uiSettings : UiSettings
|
||||||
, sidebarVisible : Bool
|
, sidebarVisible : Bool
|
||||||
, anonymousTheme : UiTheme
|
, anonymousTheme : UiTheme
|
||||||
|
, anonymousUiLang : UiLanguage
|
||||||
|
, langMenuOpen : Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -97,6 +101,8 @@ init key url flags_ settings =
|
|||||||
, uiSettings = settings
|
, uiSettings = settings
|
||||||
, sidebarVisible = settings.sideMenuVisible
|
, sidebarVisible = settings.sideMenuVisible
|
||||||
, anonymousTheme = Data.UiTheme.Light
|
, anonymousTheme = Data.UiTheme.Light
|
||||||
|
, anonymousUiLang = Messages.UiLanguage.English
|
||||||
|
, langMenuOpen = False
|
||||||
}
|
}
|
||||||
, Cmd.batch
|
, Cmd.batch
|
||||||
[ Cmd.map UserSettingsMsg uc
|
[ Cmd.map UserSettingsMsg uc
|
||||||
@ -152,8 +158,20 @@ type Msg
|
|||||||
| GetUiSettings UiSettings
|
| GetUiSettings UiSettings
|
||||||
| ToggleSidebar
|
| ToggleSidebar
|
||||||
| ToggleDarkMode
|
| ToggleDarkMode
|
||||||
|
| ToggleLangMenu
|
||||||
|
| SetLanguage UiLanguage
|
||||||
|
|
||||||
|
|
||||||
defaultPage : Flags -> Page
|
defaultPage : Flags -> Page
|
||||||
defaultPage flags =
|
defaultPage _ =
|
||||||
HomePage
|
HomePage
|
||||||
|
|
||||||
|
|
||||||
|
getUiLanguage : Model -> UiLanguage
|
||||||
|
getUiLanguage model =
|
||||||
|
case model.flags.account of
|
||||||
|
Just _ ->
|
||||||
|
model.uiSettings.uiLang
|
||||||
|
|
||||||
|
Nothing ->
|
||||||
|
model.anonymousUiLang
|
||||||
|
@ -84,6 +84,15 @@ updateWithSub msg model =
|
|||||||
, Sub.none
|
, Sub.none
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ToggleLangMenu ->
|
||||||
|
( { model | langMenuOpen = not model.langMenuOpen }
|
||||||
|
, Cmd.none
|
||||||
|
, Sub.none
|
||||||
|
)
|
||||||
|
|
||||||
|
SetLanguage lang ->
|
||||||
|
( { model | anonymousUiLang = lang, langMenuOpen = False }, Cmd.none, Sub.none )
|
||||||
|
|
||||||
HomeMsg lm ->
|
HomeMsg lm ->
|
||||||
updateHome lm model
|
updateHome lm model
|
||||||
|
|
||||||
|
@ -7,6 +7,9 @@ import Data.Flags
|
|||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onClick)
|
import Html.Events exposing (onClick)
|
||||||
|
import Messages exposing (Messages)
|
||||||
|
import Messages.App exposing (Texts)
|
||||||
|
import Messages.UiLanguage
|
||||||
import Page exposing (Page(..))
|
import Page exposing (Page(..))
|
||||||
import Page.CollectiveSettings.View2 as CollectiveSettings
|
import Page.CollectiveSettings.View2 as CollectiveSettings
|
||||||
import Page.Home.Data
|
import Page.Home.Data
|
||||||
@ -41,6 +44,10 @@ topNavbar model =
|
|||||||
|
|
||||||
topNavUser : AuthResult -> Model -> Html Msg
|
topNavUser : AuthResult -> Model -> Html Msg
|
||||||
topNavUser auth model =
|
topNavUser auth model =
|
||||||
|
let
|
||||||
|
texts =
|
||||||
|
Messages.get <| App.Data.getUiLanguage model
|
||||||
|
in
|
||||||
nav
|
nav
|
||||||
[ id "top-nav"
|
[ id "top-nav"
|
||||||
, class styleTopNav
|
, class styleTopNav
|
||||||
@ -56,8 +63,8 @@ topNavUser auth model =
|
|||||||
}
|
}
|
||||||
, headerNavItem model
|
, headerNavItem model
|
||||||
, div [ class "flex flex-grow justify-end" ]
|
, div [ class "flex flex-grow justify-end" ]
|
||||||
[ userMenu auth model
|
[ userMenu texts.app auth model
|
||||||
, dataMenu auth model
|
, dataMenu texts.app auth model
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -70,7 +77,8 @@ topNavAnon model =
|
|||||||
]
|
]
|
||||||
[ headerNavItem model
|
[ headerNavItem model
|
||||||
, div [ class "flex flex-grow justify-end" ]
|
, div [ class "flex flex-grow justify-end" ]
|
||||||
[ a
|
[ langMenu model
|
||||||
|
, a
|
||||||
[ href "#"
|
[ href "#"
|
||||||
, onClick ToggleDarkMode
|
, onClick ToggleDarkMode
|
||||||
, class dropdownLink
|
, class dropdownLink
|
||||||
@ -100,40 +108,44 @@ headerNavItem model =
|
|||||||
|
|
||||||
mainContent : Model -> Html Msg
|
mainContent : Model -> Html Msg
|
||||||
mainContent model =
|
mainContent model =
|
||||||
|
let
|
||||||
|
texts =
|
||||||
|
Messages.get <| App.Data.getUiLanguage model
|
||||||
|
in
|
||||||
div
|
div
|
||||||
[ id "main"
|
[ id "main"
|
||||||
, class styleMain
|
, class styleMain
|
||||||
]
|
]
|
||||||
(case model.page of
|
(case model.page of
|
||||||
HomePage ->
|
HomePage ->
|
||||||
viewHome model
|
viewHome texts model
|
||||||
|
|
||||||
CollectiveSettingPage ->
|
CollectiveSettingPage ->
|
||||||
viewCollectiveSettings model
|
viewCollectiveSettings texts model
|
||||||
|
|
||||||
LoginPage _ ->
|
LoginPage _ ->
|
||||||
viewLogin model
|
viewLogin texts model
|
||||||
|
|
||||||
ManageDataPage ->
|
ManageDataPage ->
|
||||||
viewManageData model
|
viewManageData texts model
|
||||||
|
|
||||||
UserSettingPage ->
|
UserSettingPage ->
|
||||||
viewUserSettings model
|
viewUserSettings texts model
|
||||||
|
|
||||||
QueuePage ->
|
QueuePage ->
|
||||||
viewQueue model
|
viewQueue texts model
|
||||||
|
|
||||||
RegisterPage ->
|
RegisterPage ->
|
||||||
viewRegister model
|
viewRegister texts model
|
||||||
|
|
||||||
UploadPage mid ->
|
UploadPage mid ->
|
||||||
viewUpload mid model
|
viewUpload texts mid model
|
||||||
|
|
||||||
NewInvitePage ->
|
NewInvitePage ->
|
||||||
viewNewInvite model
|
viewNewInvite texts model
|
||||||
|
|
||||||
ItemDetailPage id ->
|
ItemDetailPage id ->
|
||||||
viewItemDetail id model
|
viewItemDetail texts id model
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -151,8 +163,47 @@ styleMain =
|
|||||||
"mt-12 flex md:flex-row flex-col w-full h-screen-12 overflow-y-hidden bg-white dark:bg-bluegray-800 text-gray-800 dark:text-bluegray-300 antialiased"
|
"mt-12 flex md:flex-row flex-col w-full h-screen-12 overflow-y-hidden bg-white dark:bg-bluegray-800 text-gray-800 dark:text-bluegray-300 antialiased"
|
||||||
|
|
||||||
|
|
||||||
dataMenu : AuthResult -> Model -> Html Msg
|
langMenu : Model -> Html Msg
|
||||||
dataMenu _ model =
|
langMenu model =
|
||||||
|
let
|
||||||
|
texts =
|
||||||
|
Messages.get <| App.Data.getUiLanguage model
|
||||||
|
|
||||||
|
langItem lang =
|
||||||
|
let
|
||||||
|
langMsg =
|
||||||
|
Messages.get lang
|
||||||
|
in
|
||||||
|
a
|
||||||
|
[ classList
|
||||||
|
[ ( dropdownItem, True )
|
||||||
|
, ( "bg-gray-200 dark:bg-bluegray-700", lang == texts.lang )
|
||||||
|
]
|
||||||
|
, onClick (SetLanguage lang)
|
||||||
|
, href "#"
|
||||||
|
]
|
||||||
|
[ i [ langMsg |> .flagIcon |> class ] []
|
||||||
|
, span [ class "ml-2" ] [ text langMsg.label ]
|
||||||
|
]
|
||||||
|
in
|
||||||
|
div [ class "relative" ]
|
||||||
|
[ a
|
||||||
|
[ class dropdownLink
|
||||||
|
, onClick ToggleLangMenu
|
||||||
|
, href "#"
|
||||||
|
]
|
||||||
|
[ i [ class texts.flagIcon ] []
|
||||||
|
]
|
||||||
|
, div
|
||||||
|
[ class dropdownMenu
|
||||||
|
, classList [ ( "hidden", not model.langMenuOpen ) ]
|
||||||
|
]
|
||||||
|
(List.map langItem Messages.UiLanguage.all)
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
dataMenu : Texts -> AuthResult -> Model -> Html Msg
|
||||||
|
dataMenu texts _ model =
|
||||||
div [ class "relative" ]
|
div [ class "relative" ]
|
||||||
[ a
|
[ a
|
||||||
[ class dropdownLink
|
[ class dropdownLink
|
||||||
@ -174,7 +225,7 @@ dataMenu _ model =
|
|||||||
]
|
]
|
||||||
[]
|
[]
|
||||||
, div [ class "inline-block ml-2" ]
|
, div [ class "inline-block ml-2" ]
|
||||||
[ text "Items"
|
[ text texts.items
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div [ class "py-1" ] [ hr [ class S.border ] [] ]
|
, div [ class "py-1" ] [ hr [ class S.border ] [] ]
|
||||||
@ -183,7 +234,7 @@ dataMenu _ model =
|
|||||||
[]
|
[]
|
||||||
[ i [ class "fa fa-cubes w-6" ] []
|
[ i [ class "fa fa-cubes w-6" ] []
|
||||||
, span [ class "ml-1" ]
|
, span [ class "ml-1" ]
|
||||||
[ text "Manage Data"
|
[ text texts.manageData
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div [ class "divider" ] []
|
, div [ class "divider" ] []
|
||||||
@ -192,7 +243,7 @@ dataMenu _ model =
|
|||||||
[]
|
[]
|
||||||
[ i [ class "fa fa-upload w-6" ] []
|
[ i [ class "fa fa-upload w-6" ] []
|
||||||
, span [ class "ml-1" ]
|
, span [ class "ml-1" ]
|
||||||
[ text "Upload files"
|
[ text texts.uploadFiles
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, dataPageLink model
|
, dataPageLink model
|
||||||
@ -200,7 +251,7 @@ dataMenu _ model =
|
|||||||
[]
|
[]
|
||||||
[ i [ class "fa fa-tachometer-alt w-6" ] []
|
[ i [ class "fa fa-tachometer-alt w-6" ] []
|
||||||
, span [ class "ml-1" ]
|
, span [ class "ml-1" ]
|
||||||
[ text "Processing Queue"
|
[ text texts.processingQueue
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div
|
, div
|
||||||
@ -215,7 +266,7 @@ dataMenu _ model =
|
|||||||
[ ( "hidden", model.flags.config.signupMode /= "invite" ) ]
|
[ ( "hidden", model.flags.config.signupMode /= "invite" ) ]
|
||||||
[ i [ class "fa fa-key w-6" ] []
|
[ i [ class "fa fa-key w-6" ] []
|
||||||
, span [ class "ml-1" ]
|
, span [ class "ml-1" ]
|
||||||
[ text "New Invites"
|
[ text texts.newInvites
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div [ class "py-1" ]
|
, div [ class "py-1" ]
|
||||||
@ -229,7 +280,7 @@ dataMenu _ model =
|
|||||||
, title "Opens https://docspell.org/docs"
|
, title "Opens https://docspell.org/docs"
|
||||||
]
|
]
|
||||||
[ i [ class "fa fa-question-circle w-6" ] []
|
[ i [ class "fa fa-question-circle w-6" ] []
|
||||||
, span [ class "ml-1" ] [ text "Help" ]
|
, span [ class "ml-1" ] [ text texts.help ]
|
||||||
, span [ class "float-right" ]
|
, span [ class "float-right" ]
|
||||||
[ i [ class "fa fa-external-link-alt w-6" ] []
|
[ i [ class "fa fa-external-link-alt w-6" ] []
|
||||||
]
|
]
|
||||||
@ -238,8 +289,8 @@ dataMenu _ model =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
userMenu : AuthResult -> Model -> Html Msg
|
userMenu : Texts -> AuthResult -> Model -> Html Msg
|
||||||
userMenu acc model =
|
userMenu texts acc model =
|
||||||
div [ class "relative" ]
|
div [ class "relative" ]
|
||||||
[ a
|
[ a
|
||||||
[ class dropdownLink
|
[ class dropdownLink
|
||||||
@ -263,14 +314,14 @@ userMenu acc model =
|
|||||||
CollectiveSettingPage
|
CollectiveSettingPage
|
||||||
[ i [ class "fa fa-users w-6" ] []
|
[ i [ class "fa fa-users w-6" ] []
|
||||||
, span [ class "ml-1" ]
|
, span [ class "ml-1" ]
|
||||||
[ text "Collective Profile"
|
[ text texts.collectiveProfile
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, userPageLink model
|
, userPageLink model
|
||||||
UserSettingPage
|
UserSettingPage
|
||||||
[ i [ class "fa fa-user-circle w-6" ] []
|
[ i [ class "fa fa-user-circle w-6" ] []
|
||||||
, span [ class "ml-1" ]
|
, span [ class "ml-1" ]
|
||||||
[ text "User Profile"
|
[ text texts.userProfile
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, a
|
, a
|
||||||
@ -280,7 +331,7 @@ userMenu acc model =
|
|||||||
]
|
]
|
||||||
[ i [ class "fa fa-adjust w-6" ] []
|
[ i [ class "fa fa-adjust w-6" ] []
|
||||||
, span [ class "ml-1" ]
|
, span [ class "ml-1" ]
|
||||||
[ text "Light/Dark"
|
[ text texts.lightDark
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div [ class "py-1" ] [ hr [ class S.border ] [] ]
|
, div [ class "py-1" ] [ hr [ class S.border ] [] ]
|
||||||
@ -291,7 +342,7 @@ userMenu acc model =
|
|||||||
]
|
]
|
||||||
[ i [ class "fa fa-sign-out-alt w-6" ] []
|
[ i [ class "fa fa-sign-out-alt w-6" ] []
|
||||||
, span [ class "ml-1" ]
|
, span [ class "ml-1" ]
|
||||||
[ text "Logout"
|
[ text texts.logout
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -346,85 +397,121 @@ dropdownMenu =
|
|||||||
" absolute right-0 bg-white dark:bg-bluegray-800 border dark:border-bluegray-700 dark:text-bluegray-300 shadow-lg opacity-1 transition duration-200 min-w-max "
|
" absolute right-0 bg-white dark:bg-bluegray-800 border dark:border-bluegray-700 dark:text-bluegray-300 shadow-lg opacity-1 transition duration-200 min-w-max "
|
||||||
|
|
||||||
|
|
||||||
viewHome : Model -> List (Html Msg)
|
viewHome : Messages -> Model -> List (Html Msg)
|
||||||
viewHome model =
|
viewHome texts model =
|
||||||
[ Html.map HomeMsg (Home.viewSidebar model.sidebarVisible model.flags model.uiSettings model.homeModel)
|
[ Html.map HomeMsg
|
||||||
, Html.map HomeMsg (Home.viewContent model.flags model.uiSettings model.homeModel)
|
(Home.viewSidebar texts.home
|
||||||
|
model.sidebarVisible
|
||||||
|
model.flags
|
||||||
|
model.uiSettings
|
||||||
|
model.homeModel
|
||||||
|
)
|
||||||
|
, Html.map HomeMsg
|
||||||
|
(Home.viewContent texts.home
|
||||||
|
model.flags
|
||||||
|
model.uiSettings
|
||||||
|
model.homeModel
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewCollectiveSettings : Model -> List (Html Msg)
|
viewCollectiveSettings : Messages -> Model -> List (Html Msg)
|
||||||
viewCollectiveSettings model =
|
viewCollectiveSettings texts model =
|
||||||
[ Html.map CollSettingsMsg
|
[ Html.map CollSettingsMsg
|
||||||
(CollectiveSettings.viewSidebar model.sidebarVisible
|
(CollectiveSettings.viewSidebar texts.collectiveSettings
|
||||||
|
model.sidebarVisible
|
||||||
model.flags
|
model.flags
|
||||||
model.uiSettings
|
model.uiSettings
|
||||||
model.collSettingsModel
|
model.collSettingsModel
|
||||||
)
|
)
|
||||||
, Html.map CollSettingsMsg
|
, Html.map CollSettingsMsg
|
||||||
(CollectiveSettings.viewContent model.flags
|
(CollectiveSettings.viewContent texts.collectiveSettings
|
||||||
|
model.flags
|
||||||
model.uiSettings
|
model.uiSettings
|
||||||
model.collSettingsModel
|
model.collSettingsModel
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewLogin : Model -> List (Html Msg)
|
viewLogin : Messages -> Model -> List (Html Msg)
|
||||||
viewLogin model =
|
viewLogin texts model =
|
||||||
[ Html.map LoginMsg
|
[ Html.map LoginMsg
|
||||||
(Login.viewSidebar model.sidebarVisible model.flags model.uiSettings model.loginModel)
|
(Login.viewSidebar model.sidebarVisible model.flags model.uiSettings model.loginModel)
|
||||||
, Html.map LoginMsg
|
, Html.map LoginMsg
|
||||||
(Login.viewContent model.flags model.version model.uiSettings model.loginModel)
|
(Login.viewContent texts.login model.flags model.version model.uiSettings model.loginModel)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewManageData : Model -> List (Html Msg)
|
viewManageData : Messages -> Model -> List (Html Msg)
|
||||||
viewManageData model =
|
viewManageData texts model =
|
||||||
[ Html.map ManageDataMsg
|
[ Html.map ManageDataMsg
|
||||||
(ManageData.viewSidebar model.sidebarVisible model.flags model.uiSettings model.manageDataModel)
|
(ManageData.viewSidebar texts.manageData
|
||||||
|
model.sidebarVisible
|
||||||
|
model.flags
|
||||||
|
model.uiSettings
|
||||||
|
model.manageDataModel
|
||||||
|
)
|
||||||
, Html.map ManageDataMsg
|
, Html.map ManageDataMsg
|
||||||
(ManageData.viewContent model.flags model.uiSettings model.manageDataModel)
|
(ManageData.viewContent texts.manageData
|
||||||
|
model.flags
|
||||||
|
model.uiSettings
|
||||||
|
model.manageDataModel
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewUserSettings : Model -> List (Html Msg)
|
viewUserSettings : Messages -> Model -> List (Html Msg)
|
||||||
viewUserSettings model =
|
viewUserSettings texts model =
|
||||||
[ Html.map UserSettingsMsg
|
[ Html.map UserSettingsMsg
|
||||||
(UserSettings.viewSidebar model.sidebarVisible model.flags model.uiSettings model.userSettingsModel)
|
(UserSettings.viewSidebar texts.userSettings
|
||||||
|
model.sidebarVisible
|
||||||
|
model.flags
|
||||||
|
model.uiSettings
|
||||||
|
model.userSettingsModel
|
||||||
|
)
|
||||||
, Html.map UserSettingsMsg
|
, Html.map UserSettingsMsg
|
||||||
(UserSettings.viewContent model.flags model.uiSettings model.userSettingsModel)
|
(UserSettings.viewContent texts.userSettings
|
||||||
|
model.flags
|
||||||
|
model.uiSettings
|
||||||
|
model.userSettingsModel
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewQueue : Model -> List (Html Msg)
|
viewQueue : Messages -> Model -> List (Html Msg)
|
||||||
viewQueue model =
|
viewQueue texts model =
|
||||||
[ Html.map QueueMsg
|
[ Html.map QueueMsg
|
||||||
(Queue.viewSidebar model.sidebarVisible model.flags model.uiSettings model.queueModel)
|
(Queue.viewSidebar texts.queue
|
||||||
|
model.sidebarVisible
|
||||||
|
model.flags
|
||||||
|
model.uiSettings
|
||||||
|
model.queueModel
|
||||||
|
)
|
||||||
, Html.map QueueMsg
|
, Html.map QueueMsg
|
||||||
(Queue.viewContent model.flags model.uiSettings model.queueModel)
|
(Queue.viewContent texts.queue model.flags model.uiSettings model.queueModel)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewRegister : Model -> List (Html Msg)
|
viewRegister : Messages -> Model -> List (Html Msg)
|
||||||
viewRegister model =
|
viewRegister texts model =
|
||||||
[ Html.map RegisterMsg
|
[ Html.map RegisterMsg
|
||||||
(Register.viewSidebar model.sidebarVisible model.flags model.uiSettings model.registerModel)
|
(Register.viewSidebar model.sidebarVisible model.flags model.uiSettings model.registerModel)
|
||||||
, Html.map RegisterMsg
|
, Html.map RegisterMsg
|
||||||
(Register.viewContent model.flags model.uiSettings model.registerModel)
|
(Register.viewContent texts.register model.flags model.uiSettings model.registerModel)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewNewInvite : Model -> List (Html Msg)
|
viewNewInvite : Messages -> Model -> List (Html Msg)
|
||||||
viewNewInvite model =
|
viewNewInvite texts model =
|
||||||
[ Html.map NewInviteMsg
|
[ Html.map NewInviteMsg
|
||||||
(NewInvite.viewSidebar model.sidebarVisible model.flags model.uiSettings model.newInviteModel)
|
(NewInvite.viewSidebar model.sidebarVisible model.flags model.uiSettings model.newInviteModel)
|
||||||
, Html.map NewInviteMsg
|
, Html.map NewInviteMsg
|
||||||
(NewInvite.viewContent model.flags model.uiSettings model.newInviteModel)
|
(NewInvite.viewContent texts.newInvite model.flags model.uiSettings model.newInviteModel)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewUpload : Maybe String -> Model -> List (Html Msg)
|
viewUpload : Messages -> Maybe String -> Model -> List (Html Msg)
|
||||||
viewUpload mid model =
|
viewUpload texts mid model =
|
||||||
[ Html.map UploadMsg
|
[ Html.map UploadMsg
|
||||||
(Upload.viewSidebar
|
(Upload.viewSidebar
|
||||||
mid
|
mid
|
||||||
@ -434,7 +521,8 @@ viewUpload mid model =
|
|||||||
model.uploadModel
|
model.uploadModel
|
||||||
)
|
)
|
||||||
, Html.map UploadMsg
|
, Html.map UploadMsg
|
||||||
(Upload.viewContent mid
|
(Upload.viewContent texts.upload
|
||||||
|
mid
|
||||||
model.flags
|
model.flags
|
||||||
model.uiSettings
|
model.uiSettings
|
||||||
model.uploadModel
|
model.uploadModel
|
||||||
@ -442,21 +530,21 @@ viewUpload mid model =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewItemDetail : String -> Model -> List (Html Msg)
|
viewItemDetail : Messages -> String -> Model -> List (Html Msg)
|
||||||
viewItemDetail id model =
|
viewItemDetail texts id model =
|
||||||
let
|
let
|
||||||
inav =
|
inav =
|
||||||
Page.Home.Data.itemNav id model.homeModel
|
Page.Home.Data.itemNav id model.homeModel
|
||||||
in
|
in
|
||||||
[ Html.map ItemDetailMsg
|
[ Html.map ItemDetailMsg
|
||||||
(ItemDetail.viewSidebar
|
(ItemDetail.viewSidebar texts.itemDetail
|
||||||
model.sidebarVisible
|
model.sidebarVisible
|
||||||
model.flags
|
model.flags
|
||||||
model.uiSettings
|
model.uiSettings
|
||||||
model.itemDetailModel
|
model.itemDetailModel
|
||||||
)
|
)
|
||||||
, Html.map ItemDetailMsg
|
, Html.map ItemDetailMsg
|
||||||
(ItemDetail.viewContent
|
(ItemDetail.viewContent texts.itemDetail
|
||||||
inav
|
inav
|
||||||
model.flags
|
model.flags
|
||||||
model.uiSettings
|
model.uiSettings
|
||||||
|
@ -14,6 +14,7 @@ import Data.UiSettings exposing (UiSettings)
|
|||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onInput)
|
import Html.Events exposing (onInput)
|
||||||
|
import Messages.Comp.AddressForm exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.List
|
import Util.List
|
||||||
|
|
||||||
@ -51,9 +52,7 @@ emptyModel =
|
|||||||
, city = ""
|
, city = ""
|
||||||
, country =
|
, country =
|
||||||
Comp.Dropdown.makeSingleList
|
Comp.Dropdown.makeSingleList
|
||||||
{ makeOption = \c -> { value = c.code, text = c.label, additional = "" }
|
{ options = countries
|
||||||
, placeholder = "Select Country"
|
|
||||||
, options = countries
|
|
||||||
, selected = Nothing
|
, selected = Nothing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -112,8 +111,16 @@ update msg model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : UiSettings -> Model -> Html Msg
|
view2 : Texts -> UiSettings -> Model -> Html Msg
|
||||||
view2 settings model =
|
view2 texts settings model =
|
||||||
|
let
|
||||||
|
countryCfg =
|
||||||
|
{ makeOption = \c -> { text = c.label, additional = "" }
|
||||||
|
, placeholder = texts.selectCountry
|
||||||
|
, labelColor = \_ -> \_ -> ""
|
||||||
|
, style = DS.mainStyle
|
||||||
|
}
|
||||||
|
in
|
||||||
div [ class "flex flex-col" ]
|
div [ class "flex flex-col" ]
|
||||||
[ div
|
[ div
|
||||||
[ class "mb-2"
|
[ class "mb-2"
|
||||||
@ -122,12 +129,12 @@ view2 settings model =
|
|||||||
[ for "street"
|
[ for "street"
|
||||||
, class S.inputLabel
|
, class S.inputLabel
|
||||||
]
|
]
|
||||||
[ text "Street"
|
[ text texts.street
|
||||||
]
|
]
|
||||||
, input
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
, onInput SetStreet
|
, onInput SetStreet
|
||||||
, placeholder "Street"
|
, placeholder texts.street
|
||||||
, value model.street
|
, value model.street
|
||||||
, name "street"
|
, name "street"
|
||||||
, class S.textInput
|
, class S.textInput
|
||||||
@ -141,12 +148,12 @@ view2 settings model =
|
|||||||
[ for "zip"
|
[ for "zip"
|
||||||
, class S.inputLabel
|
, class S.inputLabel
|
||||||
]
|
]
|
||||||
[ text "Zip Code"
|
[ text texts.zipCode
|
||||||
]
|
]
|
||||||
, input
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
, onInput SetZip
|
, onInput SetZip
|
||||||
, placeholder "Zip"
|
, placeholder texts.zipCode
|
||||||
, value model.zip
|
, value model.zip
|
||||||
, name "zip"
|
, name "zip"
|
||||||
, class S.textInput
|
, class S.textInput
|
||||||
@ -160,12 +167,12 @@ view2 settings model =
|
|||||||
[ for "city"
|
[ for "city"
|
||||||
, class S.inputLabel
|
, class S.inputLabel
|
||||||
]
|
]
|
||||||
[ text "City"
|
[ text texts.city
|
||||||
]
|
]
|
||||||
, input
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
, onInput SetCity
|
, onInput SetCity
|
||||||
, placeholder "City"
|
, placeholder texts.city
|
||||||
, value model.city
|
, value model.city
|
||||||
, name "city"
|
, name "city"
|
||||||
, class S.textInput
|
, class S.textInput
|
||||||
@ -174,11 +181,11 @@ view2 settings model =
|
|||||||
]
|
]
|
||||||
, div [ class "" ]
|
, div [ class "" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "Country"
|
[ text texts.country
|
||||||
]
|
]
|
||||||
, Html.map CountryMsg
|
, Html.map CountryMsg
|
||||||
(Comp.Dropdown.view2
|
(Comp.Dropdown.view2
|
||||||
DS.mainStyle
|
countryCfg
|
||||||
settings
|
settings
|
||||||
model.country
|
model.country
|
||||||
)
|
)
|
||||||
|
@ -15,6 +15,7 @@ import Data.Flags exposing (Flags)
|
|||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Http
|
import Http
|
||||||
|
import Messages.Comp.AttachmentMeta exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.Http
|
import Util.Http
|
||||||
import Util.Time
|
import Util.Time
|
||||||
@ -64,15 +65,18 @@ update msg model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : List (Attribute Msg) -> Model -> Html Msg
|
view2 : Texts -> List (Attribute Msg) -> Model -> Html Msg
|
||||||
view2 attrs model =
|
view2 texts attrs model =
|
||||||
div attrs
|
div attrs
|
||||||
[ h3 [ class S.header3 ]
|
[ h3 [ class S.header3 ]
|
||||||
[ text "Extracted Meta Data"
|
[ text texts.extractedMetadata
|
||||||
]
|
]
|
||||||
, case model.meta of
|
, case model.meta of
|
||||||
NotAvailable ->
|
NotAvailable ->
|
||||||
B.loadingDimmer True
|
B.loadingDimmer
|
||||||
|
{ active = True
|
||||||
|
, label = texts.basics.loading
|
||||||
|
}
|
||||||
|
|
||||||
Failure msg ->
|
Failure msg ->
|
||||||
div [ class S.errorMessage ]
|
div [ class S.errorMessage ]
|
||||||
@ -80,33 +84,33 @@ view2 attrs model =
|
|||||||
]
|
]
|
||||||
|
|
||||||
Success data ->
|
Success data ->
|
||||||
viewData2 data
|
viewData2 texts data
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewData2 : AttachmentMeta -> Html Msg
|
viewData2 : Texts -> AttachmentMeta -> Html Msg
|
||||||
viewData2 meta =
|
viewData2 texts meta =
|
||||||
div [ class "flex flex-col" ]
|
div [ class "flex flex-col" ]
|
||||||
[ div [ class "text-lg font-bold" ]
|
[ div [ class "text-lg font-bold" ]
|
||||||
[ text "Content"
|
[ text texts.content
|
||||||
]
|
]
|
||||||
, div [ class "px-2 py-2 text-sm bg-yellow-50 dark:bg-warmgray-800 break-words whitespace-pre max-h-80 overflow-auto" ]
|
, div [ class "px-2 py-2 text-sm bg-yellow-50 dark:bg-warmgray-800 break-words whitespace-pre max-h-80 overflow-auto" ]
|
||||||
[ text meta.content
|
[ text meta.content
|
||||||
]
|
]
|
||||||
, div [ class "text-lg font-bold mt-2" ]
|
, div [ class "text-lg font-bold mt-2" ]
|
||||||
[ text "Labels"
|
[ text texts.labels
|
||||||
]
|
]
|
||||||
, div [ class "flex fex-row flex-wrap" ]
|
, div [ class "flex fex-row flex-wrap" ]
|
||||||
(List.map renderLabelItem2 meta.labels)
|
(List.map renderLabelItem2 meta.labels)
|
||||||
, div [ class "text-lg font-bold mt-2" ]
|
, div [ class "text-lg font-bold mt-2" ]
|
||||||
[ text "Proposals"
|
[ text texts.proposals
|
||||||
]
|
]
|
||||||
, viewProposals2 meta.proposals
|
, viewProposals2 texts meta.proposals
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewProposals2 : ItemProposals -> Html Msg
|
viewProposals2 : Texts -> ItemProposals -> Html Msg
|
||||||
viewProposals2 props =
|
viewProposals2 texts props =
|
||||||
let
|
let
|
||||||
mkItem n lbl =
|
mkItem n lbl =
|
||||||
div
|
div
|
||||||
@ -130,32 +134,32 @@ viewProposals2 props =
|
|||||||
in
|
in
|
||||||
div [ class "flex flex-col" ]
|
div [ class "flex flex-col" ]
|
||||||
[ div [ class "font-bold mb-2" ]
|
[ div [ class "font-bold mb-2" ]
|
||||||
[ text "Correspondent Organization"
|
[ text texts.correspondentOrg
|
||||||
]
|
]
|
||||||
, div [ class "flex flex-row flex-wrap space-x-2" ]
|
, div [ class "flex flex-row flex-wrap space-x-2" ]
|
||||||
(List.indexedMap mkItem props.corrOrg)
|
(List.indexedMap mkItem props.corrOrg)
|
||||||
, div [ class "font-bold mt-3 mb-2" ]
|
, div [ class "font-bold mt-3 mb-2" ]
|
||||||
[ text "Correspondent Person"
|
[ text texts.correspondentPerson
|
||||||
]
|
]
|
||||||
, div [ class "flex flex-row flex-wrap space-x-2" ]
|
, div [ class "flex flex-row flex-wrap space-x-2" ]
|
||||||
(List.indexedMap mkItem props.corrPerson)
|
(List.indexedMap mkItem props.corrPerson)
|
||||||
, div [ class "font-bold mt-3 mb-2" ]
|
, div [ class "font-bold mt-3 mb-2" ]
|
||||||
[ text "Concerning Person"
|
[ text texts.concerningPerson
|
||||||
]
|
]
|
||||||
, div [ class "flex flex-row flex-wrap space-x-2" ]
|
, div [ class "flex flex-row flex-wrap space-x-2" ]
|
||||||
(List.indexedMap mkItem props.concPerson)
|
(List.indexedMap mkItem props.concPerson)
|
||||||
, div [ class "font-bold mt-3 mb-2" ]
|
, div [ class "font-bold mt-3 mb-2" ]
|
||||||
[ text "Concerning Equipment"
|
[ text texts.concerningEquipment
|
||||||
]
|
]
|
||||||
, div [ class "flex flex-row flex-wrap space-x-2" ]
|
, div [ class "flex flex-row flex-wrap space-x-2" ]
|
||||||
(List.indexedMap mkItem props.concEquipment)
|
(List.indexedMap mkItem props.concEquipment)
|
||||||
, div [ class "font-bold mb-2 mt-3" ]
|
, div [ class "font-bold mb-2 mt-3" ]
|
||||||
[ text "Item Date"
|
[ text texts.itemDate
|
||||||
]
|
]
|
||||||
, div [ class "flex flex-row flex-wrap space-x-2" ]
|
, div [ class "flex flex-row flex-wrap space-x-2" ]
|
||||||
(List.map mkTimeItem props.itemDate)
|
(List.map mkTimeItem props.itemDate)
|
||||||
, div [ class "font-bold mt-3 mb-2" ]
|
, div [ class "font-bold mt-3 mb-2" ]
|
||||||
[ text "Item Due Date"
|
[ text texts.itemDueDate
|
||||||
]
|
]
|
||||||
, div [ class "flex flex-row flex-wrap space-x-2 mb-2" ]
|
, div [ class "flex flex-row flex-wrap space-x-2 mb-2" ]
|
||||||
(List.map mkTimeItem props.dueDate)
|
(List.map mkTimeItem props.dueDate)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
module Comp.Basic exposing
|
module Comp.Basic exposing
|
||||||
( editLinkLabel
|
( editLinkLabel
|
||||||
, editLinkTableCell
|
, editLinkTableCell
|
||||||
|
, editLinkTableCell2
|
||||||
, genericButton
|
, genericButton
|
||||||
, horizontalDivider
|
, horizontalDivider
|
||||||
, inputRequired
|
, inputRequired
|
||||||
@ -11,12 +12,12 @@ module Comp.Basic exposing
|
|||||||
, secondaryBasicButton
|
, secondaryBasicButton
|
||||||
, secondaryButton
|
, secondaryButton
|
||||||
, stats
|
, stats
|
||||||
, tooltipRight
|
|
||||||
)
|
)
|
||||||
|
|
||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onClick)
|
import Html.Events exposing (onClick)
|
||||||
|
import Messages.Basics
|
||||||
import Styles as S
|
import Styles as S
|
||||||
|
|
||||||
|
|
||||||
@ -174,27 +175,32 @@ linkLabel model =
|
|||||||
genericLink model.icon model.label attrs
|
genericLink model.icon model.label attrs
|
||||||
|
|
||||||
|
|
||||||
loadingDimmer : Bool -> Html msg
|
loadingDimmer : { label : String, active : Bool } -> Html msg
|
||||||
loadingDimmer active =
|
loadingDimmer cfg =
|
||||||
div
|
div
|
||||||
[ classList
|
[ classList
|
||||||
[ ( "hidden", not active )
|
[ ( "hidden", not cfg.active )
|
||||||
]
|
]
|
||||||
, class S.dimmer
|
, class S.dimmer
|
||||||
]
|
]
|
||||||
[ div [ class "text-gray-200" ]
|
[ div [ class "text-gray-200" ]
|
||||||
[ i [ class "fa fa-circle-notch animate-spin" ] []
|
[ i [ class "fa fa-circle-notch animate-spin" ] []
|
||||||
, span [ class "ml-2" ]
|
, span [ class "ml-2" ]
|
||||||
[ text "Loading…"
|
[ text cfg.label
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
editLinkLabel : msg -> Html msg
|
editLinkLabel : msg -> Html msg
|
||||||
editLinkLabel click =
|
editLinkLabel =
|
||||||
|
editLinkLabel2 Messages.Basics.gb
|
||||||
|
|
||||||
|
|
||||||
|
editLinkLabel2 : Messages.Basics.Texts -> msg -> Html msg
|
||||||
|
editLinkLabel2 texts click =
|
||||||
linkLabel
|
linkLabel
|
||||||
{ label = "Edit"
|
{ label = texts.edit
|
||||||
, icon = "fa fa-edit"
|
, icon = "fa fa-edit"
|
||||||
, handler = click
|
, handler = click
|
||||||
, disabled = False
|
, disabled = False
|
||||||
@ -204,7 +210,14 @@ editLinkLabel click =
|
|||||||
editLinkTableCell : msg -> Html msg
|
editLinkTableCell : msg -> Html msg
|
||||||
editLinkTableCell m =
|
editLinkTableCell m =
|
||||||
td [ class S.editLinkTableCellStyle ]
|
td [ class S.editLinkTableCellStyle ]
|
||||||
[ editLinkLabel m
|
[ editLinkLabel2 Messages.Basics.gb m
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
editLinkTableCell2 : Messages.Basics.Texts -> msg -> Html msg
|
||||||
|
editLinkTableCell2 texts m =
|
||||||
|
td [ class S.editLinkTableCellStyle ]
|
||||||
|
[ editLinkLabel2 texts m
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -265,17 +278,6 @@ inputRequired =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
tooltipRight : Bool -> String -> Html msg
|
|
||||||
tooltipRight show msg =
|
|
||||||
div
|
|
||||||
[ class "absolute bottom-0 right-5 px-2 py-2 rounded-lg z-50 w-40"
|
|
||||||
, class "bg-white border"
|
|
||||||
, class "text-sm font-thin"
|
|
||||||
]
|
|
||||||
[ text msg
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Helpers
|
--- Helpers
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ import Html exposing (..)
|
|||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onInput)
|
import Html.Events exposing (onInput)
|
||||||
import Http
|
import Http
|
||||||
|
import Messages.Comp.CalEventInput exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.Http
|
import Util.Http
|
||||||
import Util.Maybe
|
import Util.Maybe
|
||||||
@ -129,8 +130,8 @@ update flags ev msg model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : String -> CalEvent -> Model -> Html Msg
|
view2 : Texts -> String -> CalEvent -> Model -> Html Msg
|
||||||
view2 extraClasses ev model =
|
view2 texts extraClasses ev model =
|
||||||
let
|
let
|
||||||
yearLen =
|
yearLen =
|
||||||
Basics.max 4 (String.length ev.year)
|
Basics.max 4 (String.length ev.year)
|
||||||
@ -155,7 +156,7 @@ view2 extraClasses ev model =
|
|||||||
[ label
|
[ label
|
||||||
[ class S.inputLabel
|
[ class S.inputLabel
|
||||||
]
|
]
|
||||||
[ text "Weekday" ]
|
[ text texts.weekday ]
|
||||||
, input
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
, class S.textInput
|
, class S.textInput
|
||||||
@ -172,7 +173,7 @@ view2 extraClasses ev model =
|
|||||||
]
|
]
|
||||||
, div [ class "flex flex-col space-y-2 mr-2" ]
|
, div [ class "flex flex-col space-y-2 mr-2" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "Year" ]
|
[ text texts.year ]
|
||||||
, input
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
, class S.textInput
|
, class S.textInput
|
||||||
@ -188,7 +189,7 @@ view2 extraClasses ev model =
|
|||||||
]
|
]
|
||||||
, div [ class "flex flex-col space-y-2 mr-2" ]
|
, div [ class "flex flex-col space-y-2 mr-2" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "Month" ]
|
[ text texts.month ]
|
||||||
, input
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
, class styleInput
|
, class styleInput
|
||||||
@ -204,7 +205,7 @@ view2 extraClasses ev model =
|
|||||||
]
|
]
|
||||||
, div [ class "flex flex-col space-y-2 mr-4 mr-2" ]
|
, div [ class "flex flex-col space-y-2 mr-4 mr-2" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "Day"
|
[ text texts.day
|
||||||
]
|
]
|
||||||
, input
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
@ -218,7 +219,8 @@ view2 extraClasses ev model =
|
|||||||
]
|
]
|
||||||
, div [ class "flex flex-col space-y-2 mr-2" ]
|
, div [ class "flex flex-col space-y-2 mr-2" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "Hour" ]
|
[ text texts.hour
|
||||||
|
]
|
||||||
, input
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
, class styleInput
|
, class styleInput
|
||||||
@ -234,7 +236,7 @@ view2 extraClasses ev model =
|
|||||||
]
|
]
|
||||||
, div [ class "flex flex-col space-y-2" ]
|
, div [ class "flex flex-col space-y-2" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "Minute"
|
[ text texts.minute
|
||||||
]
|
]
|
||||||
, input
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
@ -253,7 +255,7 @@ view2 extraClasses ev model =
|
|||||||
]
|
]
|
||||||
, class S.errorMessage
|
, class S.errorMessage
|
||||||
]
|
]
|
||||||
[ text "Error: "
|
[ text (texts.error ++ ": ")
|
||||||
, Maybe.map .message model.checkResult
|
, Maybe.map .message model.checkResult
|
||||||
|> Maybe.withDefault ""
|
|> Maybe.withDefault ""
|
||||||
|> text
|
|> text
|
||||||
@ -269,7 +271,7 @@ view2 extraClasses ev model =
|
|||||||
]
|
]
|
||||||
[ div []
|
[ div []
|
||||||
[ div [ class S.inputLabel ]
|
[ div [ class S.inputLabel ]
|
||||||
[ text "Schedule: "
|
[ text (texts.schedule ++ ": ")
|
||||||
]
|
]
|
||||||
, div [ class "px-12 font-mono " ]
|
, div [ class "px-12 font-mono " ]
|
||||||
[ Maybe.andThen .event model.checkResult
|
[ Maybe.andThen .event model.checkResult
|
||||||
@ -277,7 +279,7 @@ view2 extraClasses ev model =
|
|||||||
|> text
|
|> text
|
||||||
]
|
]
|
||||||
, div [ class S.inputLabel ]
|
, div [ class S.inputLabel ]
|
||||||
[ text "Next: "
|
[ text (texts.next ++ ": ")
|
||||||
]
|
]
|
||||||
, ul [ class "list-decimal list-inside text-sm" ]
|
, ul [ class "list-decimal list-inside text-sm" ]
|
||||||
(Maybe.map .next model.checkResult
|
(Maybe.map .next model.checkResult
|
||||||
|
@ -16,6 +16,7 @@ import Html exposing (..)
|
|||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onClick)
|
import Html.Events exposing (onClick)
|
||||||
import Http
|
import Http
|
||||||
|
import Messages.Comp.ChangePasswordForm exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.Http
|
import Util.Http
|
||||||
|
|
||||||
@ -179,8 +180,8 @@ update flags msg model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : Model -> Html Msg
|
view2 : Texts -> Model -> Html Msg
|
||||||
view2 model =
|
view2 texts model =
|
||||||
let
|
let
|
||||||
currentEmpty =
|
currentEmpty =
|
||||||
model.current == Nothing
|
model.current == Nothing
|
||||||
@ -195,11 +196,12 @@ view2 model =
|
|||||||
[ class "flex flex-col space-y-4 relative" ]
|
[ class "flex flex-col space-y-4 relative" ]
|
||||||
[ div []
|
[ div []
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "Current Password"
|
[ text texts.currentPassword
|
||||||
, B.inputRequired
|
, B.inputRequired
|
||||||
]
|
]
|
||||||
, Html.map SetCurrent
|
, Html.map SetCurrent
|
||||||
(Comp.PasswordInput.view2
|
(Comp.PasswordInput.view2
|
||||||
|
{ placeholder = texts.currentPasswordPlaceholder }
|
||||||
model.current
|
model.current
|
||||||
currentEmpty
|
currentEmpty
|
||||||
model.currentModel
|
model.currentModel
|
||||||
@ -209,11 +211,12 @@ view2 model =
|
|||||||
[ label
|
[ label
|
||||||
[ class S.inputLabel
|
[ class S.inputLabel
|
||||||
]
|
]
|
||||||
[ text "New Password"
|
[ text texts.newPassword
|
||||||
, B.inputRequired
|
, B.inputRequired
|
||||||
]
|
]
|
||||||
, Html.map SetNew1
|
, Html.map SetNew1
|
||||||
(Comp.PasswordInput.view2
|
(Comp.PasswordInput.view2
|
||||||
|
{ placeholder = texts.newPasswordPlaceholder }
|
||||||
model.newPass1
|
model.newPass1
|
||||||
pass1Empty
|
pass1Empty
|
||||||
model.pass1Model
|
model.pass1Model
|
||||||
@ -221,11 +224,12 @@ view2 model =
|
|||||||
]
|
]
|
||||||
, div []
|
, div []
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "New Password (repeat)"
|
[ text texts.repeatPassword
|
||||||
, B.inputRequired
|
, B.inputRequired
|
||||||
]
|
]
|
||||||
, Html.map SetNew2
|
, Html.map SetNew2
|
||||||
(Comp.PasswordInput.view2
|
(Comp.PasswordInput.view2
|
||||||
|
{ placeholder = texts.repeatPasswordPlaceholder }
|
||||||
model.newPass2
|
model.newPass2
|
||||||
pass2Empty
|
pass2Empty
|
||||||
model.pass2Model
|
model.pass2Model
|
||||||
@ -263,5 +267,8 @@ view2 model =
|
|||||||
[ text "Submit"
|
[ text "Submit"
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, B.loadingDimmer model.loading
|
, B.loadingDimmer
|
||||||
|
{ active = model.loading
|
||||||
|
, label = texts.basics.loading
|
||||||
|
}
|
||||||
]
|
]
|
||||||
|
@ -24,6 +24,7 @@ import Html exposing (..)
|
|||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Http
|
import Http
|
||||||
import Markdown
|
import Markdown
|
||||||
|
import Messages.Comp.ClassifierSettingsForm exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.Tag
|
import Util.Tag
|
||||||
|
|
||||||
@ -59,20 +60,14 @@ init flags sett =
|
|||||||
in
|
in
|
||||||
( { scheduleModel = cem
|
( { scheduleModel = cem
|
||||||
, schedule = Data.Validated.Unknown newSchedule
|
, schedule = Data.Validated.Unknown newSchedule
|
||||||
, itemCountModel = Comp.IntField.init (Just 0) Nothing True "Item Count"
|
, itemCountModel = Comp.IntField.init (Just 0) Nothing True
|
||||||
, itemCount = Just sett.itemCount
|
, itemCount = Just sett.itemCount
|
||||||
, categoryListModel =
|
, categoryListModel =
|
||||||
let
|
let
|
||||||
mkOption s =
|
|
||||||
{ value = s, text = s, additional = "" }
|
|
||||||
|
|
||||||
minit =
|
minit =
|
||||||
Comp.Dropdown.makeModel
|
Comp.Dropdown.makeModel
|
||||||
{ multiple = True
|
{ multiple = True
|
||||||
, searchable = \n -> n > 0
|
, searchable = \n -> n > 0
|
||||||
, makeOption = mkOption
|
|
||||||
, labelColor = \_ -> \_ -> "grey "
|
|
||||||
, placeholder = "Choose categories …"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lm =
|
lm =
|
||||||
@ -86,7 +81,7 @@ init flags sett =
|
|||||||
Data.ListType.fromString sett.listType
|
Data.ListType.fromString sett.listType
|
||||||
|> Maybe.withDefault Data.ListType.Whitelist
|
|> Maybe.withDefault Data.ListType.Whitelist
|
||||||
, categoryListTypeModel =
|
, categoryListTypeModel =
|
||||||
Comp.FixedDropdown.initMap Data.ListType.label Data.ListType.all
|
Comp.FixedDropdown.init Data.ListType.all
|
||||||
}
|
}
|
||||||
, Cmd.batch
|
, Cmd.batch
|
||||||
[ Api.getTags flags "" GetTagsResp
|
[ Api.getTags flags "" GetTagsResp
|
||||||
@ -183,60 +178,69 @@ update flags msg model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : UiSettings -> Model -> Html Msg
|
view2 : Texts -> UiSettings -> Model -> Html Msg
|
||||||
view2 settings model =
|
view2 texts settings model =
|
||||||
let
|
let
|
||||||
catListTypeItem =
|
categoryCfg =
|
||||||
Comp.FixedDropdown.Item
|
{ makeOption = \s -> { text = s, additional = "" }
|
||||||
model.categoryListType
|
, labelColor = \_ -> \_ -> "grey "
|
||||||
(Data.ListType.label model.categoryListType)
|
, placeholder = "Choose categories …"
|
||||||
|
, style = DS.mainStyle
|
||||||
|
}
|
||||||
|
|
||||||
|
catListCfg =
|
||||||
|
{ display = Data.ListType.label
|
||||||
|
, icon = \_ -> Nothing
|
||||||
|
, style = DS.mainStyle
|
||||||
|
}
|
||||||
in
|
in
|
||||||
div []
|
div []
|
||||||
[ Markdown.toHtml [ class "px-2 py-2 opacity-75" ]
|
[ Markdown.toHtml [ class "px-2 py-2 opacity-75" ]
|
||||||
"""
|
texts.autoTaggingText
|
||||||
|
|
||||||
Auto-tagging works by learning from existing documents. The more
|
|
||||||
documents you have correctly tagged, the better. Learning is done
|
|
||||||
periodically based on a schedule. You can specify tag-groups that
|
|
||||||
should either be used (whitelist) or not used (blacklist) for
|
|
||||||
learning.
|
|
||||||
|
|
||||||
Use an empty whitelist to disable auto tagging.
|
|
||||||
|
|
||||||
"""
|
|
||||||
, div [ class "mb-4" ]
|
, div [ class "mb-4" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "Is the following a blacklist or whitelist?" ]
|
[ text texts.blacklistOrWhitelist ]
|
||||||
, Html.map CategoryListTypeMsg
|
, Html.map CategoryListTypeMsg
|
||||||
(Comp.FixedDropdown.view2 (Just catListTypeItem) model.categoryListTypeModel)
|
(Comp.FixedDropdown.viewStyled2 catListCfg
|
||||||
|
False
|
||||||
|
(Just model.categoryListType)
|
||||||
|
model.categoryListTypeModel
|
||||||
|
)
|
||||||
]
|
]
|
||||||
, div [ class "mb-4" ]
|
, div [ class "mb-4" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ case model.categoryListType of
|
[ case model.categoryListType of
|
||||||
Data.ListType.Whitelist ->
|
Data.ListType.Whitelist ->
|
||||||
text "Include tag categories for learning"
|
text texts.whitelistLabel
|
||||||
|
|
||||||
Data.ListType.Blacklist ->
|
Data.ListType.Blacklist ->
|
||||||
text "Exclude tag categories from learning"
|
text texts.blacklistLabel
|
||||||
]
|
]
|
||||||
, Html.map CategoryListMsg
|
, Html.map CategoryListMsg
|
||||||
(Comp.Dropdown.view2
|
(Comp.Dropdown.view2
|
||||||
DS.mainStyle
|
categoryCfg
|
||||||
settings
|
settings
|
||||||
model.categoryListModel
|
model.categoryListModel
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
, Html.map ItemCountMsg
|
, Html.map ItemCountMsg
|
||||||
(Comp.IntField.viewWithInfo2
|
(Comp.IntField.view
|
||||||
"The maximum number of items to learn from, order by date newest first. Use 0 to mean all."
|
{ label = texts.itemCount
|
||||||
model.itemCount
|
, info = texts.itemCountHelp
|
||||||
"mb-4"
|
, classes = "mb-4"
|
||||||
|
, number = model.itemCount
|
||||||
|
}
|
||||||
model.itemCountModel
|
model.itemCountModel
|
||||||
)
|
)
|
||||||
, div [ class "mb-4" ]
|
, div [ class "mb-4" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "Schedule" ]
|
[ text texts.schedule ]
|
||||||
, Html.map ScheduleMsg
|
, Html.map ScheduleMsg
|
||||||
(Comp.CalEventInput.view2 "" (Data.Validated.value model.schedule) model.scheduleModel)
|
(Comp.CalEventInput.view2
|
||||||
|
texts.calEventInput
|
||||||
|
""
|
||||||
|
(Data.Validated.value model.schedule)
|
||||||
|
model.scheduleModel
|
||||||
|
)
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
@ -23,6 +23,7 @@ import Html exposing (..)
|
|||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onCheck, onClick, onInput)
|
import Html.Events exposing (onCheck, onClick, onInput)
|
||||||
import Http
|
import Http
|
||||||
|
import Messages.Comp.CollectiveSettingsForm exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.Http
|
import Util.Http
|
||||||
|
|
||||||
@ -50,14 +51,7 @@ init flags settings =
|
|||||||
in
|
in
|
||||||
( { langModel =
|
( { langModel =
|
||||||
Comp.Dropdown.makeSingleList
|
Comp.Dropdown.makeSingleList
|
||||||
{ makeOption =
|
{ options = Data.Language.all
|
||||||
\l ->
|
|
||||||
{ value = Data.Language.toIso3 l
|
|
||||||
, text = Data.Language.toName l
|
|
||||||
, additional = ""
|
|
||||||
}
|
|
||||||
, placeholder = ""
|
|
||||||
, options = Data.Language.all
|
|
||||||
, selected = Just lang
|
, selected = Just lang
|
||||||
}
|
}
|
||||||
, intEnabled = settings.integrationEnabled
|
, intEnabled = settings.integrationEnabled
|
||||||
@ -200,8 +194,20 @@ update flags msg model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : Flags -> UiSettings -> Model -> Html Msg
|
view2 : Flags -> Texts -> UiSettings -> Model -> Html Msg
|
||||||
view2 flags settings model =
|
view2 flags texts settings model =
|
||||||
|
let
|
||||||
|
languageCfg =
|
||||||
|
{ makeOption =
|
||||||
|
\l ->
|
||||||
|
{ text = texts.languageLabel l
|
||||||
|
, additional = ""
|
||||||
|
}
|
||||||
|
, placeholder = ""
|
||||||
|
, labelColor = \_ -> \_ -> ""
|
||||||
|
, style = DS.mainStyle
|
||||||
|
}
|
||||||
|
in
|
||||||
div
|
div
|
||||||
[ classList
|
[ classList
|
||||||
[ ( "ui form error success", True )
|
[ ( "ui form error success", True )
|
||||||
@ -215,10 +221,10 @@ view2 flags settings model =
|
|||||||
[ MB.CustomElement <|
|
[ MB.CustomElement <|
|
||||||
B.primaryButton
|
B.primaryButton
|
||||||
{ handler = onClick SaveSettings
|
{ handler = onClick SaveSettings
|
||||||
, label = "Save"
|
, label = texts.save
|
||||||
, icon = "fa fa-save"
|
, icon = "fa fa-save"
|
||||||
, attrs =
|
, attrs =
|
||||||
[ title "Save settings"
|
[ title texts.saveSettings
|
||||||
, href "#"
|
, href "#"
|
||||||
]
|
]
|
||||||
, disabled = getSettings model |> Data.Validated.isInvalid
|
, disabled = getSettings model |> Data.Validated.isInvalid
|
||||||
@ -228,20 +234,20 @@ view2 flags settings model =
|
|||||||
, rootClasses = "mb-4"
|
, rootClasses = "mb-4"
|
||||||
}
|
}
|
||||||
, h3 [ class S.header3 ]
|
, h3 [ class S.header3 ]
|
||||||
[ text "Document Language"
|
[ text texts.documentLanguage
|
||||||
]
|
]
|
||||||
, div [ class "mb-4" ]
|
, div [ class "mb-4" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "Document Language"
|
[ text texts.documentLanguage
|
||||||
]
|
]
|
||||||
, Html.map LangDropdownMsg
|
, Html.map LangDropdownMsg
|
||||||
(Comp.Dropdown.view2
|
(Comp.Dropdown.view2
|
||||||
DS.mainStyle
|
languageCfg
|
||||||
settings
|
settings
|
||||||
model.langModel
|
model.langModel
|
||||||
)
|
)
|
||||||
, span [ class "opacity-50 text-sm" ]
|
, span [ class "opacity-50 text-sm" ]
|
||||||
[ text "The language of your documents. This helps text recognition (OCR) and text analysis."
|
[ text texts.documentLanguageHelp
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div
|
, div
|
||||||
@ -252,7 +258,7 @@ view2 flags settings model =
|
|||||||
[ h3
|
[ h3
|
||||||
[ class S.header3
|
[ class S.header3
|
||||||
]
|
]
|
||||||
[ text "Integration Endpoint"
|
[ text texts.integrationEndpoint
|
||||||
]
|
]
|
||||||
, div [ class "mb-4" ]
|
, div [ class "mb-4" ]
|
||||||
[ label
|
[ label
|
||||||
@ -268,12 +274,11 @@ view2 flags settings model =
|
|||||||
]
|
]
|
||||||
[]
|
[]
|
||||||
, span [ class "ml-2" ]
|
, span [ class "ml-2" ]
|
||||||
[ text "Enable integration endpoint"
|
[ text texts.integrationEndpointHelp
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div [ class "opacity-50 text-sm" ]
|
, div [ class "opacity-50 text-sm" ]
|
||||||
[ text "The integration endpoint allows (local) applications to submit files. "
|
[ text texts.integrationEndpointHelp
|
||||||
, text "You can choose to disable it for your collective."
|
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -284,7 +289,7 @@ view2 flags settings model =
|
|||||||
]
|
]
|
||||||
[ h3
|
[ h3
|
||||||
[ class S.header3 ]
|
[ class S.header3 ]
|
||||||
[ text "Full-Text Search" ]
|
[ text texts.fulltextSearch ]
|
||||||
, div
|
, div
|
||||||
[ class "mb-4" ]
|
[ class "mb-4" ]
|
||||||
[ div [ class "flex flex-row" ]
|
[ div [ class "flex flex-row" ]
|
||||||
@ -304,13 +309,12 @@ view2 flags settings model =
|
|||||||
]
|
]
|
||||||
[ i [ class "fa fa-sync-alt" ] []
|
[ i [ class "fa fa-sync-alt" ] []
|
||||||
, span [ class "ml-2 hidden sm:inline" ]
|
, span [ class "ml-2 hidden sm:inline" ]
|
||||||
[ text "Re-Index All Data"
|
[ text texts.reindexAllData
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div [ class "opacity-50 text-sm" ]
|
, div [ class "opacity-50 text-sm" ]
|
||||||
[ text "This starts a task that clears the full-text index and re-indexes all your data again."
|
[ text texts.reindexAllDataHelp
|
||||||
, text "You must type OK before clicking the button to avoid accidental re-indexing."
|
|
||||||
]
|
]
|
||||||
, renderResultMessage2 model.fullTextReIndexResult
|
, renderResultMessage2 model.fullTextReIndexResult
|
||||||
]
|
]
|
||||||
@ -322,17 +326,20 @@ view2 flags settings model =
|
|||||||
]
|
]
|
||||||
[ h3
|
[ h3
|
||||||
[ class S.header3 ]
|
[ class S.header3 ]
|
||||||
[ text "Auto-Tagging"
|
[ text texts.autoTagging
|
||||||
]
|
]
|
||||||
, div
|
, div
|
||||||
[ class "mb-4" ]
|
[ class "mb-4" ]
|
||||||
[ Html.map ClassifierSettingMsg
|
[ Html.map ClassifierSettingMsg
|
||||||
(Comp.ClassifierSettingsForm.view2 settings model.classifierModel)
|
(Comp.ClassifierSettingsForm.view2 texts.classifierSettingsForm
|
||||||
|
settings
|
||||||
|
model.classifierModel
|
||||||
|
)
|
||||||
, div [ class "flex flex-row justify-end" ]
|
, div [ class "flex flex-row justify-end" ]
|
||||||
[ B.secondaryBasicButton
|
[ B.secondaryBasicButton
|
||||||
{ handler = onClick StartClassifierTask
|
{ handler = onClick StartClassifierTask
|
||||||
, icon = "fa fa-play"
|
, icon = "fa fa-play"
|
||||||
, label = "Start now"
|
, label = texts.startNow
|
||||||
, disabled = Data.Validated.isInvalid model.classifierModel.schedule
|
, disabled = Data.Validated.isInvalid model.classifierModel.schedule
|
||||||
, attrs = [ href "#" ]
|
, attrs = [ href "#" ]
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ module Comp.ColorTagger exposing
|
|||||||
|
|
||||||
import Comp.FixedDropdown
|
import Comp.FixedDropdown
|
||||||
import Data.Color exposing (Color)
|
import Data.Color exposing (Color)
|
||||||
|
import Data.DropdownStyle as DS
|
||||||
import Dict exposing (Dict)
|
import Dict exposing (Dict)
|
||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
@ -37,7 +38,7 @@ type Msg
|
|||||||
|
|
||||||
init : List String -> List Color -> Model
|
init : List String -> List Color -> Model
|
||||||
init leftSel colors =
|
init leftSel colors =
|
||||||
{ leftDropdown = Comp.FixedDropdown.initString leftSel
|
{ leftDropdown = Comp.FixedDropdown.init leftSel
|
||||||
, colors = colors
|
, colors = colors
|
||||||
, leftSelect = Nothing
|
, leftSelect = Nothing
|
||||||
}
|
}
|
||||||
@ -89,6 +90,7 @@ update msg model =
|
|||||||
|
|
||||||
type alias ViewOpts =
|
type alias ViewOpts =
|
||||||
{ renderItem : ( String, Color ) -> Html Msg
|
{ renderItem : ( String, Color ) -> Html Msg
|
||||||
|
, colorLabel : Color -> String
|
||||||
, label : String
|
, label : String
|
||||||
, description : Maybe String
|
, description : Maybe String
|
||||||
}
|
}
|
||||||
@ -96,16 +98,26 @@ type alias ViewOpts =
|
|||||||
|
|
||||||
view2 : FormData -> ViewOpts -> Model -> Html Msg
|
view2 : FormData -> ViewOpts -> Model -> Html Msg
|
||||||
view2 data opts model =
|
view2 data opts model =
|
||||||
|
let
|
||||||
|
colorLabelCfg =
|
||||||
|
{ display = identity
|
||||||
|
, icon = \_ -> Nothing
|
||||||
|
, style = DS.mainStyle
|
||||||
|
}
|
||||||
|
in
|
||||||
div [ class "flex flex-col" ]
|
div [ class "flex flex-col" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text opts.label ]
|
[ text opts.label ]
|
||||||
, Html.map LeftMsg
|
, Html.map LeftMsg
|
||||||
(Comp.FixedDropdown.view2
|
(Comp.FixedDropdown.viewStyled2
|
||||||
(Maybe.map (\s -> Comp.FixedDropdown.Item s s) model.leftSelect)
|
colorLabelCfg
|
||||||
|
False
|
||||||
|
model.leftSelect
|
||||||
model.leftDropdown
|
model.leftDropdown
|
||||||
)
|
)
|
||||||
, div [ class "field" ]
|
, div [ class "field" ]
|
||||||
[ chooseColor2
|
[ chooseColor2
|
||||||
|
opts.colorLabel
|
||||||
(AddPair data)
|
(AddPair data)
|
||||||
Data.Color.all
|
Data.Color.all
|
||||||
Nothing
|
Nothing
|
||||||
@ -159,8 +171,8 @@ renderFormData2 opts data =
|
|||||||
(List.map valueItem values)
|
(List.map valueItem values)
|
||||||
|
|
||||||
|
|
||||||
chooseColor2 : (Color -> msg) -> List Color -> Maybe String -> Html msg
|
chooseColor2 : (Color -> String) -> (Color -> msg) -> List Color -> Maybe String -> Html msg
|
||||||
chooseColor2 tagger colors mtext =
|
chooseColor2 colorLabel tagger colors mtext =
|
||||||
let
|
let
|
||||||
renderLabel color =
|
renderLabel color =
|
||||||
a
|
a
|
||||||
@ -170,7 +182,7 @@ chooseColor2 tagger colors mtext =
|
|||||||
, onClick (tagger color)
|
, onClick (tagger color)
|
||||||
]
|
]
|
||||||
[ Maybe.withDefault
|
[ Maybe.withDefault
|
||||||
(Data.Color.toString color)
|
(colorLabel color)
|
||||||
mtext
|
mtext
|
||||||
|> text
|
|> text
|
||||||
]
|
]
|
||||||
|
@ -23,14 +23,14 @@ type alias Settings msg =
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
defaultSettings : msg -> msg -> String -> Settings msg
|
defaultSettings : msg -> msg -> String -> String -> String -> Settings msg
|
||||||
defaultSettings confirm cancel confirmMsg =
|
defaultSettings confirm cancel okLabel cancelLabel confirmMsg =
|
||||||
{ enabled = True
|
{ enabled = True
|
||||||
, extraClass = ""
|
, extraClass = ""
|
||||||
, headerIcon = "fa fa-exclamation-circle mr-3"
|
, headerIcon = "fa fa-exclamation-circle mr-3"
|
||||||
, headerClass = "text-2xl font-bold text-center w-full"
|
, headerClass = "text-2xl font-bold text-center w-full"
|
||||||
, confirmText = "Ok"
|
, confirmText = okLabel
|
||||||
, cancelText = "Cancel"
|
, cancelText = cancelLabel
|
||||||
, message = confirmMsg
|
, message = confirmMsg
|
||||||
, confirm = confirm
|
, confirm = confirm
|
||||||
, cancel = cancel
|
, cancel = cancel
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
module Comp.ContactField exposing
|
module Comp.ContactField exposing
|
||||||
( Model
|
( Model
|
||||||
, Msg(..)
|
, Msg(..)
|
||||||
|
, ViewSettings
|
||||||
, emptyModel
|
, emptyModel
|
||||||
, getContacts
|
, getContacts
|
||||||
, update
|
, update
|
||||||
@ -11,6 +12,7 @@ import Api.Model.Contact exposing (Contact)
|
|||||||
import Comp.Basic as B
|
import Comp.Basic as B
|
||||||
import Comp.FixedDropdown
|
import Comp.FixedDropdown
|
||||||
import Data.ContactType exposing (ContactType)
|
import Data.ContactType exposing (ContactType)
|
||||||
|
import Data.DropdownStyle as DS
|
||||||
import Data.UiSettings exposing (UiSettings)
|
import Data.UiSettings exposing (UiSettings)
|
||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
@ -30,7 +32,7 @@ emptyModel : Model
|
|||||||
emptyModel =
|
emptyModel =
|
||||||
{ items = []
|
{ items = []
|
||||||
, kind =
|
, kind =
|
||||||
Comp.FixedDropdown.initMap Data.ContactType.toString Data.ContactType.all
|
Comp.FixedDropdown.init Data.ContactType.all
|
||||||
, selectedKind = List.head Data.ContactType.all
|
, selectedKind = List.head Data.ContactType.all
|
||||||
, value = ""
|
, value = ""
|
||||||
}
|
}
|
||||||
@ -41,13 +43,6 @@ getContacts model =
|
|||||||
List.filter (\c -> c.value /= "") model.items
|
List.filter (\c -> c.value /= "") model.items
|
||||||
|
|
||||||
|
|
||||||
makeDropdownItem : ContactType -> Comp.FixedDropdown.Item ContactType
|
|
||||||
makeDropdownItem ct =
|
|
||||||
{ id = ct
|
|
||||||
, display = Data.ContactType.toString ct
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type Msg
|
type Msg
|
||||||
= SetValue String
|
= SetValue String
|
||||||
| TypeMsg (Comp.FixedDropdown.Msg ContactType)
|
| TypeMsg (Comp.FixedDropdown.Msg ContactType)
|
||||||
@ -121,19 +116,34 @@ update msg model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : Bool -> UiSettings -> Model -> Html Msg
|
type alias ViewSettings =
|
||||||
view2 mobile _ model =
|
{ contactTypeLabel : ContactType -> String
|
||||||
|
, mobile : Bool
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
view2 : ViewSettings -> UiSettings -> Model -> Html Msg
|
||||||
|
view2 cfg _ model =
|
||||||
|
let
|
||||||
|
kindCfg =
|
||||||
|
{ display = cfg.contactTypeLabel
|
||||||
|
, icon = \_ -> Nothing
|
||||||
|
, style = DS.mainStyle
|
||||||
|
}
|
||||||
|
in
|
||||||
div [ class "flex flex-col" ]
|
div [ class "flex flex-col" ]
|
||||||
[ div
|
[ div
|
||||||
[ class "flex flex-col space-y-2"
|
[ class "flex flex-col space-y-2"
|
||||||
, classList [ ( " md:flex-row md:space-y-0 md:space-x-2", not mobile ) ]
|
, classList [ ( " md:flex-row md:space-y-0 md:space-x-2", not cfg.mobile ) ]
|
||||||
]
|
]
|
||||||
[ div
|
[ div
|
||||||
[ classList [ ( "flex-none md:w-1/6", not mobile ) ]
|
[ classList [ ( "flex-none md:w-1/6", not cfg.mobile ) ]
|
||||||
]
|
]
|
||||||
[ Html.map TypeMsg
|
[ Html.map TypeMsg
|
||||||
(Comp.FixedDropdown.view2
|
(Comp.FixedDropdown.viewStyled2
|
||||||
(Maybe.map makeDropdownItem model.selectedKind)
|
kindCfg
|
||||||
|
False
|
||||||
|
model.selectedKind
|
||||||
model.kind
|
model.kind
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
@ -160,7 +170,7 @@ view2 mobile _ model =
|
|||||||
]
|
]
|
||||||
, class "flex flex-col space-y-2 mt-2 px-2 border-0 border-l dark:border-bluegray-600 "
|
, class "flex flex-col space-y-2 mt-2 px-2 border-0 border-l dark:border-bluegray-600 "
|
||||||
]
|
]
|
||||||
(List.map (renderItem2 mobile) model.items)
|
(List.map (renderItem2 cfg.mobile) model.items)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,8 +23,9 @@ import Data.Flags exposing (Flags)
|
|||||||
import Data.Validated exposing (Validated)
|
import Data.Validated exposing (Validated)
|
||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onClick, onInput)
|
import Html.Events exposing (onInput)
|
||||||
import Http
|
import Http
|
||||||
|
import Messages.Comp.CustomFieldForm exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.Http
|
import Util.Http
|
||||||
import Util.Maybe
|
import Util.Maybe
|
||||||
@ -61,8 +62,7 @@ init field =
|
|||||||
, label = field.label
|
, label = field.label
|
||||||
, ftype = Data.CustomFieldType.fromString field.ftype
|
, ftype = Data.CustomFieldType.fromString field.ftype
|
||||||
, ftypeModel =
|
, ftypeModel =
|
||||||
Comp.FixedDropdown.initMap Data.CustomFieldType.label
|
Comp.FixedDropdown.init Data.CustomFieldType.all
|
||||||
Data.CustomFieldType.all
|
|
||||||
, loading = False
|
, loading = False
|
||||||
, deleteDimmer = Comp.YesNoDimmer.emptyModel
|
, deleteDimmer = Comp.YesNoDimmer.emptyModel
|
||||||
}
|
}
|
||||||
@ -197,17 +197,22 @@ type alias ViewSettings =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : ViewSettings -> Model -> List (Html Msg)
|
view2 : Texts -> ViewSettings -> Model -> List (Html Msg)
|
||||||
view2 viewSettings model =
|
view2 texts viewSettings model =
|
||||||
let
|
let
|
||||||
mkItem cft =
|
|
||||||
Comp.FixedDropdown.Item cft (Data.CustomFieldType.label cft)
|
|
||||||
|
|
||||||
dimmerSettings =
|
dimmerSettings =
|
||||||
Comp.YesNoDimmer.defaultSettings2 "Really delete this custom field?"
|
Comp.YesNoDimmer.defaultSettings texts.reallyDeleteField
|
||||||
|
texts.basics.yes
|
||||||
|
texts.basics.no
|
||||||
|
|
||||||
|
ftypeCfg =
|
||||||
|
{ display = texts.fieldTypeLabel
|
||||||
|
, icon = \_ -> Nothing
|
||||||
|
, style = DS.mainStyle
|
||||||
|
}
|
||||||
in
|
in
|
||||||
(if viewSettings.showControls then
|
(if viewSettings.showControls then
|
||||||
[ viewButtons2 model ]
|
[ viewButtons2 texts model ]
|
||||||
|
|
||||||
else
|
else
|
||||||
[]
|
[]
|
||||||
@ -236,20 +241,19 @@ view2 viewSettings model =
|
|||||||
]
|
]
|
||||||
, if model.field.id == "" then
|
, if model.field.id == "" then
|
||||||
div [ class "py-2 text-lg opacity-75" ]
|
div [ class "py-2 text-lg opacity-75" ]
|
||||||
[ text "Create a new custom field."
|
[ text texts.createCustomField
|
||||||
]
|
]
|
||||||
|
|
||||||
else
|
else
|
||||||
div [ class "py-2 text-lg opacity-75" ]
|
div [ class "py-2 text-lg opacity-75" ]
|
||||||
[ text "Note that changing the format may "
|
[ text texts.modifyTypeWarning
|
||||||
, text "result in invisible values in the ui, if they don't comply to the new format!"
|
|
||||||
]
|
]
|
||||||
, div [ class "mb-4" ]
|
, div [ class "mb-4" ]
|
||||||
[ label
|
[ label
|
||||||
[ class S.inputLabel
|
[ class S.inputLabel
|
||||||
, for "fieldname"
|
, for "fieldname"
|
||||||
]
|
]
|
||||||
[ text "Name"
|
[ text texts.basics.name
|
||||||
, B.inputRequired
|
, B.inputRequired
|
||||||
]
|
]
|
||||||
, input
|
, input
|
||||||
@ -266,27 +270,25 @@ view2 viewSettings model =
|
|||||||
]
|
]
|
||||||
[]
|
[]
|
||||||
, div [ class "opacity-75 text-sm" ]
|
, div [ class "opacity-75 text-sm" ]
|
||||||
[ text "The name uniquely identifies this field. It must be a valid "
|
[ text texts.nameInfo
|
||||||
, text "identifier, not contain spaces or weird characters."
|
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div
|
, div
|
||||||
[ class "mb-4"
|
[ class "mb-4"
|
||||||
]
|
]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "Field Format"
|
[ text texts.fieldFormat
|
||||||
, B.inputRequired
|
, B.inputRequired
|
||||||
]
|
]
|
||||||
, Html.map FTypeMsg
|
, Html.map FTypeMsg
|
||||||
(Comp.FixedDropdown.viewStyled2
|
(Comp.FixedDropdown.viewStyled2
|
||||||
DS.mainStyle
|
ftypeCfg
|
||||||
(model.ftype == Nothing)
|
(model.ftype == Nothing)
|
||||||
(Maybe.map mkItem model.ftype)
|
model.ftype
|
||||||
model.ftypeModel
|
model.ftypeModel
|
||||||
)
|
)
|
||||||
, div [ class "opacity-75 text-sm" ]
|
, div [ class "opacity-75 text-sm" ]
|
||||||
[ text "A field must have a format. Values are validated "
|
[ text texts.fieldFormatInfo
|
||||||
, text "according to this format."
|
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div [ class "mb-4" ]
|
, div [ class "mb-4" ]
|
||||||
@ -294,7 +296,7 @@ view2 viewSettings model =
|
|||||||
[ class S.inputLabel
|
[ class S.inputLabel
|
||||||
, for "fieldlabel"
|
, for "fieldlabel"
|
||||||
]
|
]
|
||||||
[ text "Label" ]
|
[ text texts.label ]
|
||||||
, input
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
, onInput SetLabel
|
, onInput SetLabel
|
||||||
@ -306,38 +308,37 @@ view2 viewSettings model =
|
|||||||
]
|
]
|
||||||
[]
|
[]
|
||||||
, div [ class "opacity-75 text-sm" ]
|
, div [ class "opacity-75 text-sm" ]
|
||||||
[ text "The user defined label for this field. This is used to represent "
|
[ text texts.labelInfo
|
||||||
, text "this field in the ui. If not present, the name is used."
|
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewButtons2 : Model -> Html Msg
|
viewButtons2 : Texts -> Model -> Html Msg
|
||||||
viewButtons2 model =
|
viewButtons2 texts model =
|
||||||
MB.view
|
MB.view
|
||||||
{ start =
|
{ start =
|
||||||
[ MB.PrimaryButton
|
[ MB.PrimaryButton
|
||||||
{ tagger = SubmitForm
|
{ tagger = SubmitForm
|
||||||
, title = "Submit this form"
|
, title = texts.basics.submitThisForm
|
||||||
, icon = Just "fa fa-save"
|
, icon = Just "fa fa-save"
|
||||||
, label = "Submit"
|
, label = texts.basics.submit
|
||||||
}
|
}
|
||||||
, MB.SecondaryButton
|
, MB.SecondaryButton
|
||||||
{ tagger = GoBack
|
{ tagger = GoBack
|
||||||
, title = "Back to list"
|
, title = texts.basics.backToList
|
||||||
, icon = Just "fa fa-arrow-left"
|
, icon = Just "fa fa-arrow-left"
|
||||||
, label = "Cancel"
|
, label = texts.basics.cancel
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
, end =
|
, end =
|
||||||
if model.field.id /= "" then
|
if model.field.id /= "" then
|
||||||
[ MB.DeleteButton
|
[ MB.DeleteButton
|
||||||
{ tagger = RequestDelete
|
{ tagger = RequestDelete
|
||||||
, title = "Delete this field"
|
, title = texts.deleteThisField
|
||||||
, icon = Just "fa fa-trash"
|
, icon = Just "fa fa-trash"
|
||||||
, label = "Delete"
|
, label = texts.basics.delete
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -16,12 +16,13 @@ import Comp.DatePicker
|
|||||||
import Comp.MenuBar as MB
|
import Comp.MenuBar as MB
|
||||||
import Data.CustomFieldType exposing (CustomFieldType)
|
import Data.CustomFieldType exposing (CustomFieldType)
|
||||||
import Data.Icons as Icons
|
import Data.Icons as Icons
|
||||||
import Data.Money
|
import Data.Money exposing (MoneyParseError(..))
|
||||||
import Date exposing (Date)
|
import Date exposing (Date)
|
||||||
import DatePicker exposing (DatePicker)
|
import DatePicker exposing (DatePicker)
|
||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onCheck, onClick, onInput)
|
import Html.Events exposing (onClick, onInput)
|
||||||
|
import Messages.Comp.CustomFieldInput exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.Maybe
|
import Util.Maybe
|
||||||
|
|
||||||
@ -32,9 +33,15 @@ type alias Model =
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type FieldError
|
||||||
|
= NoValue
|
||||||
|
| NotANumber String
|
||||||
|
| NotMoney MoneyParseError
|
||||||
|
|
||||||
|
|
||||||
type alias FloatModel =
|
type alias FloatModel =
|
||||||
{ input : String
|
{ input : String
|
||||||
, result : Result String Float
|
, result : Result FieldError Float
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -61,27 +68,47 @@ fieldType field =
|
|||||||
|> Maybe.withDefault Data.CustomFieldType.Text
|
|> Maybe.withDefault Data.CustomFieldType.Text
|
||||||
|
|
||||||
|
|
||||||
errorMsg : Model -> Maybe String
|
errorMsg : Texts -> Model -> Maybe String
|
||||||
errorMsg model =
|
errorMsg texts model =
|
||||||
let
|
let
|
||||||
getMsg res =
|
parseMsg isMoneyField perr =
|
||||||
case res of
|
case perr of
|
||||||
Ok _ ->
|
NoValue ->
|
||||||
Nothing
|
if isMoneyField then
|
||||||
|
Just <| texts.errorNoAmount
|
||||||
|
|
||||||
Err m ->
|
else
|
||||||
Just m
|
Just <| texts.errorNoNumber
|
||||||
|
|
||||||
|
NotANumber str ->
|
||||||
|
Just <| texts.errorNotANumber str
|
||||||
|
|
||||||
|
NotMoney (RequireTwoDigitsAfterDot _) ->
|
||||||
|
Just "Two digits required after the dot."
|
||||||
|
|
||||||
|
NotMoney (NoOrTooManyPoints _) ->
|
||||||
|
Just "One single dot + digits required for money."
|
||||||
in
|
in
|
||||||
case model.fieldModel of
|
case model.fieldModel of
|
||||||
NumberField fm ->
|
NumberField fm ->
|
||||||
getMsg fm.result
|
case fm.result of
|
||||||
|
Ok _ ->
|
||||||
|
Nothing
|
||||||
|
|
||||||
|
Err parseError ->
|
||||||
|
parseMsg False parseError
|
||||||
|
|
||||||
MoneyField fm ->
|
MoneyField fm ->
|
||||||
getMsg fm.result
|
case fm.result of
|
||||||
|
Ok _ ->
|
||||||
|
Nothing
|
||||||
|
|
||||||
|
Err parseError ->
|
||||||
|
parseMsg True parseError
|
||||||
|
|
||||||
TextField mt ->
|
TextField mt ->
|
||||||
if mt == Nothing then
|
if mt == Nothing then
|
||||||
Just "Please fill in some value"
|
Just texts.errorNoValue
|
||||||
|
|
||||||
else
|
else
|
||||||
Nothing
|
Nothing
|
||||||
@ -103,10 +130,10 @@ init field =
|
|||||||
TextField Nothing
|
TextField Nothing
|
||||||
|
|
||||||
Data.CustomFieldType.Numeric ->
|
Data.CustomFieldType.Numeric ->
|
||||||
NumberField (FloatModel "" (Err "No number given"))
|
NumberField (FloatModel "" (Err NoValue))
|
||||||
|
|
||||||
Data.CustomFieldType.Money ->
|
Data.CustomFieldType.Money ->
|
||||||
MoneyField (FloatModel "" (Err "No amount given"))
|
MoneyField (FloatModel "" (Err NoValue))
|
||||||
|
|
||||||
Data.CustomFieldType.Boolean ->
|
Data.CustomFieldType.Boolean ->
|
||||||
BoolField False
|
BoolField False
|
||||||
@ -150,7 +177,7 @@ initWith value =
|
|||||||
updateFloatModel
|
updateFloatModel
|
||||||
False
|
False
|
||||||
value.value
|
value.value
|
||||||
Data.Money.fromString
|
(Data.Money.fromString >> Result.mapError NotMoney)
|
||||||
Data.Money.normalizeInput
|
Data.Money.normalizeInput
|
||||||
in
|
in
|
||||||
MoneyField fm
|
MoneyField fm
|
||||||
@ -230,7 +257,7 @@ update1 forSearch msg model =
|
|||||||
updateFloatModel
|
updateFloatModel
|
||||||
forSearch
|
forSearch
|
||||||
str
|
str
|
||||||
Data.Money.fromString
|
(Data.Money.fromString >> Result.mapError NotMoney)
|
||||||
Data.Money.normalizeInput
|
Data.Money.normalizeInput
|
||||||
|
|
||||||
model_ =
|
model_ =
|
||||||
@ -294,7 +321,7 @@ update1 forSearch msg model =
|
|||||||
updateFloatModel :
|
updateFloatModel :
|
||||||
Bool
|
Bool
|
||||||
-> String
|
-> String
|
||||||
-> (String -> Result String Float)
|
-> (String -> Result FieldError Float)
|
||||||
-> (String -> String)
|
-> (String -> String)
|
||||||
-> ( FloatModel, FieldResult )
|
-> ( FloatModel, FieldResult )
|
||||||
updateFloatModel forSearch msg parse normalize =
|
updateFloatModel forSearch msg parse normalize =
|
||||||
@ -331,11 +358,11 @@ hasWildCards msg =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : String -> Maybe String -> Model -> Html Msg
|
view2 : Texts -> String -> Maybe String -> Model -> Html Msg
|
||||||
view2 classes icon model =
|
view2 texts classes icon model =
|
||||||
let
|
let
|
||||||
error =
|
error =
|
||||||
errorMsg model
|
errorMsg texts model
|
||||||
in
|
in
|
||||||
div
|
div
|
||||||
[ class classes
|
[ class classes
|
||||||
@ -473,11 +500,11 @@ mkLabel model =
|
|||||||
Maybe.withDefault model.field.name model.field.label
|
Maybe.withDefault model.field.name model.field.label
|
||||||
|
|
||||||
|
|
||||||
string2Float : String -> Result String Float
|
string2Float : String -> Result FieldError Float
|
||||||
string2Float str =
|
string2Float str =
|
||||||
case String.toFloat str of
|
case String.toFloat str of
|
||||||
Just n ->
|
Just n ->
|
||||||
Ok n
|
Ok n
|
||||||
|
|
||||||
Nothing ->
|
Nothing ->
|
||||||
Err ("Not a number: " ++ str)
|
Err (NotANumber str)
|
||||||
|
@ -17,8 +17,8 @@ import Comp.MenuBar as MB
|
|||||||
import Data.Flags exposing (Flags)
|
import Data.Flags exposing (Flags)
|
||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onClick, onInput)
|
|
||||||
import Http
|
import Http
|
||||||
|
import Messages.Comp.CustomFieldManage exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.CustomField
|
import Util.CustomField
|
||||||
|
|
||||||
@ -135,18 +135,18 @@ update flags msg model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : Flags -> Model -> Html Msg
|
view2 : Texts -> Flags -> Model -> Html Msg
|
||||||
view2 flags model =
|
view2 texts flags model =
|
||||||
case model.detailModel of
|
case model.detailModel of
|
||||||
Just dm ->
|
Just dm ->
|
||||||
viewDetail2 flags dm
|
viewDetail2 texts flags dm
|
||||||
|
|
||||||
Nothing ->
|
Nothing ->
|
||||||
viewTable2 model
|
viewTable2 texts model
|
||||||
|
|
||||||
|
|
||||||
viewDetail2 : Flags -> Comp.CustomFieldForm.Model -> Html Msg
|
viewDetail2 : Texts -> Flags -> Comp.CustomFieldForm.Model -> Html Msg
|
||||||
viewDetail2 _ detailModel =
|
viewDetail2 texts _ detailModel =
|
||||||
let
|
let
|
||||||
viewSettings =
|
viewSettings =
|
||||||
{ showControls = True
|
{ showControls = True
|
||||||
@ -156,44 +156,55 @@ viewDetail2 _ detailModel =
|
|||||||
div []
|
div []
|
||||||
((if detailModel.field.id == "" then
|
((if detailModel.field.id == "" then
|
||||||
h3 [ class S.header2 ]
|
h3 [ class S.header2 ]
|
||||||
[ text "Create new custom field"
|
[ text texts.newCustomField
|
||||||
]
|
]
|
||||||
|
|
||||||
else
|
else
|
||||||
h3 [ class S.header2 ]
|
h3 [ class S.header2 ]
|
||||||
[ Util.CustomField.nameOrLabel detailModel.field |> text
|
[ Util.CustomField.nameOrLabel detailModel.field |> text
|
||||||
, div [ class "opacity-50 text-sm" ]
|
, div [ class "opacity-50 text-sm" ]
|
||||||
[ text "Id: "
|
[ text (texts.basics.id ++ ": ")
|
||||||
, text detailModel.field.id
|
, text detailModel.field.id
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
:: List.map (Html.map DetailMsg) (Comp.CustomFieldForm.view2 viewSettings detailModel)
|
:: List.map (Html.map DetailMsg)
|
||||||
|
(Comp.CustomFieldForm.view2 texts.fieldForm
|
||||||
|
viewSettings
|
||||||
|
detailModel
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
viewTable2 : Model -> Html Msg
|
viewTable2 : Texts -> Model -> Html Msg
|
||||||
viewTable2 model =
|
viewTable2 texts model =
|
||||||
div [ class "flex flex-col md:relative" ]
|
div [ class "flex flex-col md:relative" ]
|
||||||
[ MB.view
|
[ MB.view
|
||||||
{ start =
|
{ start =
|
||||||
[ MB.TextInput
|
[ MB.TextInput
|
||||||
{ tagger = SetQuery
|
{ tagger = SetQuery
|
||||||
, value = model.query
|
, value = model.query
|
||||||
, placeholder = "Search…"
|
, placeholder = texts.basics.searchPlaceholder
|
||||||
, icon = Just "fa fa-search"
|
, icon = Just "fa fa-search"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
, end =
|
, end =
|
||||||
[ MB.PrimaryButton
|
[ MB.PrimaryButton
|
||||||
{ tagger = InitNewCustomField
|
{ tagger = InitNewCustomField
|
||||||
, title = "Add a new custom field"
|
, title = texts.addCustomField
|
||||||
, icon = Just "fa fa-plus"
|
, icon = Just "fa fa-plus"
|
||||||
, label = "New custom field"
|
, label = texts.newCustomField
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
, rootClasses = "mb-4"
|
, rootClasses = "mb-4"
|
||||||
}
|
}
|
||||||
, Html.map TableMsg (Comp.CustomFieldTable.view2 model.tableModel model.fields)
|
, Html.map TableMsg
|
||||||
, B.loadingDimmer model.loading
|
(Comp.CustomFieldTable.view2 texts.fieldTable
|
||||||
|
model.tableModel
|
||||||
|
model.fields
|
||||||
|
)
|
||||||
|
, B.loadingDimmer
|
||||||
|
{ active = model.loading
|
||||||
|
, label = texts.basics.loading
|
||||||
|
}
|
||||||
]
|
]
|
||||||
|
@ -29,6 +29,7 @@ import Html exposing (..)
|
|||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onClick)
|
import Html.Events exposing (onClick)
|
||||||
import Http
|
import Http
|
||||||
|
import Messages.Comp.CustomFieldMultiInput exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.CustomField
|
import Util.CustomField
|
||||||
import Util.Maybe
|
import Util.Maybe
|
||||||
@ -130,7 +131,7 @@ reset model =
|
|||||||
mkFieldSelect : List CustomField -> FieldSelect
|
mkFieldSelect : List CustomField -> FieldSelect
|
||||||
mkFieldSelect fields =
|
mkFieldSelect fields =
|
||||||
{ selected = Nothing
|
{ selected = Nothing
|
||||||
, dropdown = Comp.FixedDropdown.init (List.map mkItem fields)
|
, dropdown = Comp.FixedDropdown.init fields
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -145,11 +146,6 @@ type alias UpdateResult =
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
mkItem : CustomField -> Comp.FixedDropdown.Item CustomField
|
|
||||||
mkItem f =
|
|
||||||
Comp.FixedDropdown.Item f (Maybe.withDefault f.name f.label)
|
|
||||||
|
|
||||||
|
|
||||||
update : Flags -> Msg -> Model -> UpdateResult
|
update : Flags -> Msg -> Model -> UpdateResult
|
||||||
update =
|
update =
|
||||||
update1 False
|
update1 False
|
||||||
@ -318,25 +314,33 @@ type alias ViewSettings =
|
|||||||
{ showAddButton : Bool
|
{ showAddButton : Bool
|
||||||
, classes : String
|
, classes : String
|
||||||
, fieldIcon : CustomField -> Maybe String
|
, fieldIcon : CustomField -> Maybe String
|
||||||
|
, style : DS.DropdownStyle
|
||||||
|
, createCustomFieldTitle : String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
view2 : DS.DropdownStyle -> ViewSettings -> Model -> Html Msg
|
view2 : Texts -> ViewSettings -> Model -> Html Msg
|
||||||
view2 ddstyle viewSettings model =
|
view2 texts viewSettings model =
|
||||||
div [ class viewSettings.classes ]
|
div [ class viewSettings.classes ]
|
||||||
(viewMenuBar2 ddstyle viewSettings model
|
(viewMenuBar2 viewSettings model
|
||||||
:: List.map (viewCustomField2 viewSettings model) (visibleFields model)
|
:: List.map (viewCustomField2 texts viewSettings model) (visibleFields model)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
viewMenuBar2 : DS.DropdownStyle -> ViewSettings -> Model -> Html Msg
|
viewMenuBar2 : ViewSettings -> Model -> Html Msg
|
||||||
viewMenuBar2 ddstyle viewSettings model =
|
viewMenuBar2 viewSettings model =
|
||||||
let
|
let
|
||||||
{ dropdown, selected } =
|
{ dropdown, selected } =
|
||||||
model.fieldSelect
|
model.fieldSelect
|
||||||
|
|
||||||
|
ddstyle =
|
||||||
|
viewSettings.style
|
||||||
|
|
||||||
ddstyleFlex =
|
ddstyleFlex =
|
||||||
{ ddstyle | root = ddstyle.root ++ " flex-grow" }
|
{ display = \f -> Maybe.withDefault f.name f.label
|
||||||
|
, icon = \_ -> Nothing
|
||||||
|
, style = { ddstyle | root = ddstyle.root ++ " flex-grow" }
|
||||||
|
}
|
||||||
in
|
in
|
||||||
div
|
div
|
||||||
[ classList
|
[ classList
|
||||||
@ -348,11 +352,11 @@ viewMenuBar2 ddstyle viewSettings model =
|
|||||||
(Comp.FixedDropdown.viewStyled2
|
(Comp.FixedDropdown.viewStyled2
|
||||||
ddstyleFlex
|
ddstyleFlex
|
||||||
False
|
False
|
||||||
(Maybe.map mkItem selected)
|
selected
|
||||||
dropdown
|
dropdown
|
||||||
)
|
)
|
||||||
:: (if viewSettings.showAddButton then
|
:: (if viewSettings.showAddButton then
|
||||||
[ addFieldLink2 "ml-1" model
|
[ addFieldLink2 viewSettings.createCustomFieldTitle "ml-1" model
|
||||||
]
|
]
|
||||||
|
|
||||||
else
|
else
|
||||||
@ -361,8 +365,8 @@ viewMenuBar2 ddstyle viewSettings model =
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
viewCustomField2 : ViewSettings -> Model -> CustomField -> Html Msg
|
viewCustomField2 : Texts -> ViewSettings -> Model -> CustomField -> Html Msg
|
||||||
viewCustomField2 viewSettings model field =
|
viewCustomField2 texts viewSettings model field =
|
||||||
let
|
let
|
||||||
visibleField =
|
visibleField =
|
||||||
Dict.get field.name model.visibleFields
|
Dict.get field.name model.visibleFields
|
||||||
@ -370,7 +374,8 @@ viewCustomField2 viewSettings model field =
|
|||||||
case visibleField of
|
case visibleField of
|
||||||
Just vf ->
|
Just vf ->
|
||||||
Html.map (CustomFieldInputMsg field)
|
Html.map (CustomFieldInputMsg field)
|
||||||
(Comp.CustomFieldInput.view2 "mt-2"
|
(Comp.CustomFieldInput.view2 texts.customFieldInput
|
||||||
|
"mt-2"
|
||||||
(viewSettings.fieldIcon vf.field)
|
(viewSettings.fieldIcon vf.field)
|
||||||
vf.inputModel
|
vf.inputModel
|
||||||
)
|
)
|
||||||
@ -379,8 +384,8 @@ viewCustomField2 viewSettings model field =
|
|||||||
span [] []
|
span [] []
|
||||||
|
|
||||||
|
|
||||||
addFieldLink2 : String -> Model -> Html Msg
|
addFieldLink2 : String -> String -> Model -> Html Msg
|
||||||
addFieldLink2 classes _ =
|
addFieldLink2 titleStr classes _ =
|
||||||
a
|
a
|
||||||
[ class classes
|
[ class classes
|
||||||
, class S.secondaryButton
|
, class S.secondaryButton
|
||||||
@ -388,7 +393,7 @@ addFieldLink2 classes _ =
|
|||||||
-- , class "absolute -right-12 top-0"
|
-- , class "absolute -right-12 top-0"
|
||||||
, href "#"
|
, href "#"
|
||||||
, onClick CreateNewField
|
, onClick CreateNewField
|
||||||
, title "Create a new custom field"
|
, title titleStr
|
||||||
]
|
]
|
||||||
[ i [ class "fa fa-plus" ] []
|
[ i [ class "fa fa-plus" ] []
|
||||||
]
|
]
|
||||||
|
@ -11,7 +11,7 @@ import Api.Model.CustomField exposing (CustomField)
|
|||||||
import Comp.Basic as B
|
import Comp.Basic as B
|
||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onClick)
|
import Messages.Comp.CustomFieldTable exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.Time
|
import Util.Time
|
||||||
|
|
||||||
@ -45,17 +45,17 @@ update msg model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : Model -> List CustomField -> Html Msg
|
view2 : Texts -> Model -> List CustomField -> Html Msg
|
||||||
view2 _ items =
|
view2 texts _ items =
|
||||||
div []
|
div []
|
||||||
[ table [ class S.tableMain ]
|
[ table [ class S.tableMain ]
|
||||||
[ thead []
|
[ thead []
|
||||||
[ tr []
|
[ tr []
|
||||||
[ th [] []
|
[ th [] []
|
||||||
, th [ class "text-left" ] [ text "Name/Label" ]
|
, th [ class "text-left" ] [ text texts.nameLabel ]
|
||||||
, th [ class "text-left" ] [ text "Format" ]
|
, th [ class "text-left" ] [ text texts.format ]
|
||||||
, th [ class "text-center hidden sm:table-cell" ] [ text "#Usage" ]
|
, th [ class "text-center hidden sm:table-cell" ] [ text texts.usageCount ]
|
||||||
, th [ class "text-center hidden sm:table-cell" ] [ text "Created" ]
|
, th [ class "text-center hidden sm:table-cell" ] [ text texts.basics.created ]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, tbody []
|
, tbody []
|
||||||
|
@ -47,6 +47,7 @@ import Html exposing (..)
|
|||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onClick)
|
import Html.Events exposing (onClick)
|
||||||
import Http
|
import Http
|
||||||
|
import Messages.Comp.DetailEdit exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.Http
|
import Util.Http
|
||||||
|
|
||||||
@ -639,10 +640,10 @@ update flags msg model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : List (Attribute Msg) -> UiSettings -> Model -> Html Msg
|
view2 : Texts -> List (Attribute Msg) -> UiSettings -> Model -> Html Msg
|
||||||
view2 attr settings model =
|
view2 texts attr settings model =
|
||||||
div attr
|
div attr
|
||||||
(viewIntern2 settings True model)
|
(viewIntern2 texts settings True model)
|
||||||
|
|
||||||
|
|
||||||
formHeading : String -> Model -> Html msg
|
formHeading : String -> Model -> Html msg
|
||||||
@ -668,8 +669,8 @@ formHeading classes model =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewModal2 : UiSettings -> Maybe Model -> Html Msg
|
viewModal2 : Texts -> UiSettings -> Maybe Model -> Html Msg
|
||||||
viewModal2 settings mm =
|
viewModal2 texts settings mm =
|
||||||
let
|
let
|
||||||
hidden =
|
hidden =
|
||||||
mm == Nothing
|
mm == Nothing
|
||||||
@ -710,7 +711,7 @@ viewModal2 settings mm =
|
|||||||
, div [ class "scrolling content" ]
|
, div [ class "scrolling content" ]
|
||||||
(case mm of
|
(case mm of
|
||||||
Just model ->
|
Just model ->
|
||||||
viewIntern2 settings False model
|
viewIntern2 texts settings False model
|
||||||
|
|
||||||
Nothing ->
|
Nothing ->
|
||||||
[]
|
[]
|
||||||
@ -718,7 +719,7 @@ viewModal2 settings mm =
|
|||||||
, div [ class "flex flex-row space-x-2" ]
|
, div [ class "flex flex-row space-x-2" ]
|
||||||
(case mm of
|
(case mm of
|
||||||
Just model ->
|
Just model ->
|
||||||
viewButtons2 model
|
viewButtons2 texts model
|
||||||
|
|
||||||
Nothing ->
|
Nothing ->
|
||||||
[]
|
[]
|
||||||
@ -727,10 +728,10 @@ viewModal2 settings mm =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewButtons2 : Model -> List (Html Msg)
|
viewButtons2 : Texts -> Model -> List (Html Msg)
|
||||||
viewButtons2 model =
|
viewButtons2 texts model =
|
||||||
[ B.primaryButton
|
[ B.primaryButton
|
||||||
{ label = "Submit"
|
{ label = texts.basics.submit
|
||||||
, icon =
|
, icon =
|
||||||
if model.submitting || model.loading then
|
if model.submitting || model.loading then
|
||||||
"fa fa-circle-notch animate-spin"
|
"fa fa-circle-notch animate-spin"
|
||||||
@ -742,7 +743,7 @@ viewButtons2 model =
|
|||||||
, attrs = [ href "#" ]
|
, attrs = [ href "#" ]
|
||||||
}
|
}
|
||||||
, B.secondaryButton
|
, B.secondaryButton
|
||||||
{ label = "Cancel"
|
{ label = texts.basics.cancel
|
||||||
, handler = onClick Cancel
|
, handler = onClick Cancel
|
||||||
, disabled = False
|
, disabled = False
|
||||||
, icon = "fa fa-times"
|
, icon = "fa fa-times"
|
||||||
@ -751,8 +752,8 @@ viewButtons2 model =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewIntern2 : UiSettings -> Bool -> Model -> List (Html Msg)
|
viewIntern2 : Texts -> UiSettings -> Bool -> Model -> List (Html Msg)
|
||||||
viewIntern2 settings withButtons model =
|
viewIntern2 texts settings withButtons model =
|
||||||
[ div
|
[ div
|
||||||
[ classList
|
[ classList
|
||||||
[ ( S.errorMessage, Maybe.map .success model.result == Just False )
|
[ ( S.errorMessage, Maybe.map .success model.result == Just False )
|
||||||
@ -766,24 +767,25 @@ viewIntern2 settings withButtons model =
|
|||||||
]
|
]
|
||||||
, case model.form of
|
, case model.form of
|
||||||
TM tm ->
|
TM tm ->
|
||||||
Html.map TagMsg (Comp.TagForm.view2 tm)
|
Html.map TagMsg (Comp.TagForm.view2 texts.tagForm tm)
|
||||||
|
|
||||||
PMR pm ->
|
PMR pm ->
|
||||||
Html.map PersonMsg (Comp.PersonForm.view2 True settings pm)
|
Html.map PersonMsg (Comp.PersonForm.view2 texts.personForm True settings pm)
|
||||||
|
|
||||||
PMC pm ->
|
PMC pm ->
|
||||||
Html.map PersonMsg (Comp.PersonForm.view2 True settings pm)
|
Html.map PersonMsg (Comp.PersonForm.view2 texts.personForm True settings pm)
|
||||||
|
|
||||||
OM om ->
|
OM om ->
|
||||||
Html.map OrgMsg (Comp.OrgForm.view2 True settings om)
|
Html.map OrgMsg (Comp.OrgForm.view2 texts.orgForm True settings om)
|
||||||
|
|
||||||
EM em ->
|
EM em ->
|
||||||
Html.map EquipMsg (Comp.EquipmentForm.view2 em)
|
Html.map EquipMsg (Comp.EquipmentForm.view2 texts.equipmentForm em)
|
||||||
|
|
||||||
CFM fm ->
|
CFM fm ->
|
||||||
div []
|
div []
|
||||||
(List.map (Html.map CustomFieldMsg)
|
(List.map (Html.map CustomFieldMsg)
|
||||||
(Comp.CustomFieldForm.view2
|
(Comp.CustomFieldForm.view2
|
||||||
|
texts.customFieldForm
|
||||||
{ classes = ""
|
{ classes = ""
|
||||||
, showControls = False
|
, showControls = False
|
||||||
}
|
}
|
||||||
@ -793,7 +795,7 @@ viewIntern2 settings withButtons model =
|
|||||||
]
|
]
|
||||||
++ (if withButtons then
|
++ (if withButtons then
|
||||||
[ div [ class "flex flex-row space-x-2" ]
|
[ div [ class "flex flex-row space-x-2" ]
|
||||||
(viewButtons2 model)
|
(viewButtons2 texts model)
|
||||||
]
|
]
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -2,6 +2,7 @@ module Comp.Dropdown exposing
|
|||||||
( Model
|
( Model
|
||||||
, Msg(..)
|
, Msg(..)
|
||||||
, Option
|
, Option
|
||||||
|
, ViewSettings
|
||||||
, getSelected
|
, getSelected
|
||||||
, isDropdownChangeMsg
|
, isDropdownChangeMsg
|
||||||
, makeModel
|
, makeModel
|
||||||
@ -10,16 +11,13 @@ module Comp.Dropdown exposing
|
|||||||
, makeSingleList
|
, makeSingleList
|
||||||
, mkOption
|
, mkOption
|
||||||
, notSelected
|
, notSelected
|
||||||
, orgDropdown
|
, orgFormViewSettings
|
||||||
, setMkOption
|
, setMkOption
|
||||||
, update
|
, update
|
||||||
, view2
|
, view2
|
||||||
, viewSingle2
|
, viewSingle2
|
||||||
)
|
)
|
||||||
|
|
||||||
{-| This needs to be rewritten from scratch!
|
|
||||||
-}
|
|
||||||
|
|
||||||
import Api.Model.IdName exposing (IdName)
|
import Api.Model.IdName exposing (IdName)
|
||||||
import Data.DropdownStyle as DS
|
import Data.DropdownStyle as DS
|
||||||
import Data.UiSettings exposing (UiSettings)
|
import Data.UiSettings exposing (UiSettings)
|
||||||
@ -31,32 +29,8 @@ import Util.Html exposing (onKeyUp)
|
|||||||
import Util.List
|
import Util.List
|
||||||
|
|
||||||
|
|
||||||
orgDropdown : Model IdName
|
|
||||||
orgDropdown =
|
|
||||||
makeModel
|
|
||||||
{ multiple = False
|
|
||||||
, searchable = \n -> n > 0
|
|
||||||
, makeOption = \e -> { value = e.id, text = e.name, additional = "" }
|
|
||||||
, labelColor = \_ -> \_ -> ""
|
|
||||||
, placeholder = "Choose an organization"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type alias Option =
|
|
||||||
{ value : String
|
|
||||||
, text : String
|
|
||||||
, additional : String
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
mkOption : String -> String -> Option
|
|
||||||
mkOption value text =
|
|
||||||
Option value text ""
|
|
||||||
|
|
||||||
|
|
||||||
type alias Item a =
|
type alias Item a =
|
||||||
{ value : a
|
{ value : a
|
||||||
, option : Option
|
|
||||||
, visible : Bool
|
, visible : Bool
|
||||||
, selected : Bool
|
, selected : Bool
|
||||||
, active : Bool
|
, active : Bool
|
||||||
@ -66,7 +40,6 @@ type alias Item a =
|
|||||||
makeItem : Model a -> a -> Item a
|
makeItem : Model a -> a -> Item a
|
||||||
makeItem model val =
|
makeItem model val =
|
||||||
{ value = val
|
{ value = val
|
||||||
, option = model.makeOption val
|
|
||||||
, visible = True
|
, visible = True
|
||||||
, selected =
|
, selected =
|
||||||
List.any (\i -> i.value == val) model.selected
|
List.any (\i -> i.value == val) model.selected
|
||||||
@ -78,26 +51,15 @@ type alias Model a =
|
|||||||
{ multiple : Bool
|
{ multiple : Bool
|
||||||
, selected : List (Item a)
|
, selected : List (Item a)
|
||||||
, available : List (Item a)
|
, available : List (Item a)
|
||||||
, makeOption : a -> Option
|
|
||||||
, menuOpen : Bool
|
, menuOpen : Bool
|
||||||
, filterString : String
|
, filterString : String
|
||||||
, labelColor : a -> UiSettings -> String
|
|
||||||
, searchable : Int -> Bool
|
, searchable : Int -> Bool
|
||||||
, placeholder : String
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
setMkOption : (a -> Option) -> Model a -> Model a
|
|
||||||
setMkOption mkopt model =
|
|
||||||
{ model | makeOption = mkopt }
|
|
||||||
|
|
||||||
|
|
||||||
makeModel :
|
makeModel :
|
||||||
{ multiple : Bool
|
{ multiple : Bool
|
||||||
, searchable : Int -> Bool
|
, searchable : Int -> Bool
|
||||||
, makeOption : a -> Option
|
|
||||||
, labelColor : a -> UiSettings -> String
|
|
||||||
, placeholder : String
|
|
||||||
}
|
}
|
||||||
-> Model a
|
-> Model a
|
||||||
makeModel input =
|
makeModel input =
|
||||||
@ -105,45 +67,28 @@ makeModel input =
|
|||||||
, searchable = input.searchable
|
, searchable = input.searchable
|
||||||
, selected = []
|
, selected = []
|
||||||
, available = []
|
, available = []
|
||||||
, makeOption = input.makeOption
|
|
||||||
, menuOpen = False
|
, menuOpen = False
|
||||||
, filterString = ""
|
, filterString = ""
|
||||||
, labelColor = input.labelColor
|
|
||||||
, placeholder = input.placeholder
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
makeSingle :
|
makeSingle : Model a
|
||||||
{ makeOption : a -> Option
|
makeSingle =
|
||||||
, placeholder : String
|
|
||||||
}
|
|
||||||
-> Model a
|
|
||||||
makeSingle opts =
|
|
||||||
makeModel
|
makeModel
|
||||||
{ multiple = False
|
{ multiple = False
|
||||||
, searchable = \n -> n > 0
|
, searchable = \n -> n > 0
|
||||||
, makeOption = opts.makeOption
|
|
||||||
, labelColor = \_ -> \_ -> ""
|
|
||||||
, placeholder =
|
|
||||||
if opts.placeholder == "" then
|
|
||||||
"Select…"
|
|
||||||
|
|
||||||
else
|
|
||||||
opts.placeholder
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
makeSingleList :
|
makeSingleList :
|
||||||
{ makeOption : a -> Option
|
{ options : List a
|
||||||
, placeholder : String
|
|
||||||
, options : List a
|
|
||||||
, selected : Maybe a
|
, selected : Maybe a
|
||||||
}
|
}
|
||||||
-> Model a
|
-> Model a
|
||||||
makeSingleList opts =
|
makeSingleList opts =
|
||||||
let
|
let
|
||||||
m =
|
m =
|
||||||
makeSingle { makeOption = opts.makeOption, placeholder = opts.placeholder }
|
makeSingle
|
||||||
|
|
||||||
m2 =
|
m2 =
|
||||||
{ m | available = List.map (makeItem m) opts.options }
|
{ m | available = List.map (makeItem m) opts.options }
|
||||||
@ -156,18 +101,11 @@ makeSingleList opts =
|
|||||||
m3
|
m3
|
||||||
|
|
||||||
|
|
||||||
makeMultiple :
|
makeMultiple : Model a
|
||||||
{ makeOption : a -> Option
|
makeMultiple =
|
||||||
, labelColor : a -> UiSettings -> String
|
|
||||||
}
|
|
||||||
-> Model a
|
|
||||||
makeMultiple opts =
|
|
||||||
makeModel
|
makeModel
|
||||||
{ multiple = True
|
{ multiple = True
|
||||||
, searchable = \n -> n > 0
|
, searchable = \n -> n > 0
|
||||||
, makeOption = opts.makeOption
|
|
||||||
, labelColor = opts.labelColor
|
|
||||||
, placeholder = ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -186,9 +124,8 @@ type Msg a
|
|||||||
| SetSelection (List a)
|
| SetSelection (List a)
|
||||||
| ToggleMenu
|
| ToggleMenu
|
||||||
| AddItem (Item a)
|
| AddItem (Item a)
|
||||||
| RemoveItem (Item a)
|
|
||||||
| RemoveItem2 (Item a)
|
| RemoveItem2 (Item a)
|
||||||
| Filter String
|
| Filter (a -> String) String
|
||||||
| ShowMenu Bool
|
| ShowMenu Bool
|
||||||
| KeyPress Int
|
| KeyPress Int
|
||||||
|
|
||||||
@ -215,17 +152,17 @@ deselectItem : Model a -> Item a -> Model a
|
|||||||
deselectItem model item =
|
deselectItem model item =
|
||||||
let
|
let
|
||||||
value =
|
value =
|
||||||
item.option.value
|
item.value
|
||||||
|
|
||||||
sel =
|
sel =
|
||||||
if model.multiple then
|
if model.multiple then
|
||||||
List.filter (\e -> e.option.value /= value) model.selected
|
List.filter (\e -> e.value /= value) model.selected
|
||||||
|
|
||||||
else
|
else
|
||||||
[]
|
[]
|
||||||
|
|
||||||
show e =
|
show e =
|
||||||
if e.option.value == value then
|
if e.value == value then
|
||||||
{ e | selected = False }
|
{ e | selected = False }
|
||||||
|
|
||||||
else
|
else
|
||||||
@ -241,7 +178,7 @@ selectItem : Model a -> Item a -> Model a
|
|||||||
selectItem model item =
|
selectItem model item =
|
||||||
let
|
let
|
||||||
value =
|
value =
|
||||||
item.option.value
|
item.value
|
||||||
|
|
||||||
sel =
|
sel =
|
||||||
if model.multiple then
|
if model.multiple then
|
||||||
@ -251,7 +188,7 @@ selectItem model item =
|
|||||||
[ item ]
|
[ item ]
|
||||||
|
|
||||||
hide e =
|
hide e =
|
||||||
if e.option.value == value then
|
if e.value == value then
|
||||||
{ e | selected = True }
|
{ e | selected = True }
|
||||||
|
|
||||||
else if model.multiple then
|
else if model.multiple then
|
||||||
@ -266,13 +203,13 @@ selectItem model item =
|
|||||||
{ model | selected = sel, available = avail }
|
{ model | selected = sel, available = avail }
|
||||||
|
|
||||||
|
|
||||||
filterOptions : String -> List (Item a) -> List (Item a)
|
filterOptions : String -> (a -> String) -> List (Item a) -> List (Item a)
|
||||||
filterOptions str list =
|
filterOptions str mkText list =
|
||||||
List.map (\e -> { e | visible = Simple.Fuzzy.match str e.option.text, active = False }) list
|
List.map (\e -> { e | visible = Simple.Fuzzy.match str (mkText e.value), active = False }) list
|
||||||
|
|
||||||
|
|
||||||
applyFilter : String -> Model a -> Model a
|
applyFilter : String -> (a -> String) -> Model a -> Model a
|
||||||
applyFilter str model =
|
applyFilter str mkText model =
|
||||||
let
|
let
|
||||||
selected =
|
selected =
|
||||||
if str /= "" && not model.multiple then
|
if str /= "" && not model.multiple then
|
||||||
@ -281,7 +218,12 @@ applyFilter str model =
|
|||||||
else
|
else
|
||||||
model.selected
|
model.selected
|
||||||
in
|
in
|
||||||
{ model | filterString = str, available = filterOptions str model.available, selected = selected }
|
{ model | filterString = str, available = filterOptions str mkText model.available, selected = selected }
|
||||||
|
|
||||||
|
|
||||||
|
clearFilter : Model a -> Model a
|
||||||
|
clearFilter model =
|
||||||
|
{ model | filterString = "" }
|
||||||
|
|
||||||
|
|
||||||
makeNextActive : (Int -> Int) -> Model a -> Model a
|
makeNextActive : (Int -> Int) -> Model a -> Model a
|
||||||
@ -299,7 +241,7 @@ makeNextActive nextEl model =
|
|||||||
|> Maybe.andThen (Util.List.get opts)
|
|> Maybe.andThen (Util.List.get opts)
|
||||||
|
|
||||||
merge item1 item2 =
|
merge item1 item2 =
|
||||||
{ item2 | active = item1.option.value == item2.option.value }
|
{ item2 | active = item1.value == item2.value }
|
||||||
|
|
||||||
updateModel item =
|
updateModel item =
|
||||||
{ model | available = List.map (merge item) model.available, menuOpen = True }
|
{ model | available = List.map (merge item) model.available, menuOpen = True }
|
||||||
@ -325,7 +267,7 @@ selectActive model =
|
|||||||
in
|
in
|
||||||
case current of
|
case current of
|
||||||
Just item ->
|
Just item ->
|
||||||
selectItem model item |> applyFilter ""
|
selectItem model item |> clearFilter
|
||||||
|
|
||||||
Nothing ->
|
Nothing ->
|
||||||
model
|
model
|
||||||
@ -337,9 +279,6 @@ isDropdownChangeMsg cm =
|
|||||||
AddItem _ ->
|
AddItem _ ->
|
||||||
True
|
True
|
||||||
|
|
||||||
RemoveItem _ ->
|
|
||||||
True
|
|
||||||
|
|
||||||
RemoveItem2 _ ->
|
RemoveItem2 _ ->
|
||||||
True
|
True
|
||||||
|
|
||||||
@ -375,34 +314,23 @@ update msg model =
|
|||||||
AddItem e ->
|
AddItem e ->
|
||||||
let
|
let
|
||||||
m =
|
m =
|
||||||
selectItem model e |> applyFilter ""
|
selectItem model e |> clearFilter
|
||||||
in
|
in
|
||||||
( { m | menuOpen = False }, Cmd.none )
|
( { m | menuOpen = False }, Cmd.none )
|
||||||
|
|
||||||
RemoveItem e ->
|
|
||||||
let
|
|
||||||
m =
|
|
||||||
deselectItem model e |> applyFilter ""
|
|
||||||
in
|
|
||||||
( -- Setting to True, because parent click sets it to False… ugly
|
|
||||||
{ m | menuOpen = True }
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
RemoveItem2 e ->
|
RemoveItem2 e ->
|
||||||
let
|
let
|
||||||
m =
|
m =
|
||||||
deselectItem model e |> applyFilter ""
|
deselectItem model e |> clearFilter
|
||||||
in
|
in
|
||||||
( -- Hack above only needed with semanticui
|
( m
|
||||||
m
|
|
||||||
, Cmd.none
|
, Cmd.none
|
||||||
)
|
)
|
||||||
|
|
||||||
Filter str ->
|
Filter f str ->
|
||||||
let
|
let
|
||||||
m =
|
m =
|
||||||
applyFilter str model
|
applyFilter str f model
|
||||||
in
|
in
|
||||||
( { m | menuOpen = True }, Cmd.none )
|
( { m | menuOpen = True }, Cmd.none )
|
||||||
|
|
||||||
@ -438,7 +366,7 @@ update msg model =
|
|||||||
[ e ] ->
|
[ e ] ->
|
||||||
let
|
let
|
||||||
( m_, c_ ) =
|
( m_, c_ ) =
|
||||||
update (RemoveItem e) model
|
update (RemoveItem2 e) model
|
||||||
in
|
in
|
||||||
( { m_ | menuOpen = False }, c_ )
|
( { m_ | menuOpen = False }, c_ )
|
||||||
|
|
||||||
@ -463,32 +391,65 @@ update msg model =
|
|||||||
-- View2
|
-- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : DS.DropdownStyle -> UiSettings -> Model a -> Html (Msg a)
|
type alias Option =
|
||||||
view2 style settings model =
|
{ text : String
|
||||||
|
, additional : String
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mkOption : String -> Option
|
||||||
|
mkOption text =
|
||||||
|
Option text ""
|
||||||
|
|
||||||
|
|
||||||
|
type alias ViewSettings a =
|
||||||
|
{ makeOption : a -> Option
|
||||||
|
, placeholder : String
|
||||||
|
, labelColor : a -> UiSettings -> String
|
||||||
|
, style : DS.DropdownStyle
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
orgFormViewSettings : String -> DS.DropdownStyle -> ViewSettings IdName
|
||||||
|
orgFormViewSettings placeholder ds =
|
||||||
|
{ makeOption = \e -> { text = e.name, additional = "" }
|
||||||
|
, labelColor = \_ -> \_ -> ""
|
||||||
|
, placeholder = placeholder
|
||||||
|
, style = ds
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
setMkOption : (a -> Option) -> ViewSettings a -> ViewSettings a
|
||||||
|
setMkOption mkopt model =
|
||||||
|
{ model | makeOption = mkopt }
|
||||||
|
|
||||||
|
|
||||||
|
view2 : ViewSettings a -> UiSettings -> Model a -> Html (Msg a)
|
||||||
|
view2 cfg settings model =
|
||||||
if model.multiple then
|
if model.multiple then
|
||||||
viewMultiple2 style settings model
|
viewMultiple2 cfg settings model
|
||||||
|
|
||||||
else
|
else
|
||||||
viewSingle2 style model
|
viewSingle2 cfg model
|
||||||
|
|
||||||
|
|
||||||
viewSingle2 : DS.DropdownStyle -> Model a -> Html (Msg a)
|
viewSingle2 : ViewSettings a -> Model a -> Html (Msg a)
|
||||||
viewSingle2 style model =
|
viewSingle2 cfg model =
|
||||||
let
|
let
|
||||||
renderItem item =
|
renderItem item =
|
||||||
a
|
a
|
||||||
[ href "#"
|
[ href "#"
|
||||||
, class style.item
|
, class cfg.style.item
|
||||||
, classList
|
, classList
|
||||||
[ ( style.itemActive, item.active )
|
[ ( cfg.style.itemActive, item.active )
|
||||||
, ( "font-semibold", item.selected )
|
, ( "font-semibold", item.selected )
|
||||||
]
|
]
|
||||||
, onClick (AddItem item)
|
, onClick (AddItem item)
|
||||||
, onKeyUp KeyPress
|
, onKeyUp KeyPress
|
||||||
]
|
]
|
||||||
[ text item.option.text
|
[ text <| (.value >> cfg.makeOption >> .text) item
|
||||||
, span [ class "text-gray-400 float-right" ]
|
, span [ class "text-gray-400 float-right" ]
|
||||||
[ text item.option.additional
|
[ text <| (.value >> cfg.makeOption >> .additional) item
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -500,7 +461,7 @@ viewSingle2 style model =
|
|||||||
, onKeyUp KeyPress
|
, onKeyUp KeyPress
|
||||||
]
|
]
|
||||||
[ div
|
[ div
|
||||||
[ class style.link
|
[ class cfg.style.link
|
||||||
]
|
]
|
||||||
[ a
|
[ a
|
||||||
[ class "flex-grow"
|
[ class "flex-grow"
|
||||||
@ -514,8 +475,8 @@ viewSingle2 style model =
|
|||||||
, onClick ToggleMenu
|
, onClick ToggleMenu
|
||||||
, href "#"
|
, href "#"
|
||||||
]
|
]
|
||||||
[ Maybe.map (.option >> .text) sel
|
[ Maybe.map (.value >> cfg.makeOption >> .text) sel
|
||||||
|> Maybe.withDefault model.placeholder
|
|> Maybe.withDefault cfg.placeholder
|
||||||
|> text
|
|> text
|
||||||
]
|
]
|
||||||
, a
|
, a
|
||||||
@ -532,11 +493,11 @@ viewSingle2 style model =
|
|||||||
]
|
]
|
||||||
, input
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
, placeholder model.placeholder
|
, placeholder cfg.placeholder
|
||||||
, onInput Filter
|
, onInput (Filter (cfg.makeOption >> .text))
|
||||||
, value model.filterString
|
, value model.filterString
|
||||||
, class "inline-block border-0 px-0 w-full py-0 focus:ring-0 "
|
, class "inline-block border-0 px-0 w-full py-0 focus:ring-0 "
|
||||||
, class style.input
|
, class cfg.style.input
|
||||||
, classList [ ( "hidden", not (model.menuOpen && isSearchable model) ) ]
|
, classList [ ( "hidden", not (model.menuOpen && isSearchable model) ) ]
|
||||||
]
|
]
|
||||||
[]
|
[]
|
||||||
@ -550,43 +511,43 @@ viewSingle2 style model =
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div
|
, div
|
||||||
[ class style.menu
|
[ class cfg.style.menu
|
||||||
, classList [ ( "hidden", not model.menuOpen ) ]
|
, classList [ ( "hidden", not model.menuOpen ) ]
|
||||||
]
|
]
|
||||||
(getOptions model |> List.map renderItem)
|
(getOptions model |> List.map renderItem)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewMultiple2 : DS.DropdownStyle -> UiSettings -> Model a -> Html (Msg a)
|
viewMultiple2 : ViewSettings a -> UiSettings -> Model a -> Html (Msg a)
|
||||||
viewMultiple2 style settings model =
|
viewMultiple2 cfg settings model =
|
||||||
let
|
let
|
||||||
renderItem item =
|
renderItem item =
|
||||||
a
|
a
|
||||||
[ href "#"
|
[ href "#"
|
||||||
, class style.item
|
, class cfg.style.item
|
||||||
, classList
|
, classList
|
||||||
[ ( style.itemActive, item.active )
|
[ ( cfg.style.itemActive, item.active )
|
||||||
, ( "font-semibold", item.selected )
|
, ( "font-semibold", item.selected )
|
||||||
]
|
]
|
||||||
, onClick (AddItem item)
|
, onClick (AddItem item)
|
||||||
, onKeyUp KeyPress
|
, onKeyUp KeyPress
|
||||||
]
|
]
|
||||||
[ text item.option.text
|
[ text <| (.value >> cfg.makeOption >> .text) item
|
||||||
, span [ class "text-gray-400 float-right" ]
|
, span [ class "text-gray-400 float-right" ]
|
||||||
[ text item.option.additional
|
[ text <| (.value >> cfg.makeOption >> .additional) item
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
renderSelectMultiple : Item a -> Html (Msg a)
|
renderSelectMultiple : Item a -> Html (Msg a)
|
||||||
renderSelectMultiple item =
|
renderSelectMultiple item =
|
||||||
a
|
a
|
||||||
[ class (model.labelColor item.value settings)
|
[ class (cfg.labelColor item.value settings)
|
||||||
, class "label font-medium inline-flex relative items-center hover:shadow-md mt-1 mr-1"
|
, class "label font-medium inline-flex relative items-center hover:shadow-md mt-1 mr-1"
|
||||||
, onClick (RemoveItem item)
|
, onClick (RemoveItem2 item)
|
||||||
, href "#"
|
, href "#"
|
||||||
]
|
]
|
||||||
[ span [ class "pl-4" ]
|
[ span [ class "pl-4" ]
|
||||||
[ text item.option.text
|
[ text <| (.value >> cfg.makeOption >> .text) item
|
||||||
]
|
]
|
||||||
, span [ class "opacity-75 absolute left-2 my-auto" ]
|
, span [ class "opacity-75 absolute left-2 my-auto" ]
|
||||||
[ i [ class "fa fa-times" ] []
|
[ i [ class "fa fa-times" ] []
|
||||||
@ -598,7 +559,7 @@ viewMultiple2 style settings model =
|
|||||||
, onKeyUp KeyPress
|
, onKeyUp KeyPress
|
||||||
]
|
]
|
||||||
[ div
|
[ div
|
||||||
[ class style.link
|
[ class cfg.style.link
|
||||||
, class "flex inline-flex flex-wrap items-center"
|
, class "flex inline-flex flex-wrap items-center"
|
||||||
]
|
]
|
||||||
[ div
|
[ div
|
||||||
@ -609,10 +570,10 @@ viewMultiple2 style settings model =
|
|||||||
, input
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
, placeholder "Search…"
|
, placeholder "Search…"
|
||||||
, onInput Filter
|
, onInput (Filter (cfg.makeOption >> .text))
|
||||||
, value model.filterString
|
, value model.filterString
|
||||||
, class "inline-flex w-16 border-0 px-0 focus:ring-0 h-6"
|
, class "inline-flex w-16 border-0 px-0 focus:ring-0 h-6"
|
||||||
, class style.input
|
, class cfg.style.input
|
||||||
]
|
]
|
||||||
[]
|
[]
|
||||||
, a
|
, a
|
||||||
@ -629,7 +590,7 @@ viewMultiple2 style settings model =
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div
|
, div
|
||||||
[ class style.menu
|
[ class cfg.style.menu
|
||||||
, classList [ ( "hidden", not model.menuOpen ) ]
|
, classList [ ( "hidden", not model.menuOpen ) ]
|
||||||
]
|
]
|
||||||
(getOptions model |> List.map renderItem)
|
(getOptions model |> List.map renderItem)
|
||||||
|
@ -18,6 +18,7 @@ import File.Select
|
|||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (..)
|
import Html.Events exposing (..)
|
||||||
|
import Messages.Comp.Dropzone exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.Html exposing (onDragEnter, onDragLeave, onDragOver, onDropFiles)
|
import Util.Html exposing (onDragEnter, onDragLeave, onDragOver, onDropFiles)
|
||||||
|
|
||||||
@ -124,8 +125,8 @@ filterMime model files =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : Model -> Html Msg
|
view2 : Texts -> Model -> Html Msg
|
||||||
view2 model =
|
view2 texts model =
|
||||||
div
|
div
|
||||||
[ classList
|
[ classList
|
||||||
[ ( "bg-opacity-100 bg-blue-100 dark:bg-lightblue-800", model.state.hover )
|
[ ( "bg-opacity-100 bg-blue-100 dark:bg-lightblue-800", model.state.hover )
|
||||||
@ -144,24 +145,23 @@ view2 model =
|
|||||||
]
|
]
|
||||||
[ i [ class "fa fa-mouse-pointer" ] []
|
[ i [ class "fa fa-mouse-pointer" ] []
|
||||||
, div [ class "ml-3" ]
|
, div [ class "ml-3" ]
|
||||||
[ text "Drop files here"
|
[ text texts.dropFilesHere
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, B.horizontalDivider
|
, B.horizontalDivider
|
||||||
{ label = "Or"
|
{ label = texts.or
|
||||||
, topCss = "w-2/3 mb-4 hidden md:inline-flex"
|
, topCss = "w-2/3 mb-4 hidden md:inline-flex"
|
||||||
, labelCss = "px-4 bg-gray-200 bg-opacity-50"
|
, labelCss = "px-4 bg-gray-200 bg-opacity-50"
|
||||||
, lineColor = "bg-gray-300 dark:bg-bluegray-600"
|
, lineColor = "bg-gray-300 dark:bg-bluegray-600"
|
||||||
}
|
}
|
||||||
, B.primaryBasicButton
|
, B.primaryBasicButton
|
||||||
{ label = "Select ..."
|
{ label = texts.select
|
||||||
, icon = "fa fa-folder-open font-thin"
|
, icon = "fa fa-folder-open font-thin"
|
||||||
, handler = onClick PickFiles
|
, handler = onClick PickFiles
|
||||||
, attrs = [ href "#" ]
|
, attrs = [ href "#" ]
|
||||||
, disabled = not model.state.active
|
, disabled = not model.state.active
|
||||||
}
|
}
|
||||||
, div [ class "text-center opacity-75 text-sm mt-4" ]
|
, div [ class "text-center opacity-75 text-sm mt-4" ]
|
||||||
[ text "Choose document files (pdf, docx, txt, html, …). "
|
[ text texts.selectInfo
|
||||||
, text "Archives (zip and eml) are extracted."
|
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
module Comp.EmailInput exposing
|
module Comp.EmailInput exposing
|
||||||
( Model
|
( Model
|
||||||
, Msg
|
, Msg
|
||||||
|
, ViewSettings
|
||||||
, init
|
, init
|
||||||
, update
|
, update
|
||||||
, view2
|
, view2
|
||||||
@ -137,10 +138,16 @@ update flags current msg model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : DS.DropdownStyle -> List String -> Model -> Html Msg
|
type alias ViewSettings =
|
||||||
view2 style values model =
|
{ placeholder : String
|
||||||
|
, style : DS.DropdownStyle
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
view2 : ViewSettings -> List String -> Model -> Html Msg
|
||||||
|
view2 cfg values model =
|
||||||
div [ class "text-sm flex-row space-x-2 relative" ]
|
div [ class "text-sm flex-row space-x-2 relative" ]
|
||||||
[ div [ class style.link ]
|
[ div [ class cfg.style.link ]
|
||||||
[ div
|
[ div
|
||||||
[ class "flex flex-row space-x-2 mr-2"
|
[ class "flex flex-row space-x-2 mr-2"
|
||||||
, classList [ ( "hidden", List.isEmpty values ) ]
|
, classList [ ( "hidden", List.isEmpty values ) ]
|
||||||
@ -149,7 +156,7 @@ view2 style values model =
|
|||||||
, input
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
, value model.input
|
, value model.input
|
||||||
, placeholder "Recipients…"
|
, placeholder cfg.placeholder
|
||||||
, onKeyUp KeyPress
|
, onKeyUp KeyPress
|
||||||
, onInput SetInput
|
, onInput SetInput
|
||||||
, class "inline-flex w-24 border-0 px-0 focus:ring-0 h-6 text-sm"
|
, class "inline-flex w-24 border-0 px-0 focus:ring-0 h-6 text-sm"
|
||||||
@ -157,7 +164,7 @@ view2 style values model =
|
|||||||
]
|
]
|
||||||
[]
|
[]
|
||||||
]
|
]
|
||||||
, renderMenu2 style model
|
, renderMenu2 cfg.style model
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ import Data.UiSettings exposing (UiSettings)
|
|||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onInput)
|
import Html.Events exposing (onInput)
|
||||||
|
import Messages.Comp.EmailSettingsForm exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.Maybe
|
import Util.Maybe
|
||||||
|
|
||||||
@ -46,7 +47,7 @@ emptyModel =
|
|||||||
{ settings = Api.Model.EmailSettings.empty
|
{ settings = Api.Model.EmailSettings.empty
|
||||||
, name = ""
|
, name = ""
|
||||||
, host = ""
|
, host = ""
|
||||||
, portField = Comp.IntField.init (Just 0) Nothing True "SMTP Port"
|
, portField = Comp.IntField.init (Just 0) Nothing True
|
||||||
, portNum = Nothing
|
, portNum = Nothing
|
||||||
, user = Nothing
|
, user = Nothing
|
||||||
, passField = Comp.PasswordInput.init
|
, passField = Comp.PasswordInput.init
|
||||||
@ -55,14 +56,7 @@ emptyModel =
|
|||||||
, replyTo = Nothing
|
, replyTo = Nothing
|
||||||
, sslType =
|
, sslType =
|
||||||
Comp.Dropdown.makeSingleList
|
Comp.Dropdown.makeSingleList
|
||||||
{ makeOption =
|
{ options = Data.SSLType.all
|
||||||
\s ->
|
|
||||||
{ value = Data.SSLType.toString s
|
|
||||||
, text = Data.SSLType.label s
|
|
||||||
, additional = ""
|
|
||||||
}
|
|
||||||
, placeholder = ""
|
|
||||||
, options = Data.SSLType.all
|
|
||||||
, selected = Just Data.SSLType.None
|
, selected = Just Data.SSLType.None
|
||||||
}
|
}
|
||||||
, ignoreCertificates = False
|
, ignoreCertificates = False
|
||||||
@ -74,7 +68,7 @@ init ems =
|
|||||||
{ settings = ems
|
{ settings = ems
|
||||||
, name = ems.name
|
, name = ems.name
|
||||||
, host = ems.smtpHost
|
, host = ems.smtpHost
|
||||||
, portField = Comp.IntField.init (Just 0) Nothing True "SMTP Port"
|
, portField = Comp.IntField.init (Just 0) Nothing True
|
||||||
, portNum = ems.smtpPort
|
, portNum = ems.smtpPort
|
||||||
, user = ems.smtpUser
|
, user = ems.smtpUser
|
||||||
, passField = Comp.PasswordInput.init
|
, passField = Comp.PasswordInput.init
|
||||||
@ -83,14 +77,7 @@ init ems =
|
|||||||
, replyTo = ems.replyTo
|
, replyTo = ems.replyTo
|
||||||
, sslType =
|
, sslType =
|
||||||
Comp.Dropdown.makeSingleList
|
Comp.Dropdown.makeSingleList
|
||||||
{ makeOption =
|
{ options = Data.SSLType.all
|
||||||
\s ->
|
|
||||||
{ value = Data.SSLType.toString s
|
|
||||||
, text = Data.SSLType.label s
|
|
||||||
, additional = ""
|
|
||||||
}
|
|
||||||
, placeholder = ""
|
|
||||||
, options = Data.SSLType.all
|
|
||||||
, selected =
|
, selected =
|
||||||
Data.SSLType.fromString ems.sslType
|
Data.SSLType.fromString ems.sslType
|
||||||
|> Maybe.withDefault Data.SSLType.None
|
|> Maybe.withDefault Data.SSLType.None
|
||||||
@ -184,21 +171,33 @@ update msg model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : UiSettings -> Model -> Html Msg
|
view2 : Texts -> UiSettings -> Model -> Html Msg
|
||||||
view2 settings model =
|
view2 texts settings model =
|
||||||
|
let
|
||||||
|
sslCfg =
|
||||||
|
{ makeOption =
|
||||||
|
\s ->
|
||||||
|
{ text = texts.sslTypeLabel s
|
||||||
|
, additional = ""
|
||||||
|
}
|
||||||
|
, placeholder = ""
|
||||||
|
, labelColor = \_ -> \_ -> ""
|
||||||
|
, style = DS.mainStyle
|
||||||
|
}
|
||||||
|
in
|
||||||
div [ class "grid grid-cols-4 gap-y-4 gap-x-2" ]
|
div [ class "grid grid-cols-4 gap-y-4 gap-x-2" ]
|
||||||
[ div [ class "col-span-4" ]
|
[ div [ class "col-span-4" ]
|
||||||
[ label
|
[ label
|
||||||
[ class S.inputLabel
|
[ class S.inputLabel
|
||||||
]
|
]
|
||||||
[ text "Name"
|
[ text texts.basics.name
|
||||||
, B.inputRequired
|
, B.inputRequired
|
||||||
]
|
]
|
||||||
, input
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
, value model.name
|
, value model.name
|
||||||
, onInput SetName
|
, onInput SetName
|
||||||
, placeholder "Connection name, e.g. 'gmail.com'"
|
, placeholder texts.connectionPlaceholder
|
||||||
, class S.textInput
|
, class S.textInput
|
||||||
, classList [ ( S.inputErrorBorder, model.name == "" ) ]
|
, classList [ ( S.inputErrorBorder, model.name == "" ) ]
|
||||||
]
|
]
|
||||||
@ -207,17 +206,17 @@ view2 settings model =
|
|||||||
[ class S.message
|
[ class S.message
|
||||||
, class "mt-2"
|
, class "mt-2"
|
||||||
]
|
]
|
||||||
[ text "The connection name must not contain whitespace or special characters."
|
[ text texts.connectionNameInfo
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div [ class "col-span-3" ]
|
, div [ class "col-span-3" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "SMTP Host"
|
[ text texts.smtpHost
|
||||||
, B.inputRequired
|
, B.inputRequired
|
||||||
]
|
]
|
||||||
, input
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
, placeholder "SMTP host name, e.g. 'mail.gmail.com'"
|
, placeholder texts.smtpHostPlaceholder
|
||||||
, value model.host
|
, value model.host
|
||||||
, onInput SetHost
|
, onInput SetHost
|
||||||
, class S.textInput
|
, class S.textInput
|
||||||
@ -226,20 +225,23 @@ view2 settings model =
|
|||||||
[]
|
[]
|
||||||
]
|
]
|
||||||
, Html.map PortMsg
|
, Html.map PortMsg
|
||||||
(Comp.IntField.viewWithInfo2 ""
|
(Comp.IntField.view
|
||||||
model.portNum
|
{ label = texts.smtpPort
|
||||||
""
|
, info = ""
|
||||||
|
, number = model.portNum
|
||||||
|
, classes = ""
|
||||||
|
}
|
||||||
model.portField
|
model.portField
|
||||||
)
|
)
|
||||||
, div [ class "col-span-4 sm:col-span-2" ]
|
, div [ class "col-span-4 sm:col-span-2" ]
|
||||||
[ label
|
[ label
|
||||||
[ class S.inputLabel
|
[ class S.inputLabel
|
||||||
]
|
]
|
||||||
[ text "SMTP User"
|
[ text texts.smtpUser
|
||||||
]
|
]
|
||||||
, input
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
, placeholder "SMTP Username, e.g. 'your.name@gmail.com'"
|
, placeholder texts.smtpUserPlaceholder
|
||||||
, Maybe.withDefault "" model.user |> value
|
, Maybe.withDefault "" model.user |> value
|
||||||
, onInput SetUser
|
, onInput SetUser
|
||||||
, class S.textInput
|
, class S.textInput
|
||||||
@ -248,10 +250,11 @@ view2 settings model =
|
|||||||
]
|
]
|
||||||
, div [ class "col-span-4 sm:col-span-2" ]
|
, div [ class "col-span-4 sm:col-span-2" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "SMTP Password"
|
[ text texts.smtpPassword
|
||||||
]
|
]
|
||||||
, Html.map PassMsg
|
, Html.map PassMsg
|
||||||
(Comp.PasswordInput.view2
|
(Comp.PasswordInput.view2
|
||||||
|
{ placeholder = texts.smtpPasswordPlaceholder }
|
||||||
model.password
|
model.password
|
||||||
False
|
False
|
||||||
model.passField
|
model.passField
|
||||||
@ -259,12 +262,12 @@ view2 settings model =
|
|||||||
]
|
]
|
||||||
, div [ class "col-span-4 sm:col-span-2" ]
|
, div [ class "col-span-4 sm:col-span-2" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "From Address"
|
[ text texts.fromAddress
|
||||||
, B.inputRequired
|
, B.inputRequired
|
||||||
]
|
]
|
||||||
, input
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
, placeholder "Sender E-Mail address"
|
, placeholder texts.fromAddressPlaceholder
|
||||||
, value model.from
|
, value model.from
|
||||||
, onInput SetFrom
|
, onInput SetFrom
|
||||||
, class S.textInput
|
, class S.textInput
|
||||||
@ -274,11 +277,11 @@ view2 settings model =
|
|||||||
]
|
]
|
||||||
, div [ class "col-span-4 sm:col-span-2" ]
|
, div [ class "col-span-4 sm:col-span-2" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "Reply-To"
|
[ text texts.replyTo
|
||||||
]
|
]
|
||||||
, input
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
, placeholder "Optional reply-to E-Mail address"
|
, placeholder texts.replyToPlaceholder
|
||||||
, Maybe.withDefault "" model.replyTo |> value
|
, Maybe.withDefault "" model.replyTo |> value
|
||||||
, onInput SetReplyTo
|
, onInput SetReplyTo
|
||||||
, class S.textInput
|
, class S.textInput
|
||||||
@ -287,11 +290,11 @@ view2 settings model =
|
|||||||
]
|
]
|
||||||
, div [ class "col-span-4 sm:col-span-2" ]
|
, div [ class "col-span-4 sm:col-span-2" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "SSL"
|
[ text texts.ssl
|
||||||
]
|
]
|
||||||
, Html.map SSLTypeMsg
|
, Html.map SSLTypeMsg
|
||||||
(Comp.Dropdown.view2
|
(Comp.Dropdown.view2
|
||||||
DS.mainStyle
|
sslCfg
|
||||||
settings
|
settings
|
||||||
model.sslType
|
model.sslType
|
||||||
)
|
)
|
||||||
@ -300,7 +303,7 @@ view2 settings model =
|
|||||||
[ MB.viewItem <|
|
[ MB.viewItem <|
|
||||||
MB.Checkbox
|
MB.Checkbox
|
||||||
{ tagger = \_ -> ToggleCheckCert
|
{ tagger = \_ -> ToggleCheckCert
|
||||||
, label = "Ignore certificate check"
|
, label = texts.ignoreCertCheck
|
||||||
, value = model.ignoreCertificates
|
, value = model.ignoreCertificates
|
||||||
, id = "smpt-no-cert-check"
|
, id = "smpt-no-cert-check"
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import Data.UiSettings exposing (UiSettings)
|
|||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Http
|
import Http
|
||||||
|
import Messages.Comp.EmailSettingsManage exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.Http
|
import Util.Http
|
||||||
|
|
||||||
@ -206,71 +207,76 @@ update flags msg model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : UiSettings -> Model -> Html Msg
|
view2 : Texts -> UiSettings -> Model -> Html Msg
|
||||||
view2 settings model =
|
view2 texts settings model =
|
||||||
case model.viewMode of
|
case model.viewMode of
|
||||||
Table ->
|
Table ->
|
||||||
viewTable2 model
|
viewTable2 texts model
|
||||||
|
|
||||||
Form ->
|
Form ->
|
||||||
viewForm2 settings model
|
viewForm2 texts settings model
|
||||||
|
|
||||||
|
|
||||||
viewTable2 : Model -> Html Msg
|
viewTable2 : Texts -> Model -> Html Msg
|
||||||
viewTable2 model =
|
viewTable2 texts model =
|
||||||
div []
|
div []
|
||||||
[ MB.view
|
[ MB.view
|
||||||
{ start =
|
{ start =
|
||||||
[ MB.TextInput
|
[ MB.TextInput
|
||||||
{ tagger = SetQuery
|
{ tagger = SetQuery
|
||||||
, value = model.query
|
, value = model.query
|
||||||
, placeholder = "Search…"
|
, placeholder = texts.basics.searchPlaceholder
|
||||||
, icon = Just "fa fa-search"
|
, icon = Just "fa fa-search"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
, end =
|
, end =
|
||||||
[ MB.PrimaryButton
|
[ MB.PrimaryButton
|
||||||
{ tagger = InitNew
|
{ tagger = InitNew
|
||||||
, title = "Add new SMTP settings"
|
, title = texts.addNewSmtpSettings
|
||||||
, icon = Just "fa fa-plus"
|
, icon = Just "fa fa-plus"
|
||||||
, label = "New Settings"
|
, label = texts.newSettings
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
, rootClasses = "mb-4"
|
, rootClasses = "mb-4"
|
||||||
}
|
}
|
||||||
, Html.map TableMsg (Comp.EmailSettingsTable.view2 model.tableModel)
|
, Html.map TableMsg
|
||||||
|
(Comp.EmailSettingsTable.view2 texts.settingsTable
|
||||||
|
model.tableModel
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewForm2 : UiSettings -> Model -> Html Msg
|
viewForm2 : Texts -> UiSettings -> Model -> Html Msg
|
||||||
viewForm2 settings model =
|
viewForm2 texts settings model =
|
||||||
let
|
let
|
||||||
dimmerSettings =
|
dimmerSettings =
|
||||||
Comp.YesNoDimmer.defaultSettings2 "Really delete these connection?"
|
Comp.YesNoDimmer.defaultSettings texts.reallyDeleteConnection
|
||||||
|
texts.basics.yes
|
||||||
|
texts.basics.no
|
||||||
in
|
in
|
||||||
div [ class "flex flex-col md:relative" ]
|
div [ class "flex flex-col md:relative" ]
|
||||||
[ MB.view
|
[ MB.view
|
||||||
{ start =
|
{ start =
|
||||||
[ MB.PrimaryButton
|
[ MB.PrimaryButton
|
||||||
{ tagger = Submit
|
{ tagger = Submit
|
||||||
, title = "Submit this form"
|
, title = texts.basics.submitThisForm
|
||||||
, icon = Just "fa fa-save"
|
, icon = Just "fa fa-save"
|
||||||
, label = "Submit"
|
, label = texts.basics.submit
|
||||||
}
|
}
|
||||||
, MB.SecondaryButton
|
, MB.SecondaryButton
|
||||||
{ tagger = SetViewMode Table
|
{ tagger = SetViewMode Table
|
||||||
, title = "Back to list"
|
, title = texts.basics.backToList
|
||||||
, icon = Just "fa fa-arrow-left"
|
, icon = Just "fa fa-arrow-left"
|
||||||
, label = "Cancel"
|
, label = texts.basics.cancel
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
, end =
|
, end =
|
||||||
if model.formModel.settings.name /= "" then
|
if model.formModel.settings.name /= "" then
|
||||||
[ MB.DeleteButton
|
[ MB.DeleteButton
|
||||||
{ tagger = RequestDelete
|
{ tagger = RequestDelete
|
||||||
, title = "Delete this settings entry"
|
, title = texts.deleteThisEntry
|
||||||
, icon = Just "fa fa-trash"
|
, icon = Just "fa fa-trash"
|
||||||
, label = "Delete"
|
, label = texts.basics.delete
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -288,12 +294,18 @@ viewForm2 settings model =
|
|||||||
[ Maybe.withDefault "" model.formError |> text
|
[ Maybe.withDefault "" model.formError |> text
|
||||||
]
|
]
|
||||||
, Html.map FormMsg
|
, Html.map FormMsg
|
||||||
(Comp.EmailSettingsForm.view2 settings model.formModel)
|
(Comp.EmailSettingsForm.view2 texts.settingsForm
|
||||||
|
settings
|
||||||
|
model.formModel
|
||||||
|
)
|
||||||
, Html.map YesNoMsg
|
, Html.map YesNoMsg
|
||||||
(Comp.YesNoDimmer.viewN
|
(Comp.YesNoDimmer.viewN
|
||||||
True
|
True
|
||||||
dimmerSettings
|
dimmerSettings
|
||||||
model.deleteConfirm
|
model.deleteConfirm
|
||||||
)
|
)
|
||||||
, B.loadingDimmer model.loading
|
, B.loadingDimmer
|
||||||
|
{ active = model.loading
|
||||||
|
, label = texts.basics.loading
|
||||||
|
}
|
||||||
]
|
]
|
||||||
|
@ -11,6 +11,7 @@ import Api.Model.EmailSettings exposing (EmailSettings)
|
|||||||
import Comp.Basic as B
|
import Comp.Basic as B
|
||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
|
import Messages.Comp.EmailSettingsTable exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
|
|
||||||
|
|
||||||
@ -47,15 +48,15 @@ update msg model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : Model -> Html Msg
|
view2 : Texts -> Model -> Html Msg
|
||||||
view2 model =
|
view2 texts model =
|
||||||
table [ class S.tableMain ]
|
table [ class S.tableMain ]
|
||||||
[ thead []
|
[ thead []
|
||||||
[ tr []
|
[ tr []
|
||||||
[ th [ class "" ] []
|
[ th [ class "" ] []
|
||||||
, th [ class "text-left mr-2" ] [ text "Name" ]
|
, th [ class "text-left mr-2" ] [ text texts.basics.name ]
|
||||||
, th [ class "text-left mr-2" ] [ text "Host/Port" ]
|
, th [ class "text-left mr-2" ] [ text texts.hostPort ]
|
||||||
, th [ class "text-left mr-2 hidden sm:table-cell" ] [ text "From" ]
|
, th [ class "text-left mr-2 hidden sm:table-cell" ] [ text texts.from ]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, tbody []
|
, tbody []
|
||||||
|
@ -11,11 +11,13 @@ module Comp.EquipmentForm exposing
|
|||||||
import Api.Model.Equipment exposing (Equipment)
|
import Api.Model.Equipment exposing (Equipment)
|
||||||
import Comp.Basic as B
|
import Comp.Basic as B
|
||||||
import Comp.FixedDropdown
|
import Comp.FixedDropdown
|
||||||
|
import Data.DropdownStyle as DS
|
||||||
import Data.EquipmentUse exposing (EquipmentUse)
|
import Data.EquipmentUse exposing (EquipmentUse)
|
||||||
import Data.Flags exposing (Flags)
|
import Data.Flags exposing (Flags)
|
||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onInput)
|
import Html.Events exposing (onInput)
|
||||||
|
import Messages.Comp.EquipmentForm exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.Maybe
|
import Util.Maybe
|
||||||
|
|
||||||
@ -36,9 +38,7 @@ emptyModel =
|
|||||||
, notes = Nothing
|
, notes = Nothing
|
||||||
, use = Data.EquipmentUse.Concerning
|
, use = Data.EquipmentUse.Concerning
|
||||||
, useModel =
|
, useModel =
|
||||||
Comp.FixedDropdown.initMap
|
Comp.FixedDropdown.init Data.EquipmentUse.all
|
||||||
Data.EquipmentUse.label
|
|
||||||
Data.EquipmentUse.all
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -100,21 +100,28 @@ update _ msg model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : Model -> Html Msg
|
view2 : Texts -> Model -> Html Msg
|
||||||
view2 model =
|
view2 texts model =
|
||||||
|
let
|
||||||
|
equipUseCfg =
|
||||||
|
{ display = texts.equipmentUseLabel
|
||||||
|
, icon = \_ -> Nothing
|
||||||
|
, style = DS.mainStyle
|
||||||
|
}
|
||||||
|
in
|
||||||
div [ class "flex flex-col" ]
|
div [ class "flex flex-col" ]
|
||||||
[ div [ class "mb-4" ]
|
[ div [ class "mb-4" ]
|
||||||
[ label
|
[ label
|
||||||
[ for "equipname"
|
[ for "equipname"
|
||||||
, class S.inputLabel
|
, class S.inputLabel
|
||||||
]
|
]
|
||||||
[ text "Name"
|
[ text texts.basics.name
|
||||||
, B.inputRequired
|
, B.inputRequired
|
||||||
]
|
]
|
||||||
, input
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
, onInput SetName
|
, onInput SetName
|
||||||
, placeholder "Name"
|
, placeholder texts.basics.name
|
||||||
, value model.name
|
, value model.name
|
||||||
, name "equipname"
|
, name "equipname"
|
||||||
, class S.textInput
|
, class S.textInput
|
||||||
@ -130,21 +137,21 @@ view2 model =
|
|||||||
[ label
|
[ label
|
||||||
[ class S.inputLabel
|
[ class S.inputLabel
|
||||||
]
|
]
|
||||||
[ text "Use" ]
|
[ text texts.use ]
|
||||||
, Html.map UseDropdownMsg
|
, Html.map UseDropdownMsg
|
||||||
(Comp.FixedDropdown.view2 (makeUseItem model) model.useModel)
|
(Comp.FixedDropdown.viewStyled2 equipUseCfg False (Just model.use) model.useModel)
|
||||||
, span [ class "opacity-50 text-sm" ]
|
, span [ class "opacity-50 text-sm" ]
|
||||||
[ case model.use of
|
[ case model.use of
|
||||||
Data.EquipmentUse.Concerning ->
|
Data.EquipmentUse.Concerning ->
|
||||||
text "Use as concerning equipment"
|
text texts.useAsConcerning
|
||||||
|
|
||||||
Data.EquipmentUse.Disabled ->
|
Data.EquipmentUse.Disabled ->
|
||||||
text "Do not use for suggestions."
|
text texts.useNotSuggestions
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div [ class "mb-4" ]
|
, div [ class "mb-4" ]
|
||||||
[ h3 [ class S.header3 ]
|
[ h3 [ class S.header3 ]
|
||||||
[ text "Notes"
|
[ text texts.notes
|
||||||
]
|
]
|
||||||
, div [ class "" ]
|
, div [ class "" ]
|
||||||
[ textarea
|
[ textarea
|
||||||
@ -156,9 +163,3 @@ view2 model =
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
makeUseItem : Model -> Maybe (Comp.FixedDropdown.Item EquipmentUse)
|
|
||||||
makeUseItem model =
|
|
||||||
Just <|
|
|
||||||
Comp.FixedDropdown.Item model.use (Data.EquipmentUse.label model.use)
|
|
||||||
|
@ -20,6 +20,7 @@ import Html exposing (..)
|
|||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onSubmit)
|
import Html.Events exposing (onSubmit)
|
||||||
import Http
|
import Http
|
||||||
|
import Messages.Comp.EquipmentManage exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.Http
|
import Util.Http
|
||||||
import Util.Maybe
|
import Util.Maybe
|
||||||
@ -204,38 +205,41 @@ update flags msg model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : Model -> Html Msg
|
view2 : Texts -> Model -> Html Msg
|
||||||
view2 model =
|
view2 texts model =
|
||||||
if model.viewMode == Table then
|
if model.viewMode == Table then
|
||||||
viewTable2 model
|
viewTable2 texts model
|
||||||
|
|
||||||
else
|
else
|
||||||
viewForm2 model
|
viewForm2 texts model
|
||||||
|
|
||||||
|
|
||||||
viewTable2 : Model -> Html Msg
|
viewTable2 : Texts -> Model -> Html Msg
|
||||||
viewTable2 model =
|
viewTable2 texts model =
|
||||||
div [ class "flex flex-col" ]
|
div [ class "flex flex-col" ]
|
||||||
[ MB.view
|
[ MB.view
|
||||||
{ start =
|
{ start =
|
||||||
[ MB.TextInput
|
[ MB.TextInput
|
||||||
{ tagger = SetQuery
|
{ tagger = SetQuery
|
||||||
, value = model.query
|
, value = model.query
|
||||||
, placeholder = "Search…"
|
, placeholder = texts.basics.searchPlaceholder
|
||||||
, icon = Just "fa fa-search"
|
, icon = Just "fa fa-search"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
, end =
|
, end =
|
||||||
[ MB.PrimaryButton
|
[ MB.PrimaryButton
|
||||||
{ tagger = InitNewEquipment
|
{ tagger = InitNewEquipment
|
||||||
, title = "Create a new equipment"
|
, title = texts.createNewEquipment
|
||||||
, icon = Just "fa fa-plus"
|
, icon = Just "fa fa-plus"
|
||||||
, label = "New Equipment"
|
, label = texts.newEquipment
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
, rootClasses = "mb-4"
|
, rootClasses = "mb-4"
|
||||||
}
|
}
|
||||||
, Html.map TableMsg (Comp.EquipmentTable.view2 model.tableModel)
|
, Html.map TableMsg
|
||||||
|
(Comp.EquipmentTable.view2 texts.equipmentTable
|
||||||
|
model.tableModel
|
||||||
|
)
|
||||||
, div
|
, div
|
||||||
[ classList
|
[ classList
|
||||||
[ ( "ui dimmer", True )
|
[ ( "ui dimmer", True )
|
||||||
@ -247,14 +251,16 @@ viewTable2 model =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewForm2 : Model -> Html Msg
|
viewForm2 : Texts -> Model -> Html Msg
|
||||||
viewForm2 model =
|
viewForm2 texts model =
|
||||||
let
|
let
|
||||||
newEquipment =
|
newEquipment =
|
||||||
model.formModel.equipment.id == ""
|
model.formModel.equipment.id == ""
|
||||||
|
|
||||||
dimmerSettings2 =
|
dimmerSettings2 =
|
||||||
Comp.YesNoDimmer.defaultSettings2 "Really delete this equipment?"
|
Comp.YesNoDimmer.defaultSettings texts.reallyDeleteEquipment
|
||||||
|
texts.basics.yes
|
||||||
|
texts.basics.no
|
||||||
in
|
in
|
||||||
Html.form
|
Html.form
|
||||||
[ class "relative flex flex-col"
|
[ class "relative flex flex-col"
|
||||||
@ -268,14 +274,14 @@ viewForm2 model =
|
|||||||
)
|
)
|
||||||
, if newEquipment then
|
, if newEquipment then
|
||||||
h1 [ class S.header2 ]
|
h1 [ class S.header2 ]
|
||||||
[ text "Create new equipment"
|
[ text texts.createNewEquipment
|
||||||
]
|
]
|
||||||
|
|
||||||
else
|
else
|
||||||
h1 [ class S.header2 ]
|
h1 [ class S.header2 ]
|
||||||
[ text model.formModel.equipment.name
|
[ text model.formModel.equipment.name
|
||||||
, div [ class "opacity-50 text-sm" ]
|
, div [ class "opacity-50 text-sm" ]
|
||||||
[ text "Id: "
|
[ text (texts.basics.id ++ ": ")
|
||||||
, text model.formModel.equipment.id
|
, text model.formModel.equipment.id
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -283,24 +289,24 @@ viewForm2 model =
|
|||||||
{ start =
|
{ start =
|
||||||
[ MB.PrimaryButton
|
[ MB.PrimaryButton
|
||||||
{ tagger = Submit
|
{ tagger = Submit
|
||||||
, title = "Submit this form"
|
, title = texts.basics.submitThisForm
|
||||||
, icon = Just "fa fa-save"
|
, icon = Just "fa fa-save"
|
||||||
, label = "Submit"
|
, label = texts.basics.submit
|
||||||
}
|
}
|
||||||
, MB.SecondaryButton
|
, MB.SecondaryButton
|
||||||
{ tagger = SetViewMode Table
|
{ tagger = SetViewMode Table
|
||||||
, title = "Back to list"
|
, title = texts.basics.backToList
|
||||||
, icon = Just "fa fa-arrow-left"
|
, icon = Just "fa fa-arrow-left"
|
||||||
, label = "Cancel"
|
, label = texts.basics.cancel
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
, end =
|
, end =
|
||||||
if not newEquipment then
|
if not newEquipment then
|
||||||
[ MB.DeleteButton
|
[ MB.DeleteButton
|
||||||
{ tagger = RequestDelete
|
{ tagger = RequestDelete
|
||||||
, title = "Delete this equipment"
|
, title = texts.deleteThisEquipment
|
||||||
, icon = Just "fa fa-trash"
|
, icon = Just "fa fa-trash"
|
||||||
, label = "Delete"
|
, label = texts.basics.delete
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -317,6 +323,9 @@ viewForm2 model =
|
|||||||
]
|
]
|
||||||
[ Maybe.withDefault "" model.formError |> text
|
[ Maybe.withDefault "" model.formError |> text
|
||||||
]
|
]
|
||||||
, Html.map FormMsg (Comp.EquipmentForm.view2 model.formModel)
|
, Html.map FormMsg (Comp.EquipmentForm.view2 texts.equipmentForm model.formModel)
|
||||||
, B.loadingDimmer model.loading
|
, B.loadingDimmer
|
||||||
|
{ active = model.loading
|
||||||
|
, label = texts.basics.loading
|
||||||
|
}
|
||||||
]
|
]
|
||||||
|
@ -12,7 +12,7 @@ import Data.EquipmentUse
|
|||||||
import Data.Flags exposing (Flags)
|
import Data.Flags exposing (Flags)
|
||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onClick)
|
import Messages.Comp.EquipmentTable exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
|
|
||||||
|
|
||||||
@ -52,25 +52,25 @@ update _ msg model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : Model -> Html Msg
|
view2 : Texts -> Model -> Html Msg
|
||||||
view2 model =
|
view2 texts model =
|
||||||
table [ class S.tableMain ]
|
table [ class S.tableMain ]
|
||||||
[ thead []
|
[ thead []
|
||||||
[ tr []
|
[ tr []
|
||||||
[ th [ class "" ] []
|
[ th [ class "" ] []
|
||||||
, th [ class "text-left pr-1 md:px-2 w-20" ]
|
, th [ class "text-left pr-1 md:px-2 w-20" ]
|
||||||
[ text "Use"
|
[ text texts.use
|
||||||
]
|
]
|
||||||
, th [ class "text-left" ] [ text "Name" ]
|
, th [ class "text-left" ] [ text texts.basics.name ]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, tbody []
|
, tbody []
|
||||||
(List.map (renderEquipmentLine2 model) model.equips)
|
(List.map (renderEquipmentLine2 texts model) model.equips)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
renderEquipmentLine2 : Model -> Equipment -> Html Msg
|
renderEquipmentLine2 : Texts -> Model -> Equipment -> Html Msg
|
||||||
renderEquipmentLine2 model equip =
|
renderEquipmentLine2 texts model equip =
|
||||||
tr
|
tr
|
||||||
[ classList [ ( "active", model.selected == Just equip ) ]
|
[ classList [ ( "active", model.selected == Just equip ) ]
|
||||||
, class S.tableRow
|
, class S.tableRow
|
||||||
@ -80,7 +80,7 @@ renderEquipmentLine2 model equip =
|
|||||||
[ div [ class "label inline-flex text-sm" ]
|
[ div [ class "label inline-flex text-sm" ]
|
||||||
[ Data.EquipmentUse.fromString equip.use
|
[ Data.EquipmentUse.fromString equip.use
|
||||||
|> Maybe.withDefault Data.EquipmentUse.Concerning
|
|> Maybe.withDefault Data.EquipmentUse.Concerning
|
||||||
|> Data.EquipmentUse.label
|
|> texts.equipmentUseLabel
|
||||||
|> text
|
|> text
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
module Comp.FieldListSelect exposing
|
module Comp.FieldListSelect exposing
|
||||||
( Model
|
( Model
|
||||||
, Msg
|
, Msg
|
||||||
|
, ViewSettings
|
||||||
, update
|
, update
|
||||||
, view2
|
, view2
|
||||||
)
|
)
|
||||||
@ -49,17 +50,23 @@ addField selected field =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : String -> Model -> Html Msg
|
type alias ViewSettings =
|
||||||
view2 classes selected =
|
{ fieldLabel : Field -> String
|
||||||
|
, classes : String
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
view2 : ViewSettings -> Model -> Html Msg
|
||||||
|
view2 cfg selected =
|
||||||
div
|
div
|
||||||
[ class "flex flex-col space-y-4 md:space-y-2"
|
[ class "flex flex-col space-y-4 md:space-y-2"
|
||||||
, class classes
|
, class cfg.classes
|
||||||
]
|
]
|
||||||
(List.map (fieldCheckbox2 selected) Data.Fields.all)
|
(List.map (fieldCheckbox2 cfg selected) Data.Fields.all)
|
||||||
|
|
||||||
|
|
||||||
fieldCheckbox2 : Model -> Field -> Html Msg
|
fieldCheckbox2 : ViewSettings -> Model -> Field -> Html Msg
|
||||||
fieldCheckbox2 selected field =
|
fieldCheckbox2 cfg selected field =
|
||||||
let
|
let
|
||||||
isChecked =
|
isChecked =
|
||||||
List.member field selected
|
List.member field selected
|
||||||
@ -69,5 +76,5 @@ fieldCheckbox2 selected field =
|
|||||||
{ id = "field-toggle-" ++ Data.Fields.toString field
|
{ id = "field-toggle-" ++ Data.Fields.toString field
|
||||||
, value = isChecked
|
, value = isChecked
|
||||||
, tagger = \_ -> Toggle field
|
, tagger = \_ -> Toggle field
|
||||||
, label = Data.Fields.label field
|
, label = cfg.fieldLabel field
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,9 @@ module Comp.FixedDropdown exposing
|
|||||||
( Item
|
( Item
|
||||||
, Model
|
, Model
|
||||||
, Msg
|
, Msg
|
||||||
|
, ViewSettings
|
||||||
, init
|
, init
|
||||||
, initMap
|
|
||||||
, initString
|
|
||||||
, initTuple
|
|
||||||
, update
|
, update
|
||||||
, view2
|
|
||||||
, viewStyled2
|
, viewStyled2
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -22,7 +19,6 @@ import Util.List
|
|||||||
|
|
||||||
type alias Item a =
|
type alias Item a =
|
||||||
{ id : a
|
{ id : a
|
||||||
, display : String
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -39,31 +35,17 @@ type Msg a
|
|||||||
| KeyPress (Maybe KeyCode)
|
| KeyPress (Maybe KeyCode)
|
||||||
|
|
||||||
|
|
||||||
init : List (Item a) -> Model a
|
initItems : List (Item a) -> Model a
|
||||||
init options =
|
initItems options =
|
||||||
{ options = options
|
{ options = options
|
||||||
, menuOpen = False
|
, menuOpen = False
|
||||||
, selected = Nothing
|
, selected = Nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
initString : List String -> Model String
|
init : List a -> Model a
|
||||||
initString strings =
|
init els =
|
||||||
init <| List.map (\s -> Item s s) strings
|
List.map Item els |> initItems
|
||||||
|
|
||||||
|
|
||||||
initMap : (a -> String) -> List a -> Model a
|
|
||||||
initMap elToString els =
|
|
||||||
init <| List.map (\a -> Item a (elToString a)) els
|
|
||||||
|
|
||||||
|
|
||||||
initTuple : List ( String, a ) -> Model a
|
|
||||||
initTuple tuples =
|
|
||||||
let
|
|
||||||
mkItem ( txt, id ) =
|
|
||||||
Item id txt
|
|
||||||
in
|
|
||||||
init <| List.map mkItem tuples
|
|
||||||
|
|
||||||
|
|
||||||
isSelected : Model a -> Item a -> Bool
|
isSelected : Model a -> Item a -> Bool
|
||||||
@ -167,28 +149,48 @@ update msg model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
viewStyled2 : DS.DropdownStyle -> Bool -> Maybe (Item a) -> Model a -> Html (Msg a)
|
type alias ViewSettings a =
|
||||||
viewStyled2 style error sel model =
|
{ display : a -> String
|
||||||
|
, icon : a -> Maybe String
|
||||||
|
, style : DS.DropdownStyle
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
viewStyled2 : ViewSettings a -> Bool -> Maybe a -> Model a -> Html (Msg a)
|
||||||
|
viewStyled2 cfg error sel model =
|
||||||
let
|
let
|
||||||
|
iconItem id =
|
||||||
|
span
|
||||||
|
[ classList [ ( "hidden", cfg.icon id == Nothing ) ]
|
||||||
|
, class (Maybe.withDefault "" (cfg.icon id))
|
||||||
|
, class "mr-2"
|
||||||
|
]
|
||||||
|
[]
|
||||||
|
|
||||||
renderItem item =
|
renderItem item =
|
||||||
a
|
a
|
||||||
[ href "#"
|
[ href "#"
|
||||||
, class style.item
|
, class cfg.style.item
|
||||||
, classList
|
, classList
|
||||||
[ ( style.itemActive, isSelected model item )
|
[ ( cfg.style.itemActive, isSelected model item )
|
||||||
, ( "font-semibold", Just item == sel )
|
, ( "font-semibold", Just item.id == sel )
|
||||||
]
|
]
|
||||||
, onClick (SelectItem2 item)
|
, onClick (SelectItem2 item)
|
||||||
]
|
]
|
||||||
[ text item.display
|
[ iconItem item.id
|
||||||
|
, text (cfg.display item.id)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
selIcon =
|
||||||
|
Maybe.map iconItem sel
|
||||||
|
|> Maybe.withDefault (span [ class "hidden" ] [])
|
||||||
in
|
in
|
||||||
div
|
div
|
||||||
[ class ("relative " ++ style.root)
|
[ class ("relative " ++ cfg.style.root)
|
||||||
, onKeyUpCode KeyPress
|
, onKeyUpCode KeyPress
|
||||||
]
|
]
|
||||||
[ a
|
[ a
|
||||||
[ class style.link
|
[ class cfg.style.link
|
||||||
, classList [ ( S.inputErrorBorder, error ) ]
|
, classList [ ( S.inputErrorBorder, error ) ]
|
||||||
, tabindex 0
|
, tabindex 0
|
||||||
, onClick ToggleMenu
|
, onClick ToggleMenu
|
||||||
@ -200,7 +202,8 @@ viewStyled2 style error sel model =
|
|||||||
[ ( "opacity-50", sel == Nothing )
|
[ ( "opacity-50", sel == Nothing )
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
[ Maybe.map .display sel
|
[ selIcon
|
||||||
|
, Maybe.map cfg.display sel
|
||||||
|> Maybe.withDefault "Select…"
|
|> Maybe.withDefault "Select…"
|
||||||
|> text
|
|> text
|
||||||
]
|
]
|
||||||
@ -211,13 +214,8 @@ viewStyled2 style error sel model =
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div
|
, div
|
||||||
[ class style.menu
|
[ class cfg.style.menu
|
||||||
, classList [ ( "hidden", not model.menuOpen ) ]
|
, classList [ ( "hidden", not model.menuOpen ) ]
|
||||||
]
|
]
|
||||||
(List.map renderItem model.options)
|
(List.map renderItem model.options)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
view2 : Maybe (Item a) -> Model a -> Html (Msg a)
|
|
||||||
view2 =
|
|
||||||
viewStyled2 DS.mainStyle False
|
|
||||||
|
@ -18,11 +18,13 @@ import Comp.Basic as B
|
|||||||
import Comp.FixedDropdown
|
import Comp.FixedDropdown
|
||||||
import Comp.MenuBar as MB
|
import Comp.MenuBar as MB
|
||||||
import Comp.YesNoDimmer
|
import Comp.YesNoDimmer
|
||||||
|
import Data.DropdownStyle as DS
|
||||||
import Data.Flags exposing (Flags)
|
import Data.Flags exposing (Flags)
|
||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onClick, onInput)
|
import Html.Events exposing (onClick, onInput)
|
||||||
import Http
|
import Http
|
||||||
|
import Messages.Comp.FolderDetail exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.Http
|
import Util.Http
|
||||||
import Util.Maybe
|
import Util.Maybe
|
||||||
@ -65,8 +67,7 @@ init users folder =
|
|||||||
, members = folder.members
|
, members = folder.members
|
||||||
, users = users
|
, users = users
|
||||||
, memberDropdown =
|
, memberDropdown =
|
||||||
Comp.FixedDropdown.initMap .name
|
Comp.FixedDropdown.init (makeOptions users folder)
|
||||||
(makeOptions users folder)
|
|
||||||
, selectedMember = Nothing
|
, selectedMember = Nothing
|
||||||
, loading = False
|
, loading = False
|
||||||
, deleteDimmer = Comp.YesNoDimmer.emptyModel
|
, deleteDimmer = Comp.YesNoDimmer.emptyModel
|
||||||
@ -275,13 +276,8 @@ update flags msg model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
makeItem : IdName -> Comp.FixedDropdown.Item IdName
|
view2 : Texts -> Flags -> Model -> Html Msg
|
||||||
makeItem idn =
|
view2 texts flags model =
|
||||||
Comp.FixedDropdown.Item idn idn.name
|
|
||||||
|
|
||||||
|
|
||||||
view2 : Flags -> Model -> Html Msg
|
|
||||||
view2 flags model =
|
|
||||||
let
|
let
|
||||||
isOwner =
|
isOwner =
|
||||||
Maybe.map .user flags.account
|
Maybe.map .user flags.account
|
||||||
@ -290,10 +286,12 @@ view2 flags model =
|
|||||||
|
|
||||||
dimmerSettings : Comp.YesNoDimmer.Settings
|
dimmerSettings : Comp.YesNoDimmer.Settings
|
||||||
dimmerSettings =
|
dimmerSettings =
|
||||||
Comp.YesNoDimmer.defaultSettings2 "Really delete this folder?"
|
Comp.YesNoDimmer.defaultSettings texts.reallyDeleteThisFolder
|
||||||
|
texts.basics.yes
|
||||||
|
texts.basics.no
|
||||||
in
|
in
|
||||||
div [ class "flex flex-col md:relative" ]
|
div [ class "flex flex-col md:relative" ]
|
||||||
(viewButtons2 model
|
(viewButtons2 texts model
|
||||||
:: [ Html.map DeleteMsg
|
:: [ Html.map DeleteMsg
|
||||||
(Comp.YesNoDimmer.viewN
|
(Comp.YesNoDimmer.viewN
|
||||||
True
|
True
|
||||||
@ -304,26 +302,26 @@ view2 flags model =
|
|||||||
[ class "py-2 text-lg opacity-75"
|
[ class "py-2 text-lg opacity-75"
|
||||||
, classList [ ( "hidden", model.folder.id /= "" ) ]
|
, classList [ ( "hidden", model.folder.id /= "" ) ]
|
||||||
]
|
]
|
||||||
[ text "You are automatically set as owner of this new folder."
|
[ text texts.autoOwnerInfo
|
||||||
]
|
]
|
||||||
, div
|
, div
|
||||||
[ class "py-2 text-lg opacity-75"
|
[ class "py-2 text-lg opacity-75"
|
||||||
, classList [ ( "hidden", model.folder.id == "" ) ]
|
, classList [ ( "hidden", model.folder.id == "" ) ]
|
||||||
]
|
]
|
||||||
[ text "Modify this folder by changing the name or add/remove members."
|
[ text texts.modifyInfo
|
||||||
]
|
]
|
||||||
, div
|
, div
|
||||||
[ class S.message
|
[ class S.message
|
||||||
, classList [ ( "hidden", model.folder.id == "" || isOwner ) ]
|
, classList [ ( "hidden", model.folder.id == "" || isOwner ) ]
|
||||||
]
|
]
|
||||||
[ text "You are not the owner of this folder and therefore are not allowed to edit it."
|
[ text texts.notOwnerInfo
|
||||||
]
|
]
|
||||||
, div [ class "mb-4 flex flex-col" ]
|
, div [ class "mb-4 flex flex-col" ]
|
||||||
[ label
|
[ label
|
||||||
[ class S.inputLabel
|
[ class S.inputLabel
|
||||||
, for "folder-name"
|
, for "folder-name"
|
||||||
]
|
]
|
||||||
[ text "Name"
|
[ text texts.basics.name
|
||||||
, B.inputRequired
|
, B.inputRequired
|
||||||
]
|
]
|
||||||
, div [ class "flex flex-row space-x-2" ]
|
, div [ class "flex flex-row space-x-2" ]
|
||||||
@ -345,7 +343,7 @@ view2 flags model =
|
|||||||
]
|
]
|
||||||
[ i [ class "fa fa-save" ] []
|
[ i [ class "fa fa-save" ] []
|
||||||
, span [ class "ml-2 hidden sm:inline" ]
|
, span [ class "ml-2 hidden sm:inline" ]
|
||||||
[ text "Save"
|
[ text texts.basics.submit
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -363,12 +361,19 @@ view2 flags model =
|
|||||||
|> text
|
|> text
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
++ viewMembers2 model
|
++ viewMembers2 texts model
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
viewMembers2 : Model -> List (Html Msg)
|
viewMembers2 : Texts -> Model -> List (Html Msg)
|
||||||
viewMembers2 model =
|
viewMembers2 texts model =
|
||||||
|
let
|
||||||
|
folderCfg =
|
||||||
|
{ display = .name
|
||||||
|
, icon = \_ -> Nothing
|
||||||
|
, style = DS.mainStyle
|
||||||
|
}
|
||||||
|
in
|
||||||
if model.folder.id == "" then
|
if model.folder.id == "" then
|
||||||
[]
|
[]
|
||||||
|
|
||||||
@ -377,19 +382,21 @@ viewMembers2 model =
|
|||||||
[ class S.header3
|
[ class S.header3
|
||||||
, class "mt-4"
|
, class "mt-4"
|
||||||
]
|
]
|
||||||
[ text "Members"
|
[ text texts.members
|
||||||
]
|
]
|
||||||
, div [ class "flex flex-col space-y-2" ]
|
, div [ class "flex flex-col space-y-2" ]
|
||||||
[ div [ class "flex flex-row space-x-2" ]
|
[ div [ class "flex flex-row space-x-2" ]
|
||||||
[ div [ class "flex-grow" ]
|
[ div [ class "flex-grow" ]
|
||||||
[ Html.map MemberDropdownMsg
|
[ Html.map MemberDropdownMsg
|
||||||
(Comp.FixedDropdown.view2
|
(Comp.FixedDropdown.viewStyled2
|
||||||
(Maybe.map makeItem model.selectedMember)
|
folderCfg
|
||||||
|
False
|
||||||
|
model.selectedMember
|
||||||
model.memberDropdown
|
model.memberDropdown
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
, a
|
, a
|
||||||
[ title "Add a new member"
|
[ title texts.addMember
|
||||||
, onClick AddMember
|
, onClick AddMember
|
||||||
, class S.primaryButton
|
, class S.primaryButton
|
||||||
, href "#"
|
, href "#"
|
||||||
@ -397,7 +404,7 @@ viewMembers2 model =
|
|||||||
]
|
]
|
||||||
[ i [ class "fa fa-plus" ] []
|
[ i [ class "fa fa-plus" ] []
|
||||||
, span [ class "ml-2 hidden sm:inline" ]
|
, span [ class "ml-2 hidden sm:inline" ]
|
||||||
[ text "Add"
|
[ text texts.add
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -406,19 +413,19 @@ viewMembers2 model =
|
|||||||
[ class "flex flex-col space-y-4 md:space-y-2 mt-2"
|
[ class "flex flex-col space-y-4 md:space-y-2 mt-2"
|
||||||
, class "px-2 border-0 border-l dark:border-bluegray-600"
|
, class "px-2 border-0 border-l dark:border-bluegray-600"
|
||||||
]
|
]
|
||||||
(List.map viewMember2 model.members)
|
(List.map (viewMember2 texts) model.members)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewMember2 : IdName -> Html Msg
|
viewMember2 : Texts -> IdName -> Html Msg
|
||||||
viewMember2 member =
|
viewMember2 texts member =
|
||||||
div
|
div
|
||||||
[ class "flex flex-row space-x-2 items-center"
|
[ class "flex flex-row space-x-2 items-center"
|
||||||
]
|
]
|
||||||
[ a
|
[ a
|
||||||
[ class S.deleteLabel
|
[ class S.deleteLabel
|
||||||
, href "#"
|
, href "#"
|
||||||
, title "Remove this member"
|
, title texts.removeMember
|
||||||
, onClick (RemoveMember member)
|
, onClick (RemoveMember member)
|
||||||
]
|
]
|
||||||
[ i [ class "fa fa-trash " ] []
|
[ i [ class "fa fa-trash " ] []
|
||||||
@ -429,23 +436,23 @@ viewMember2 member =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewButtons2 : Model -> Html Msg
|
viewButtons2 : Texts -> Model -> Html Msg
|
||||||
viewButtons2 model =
|
viewButtons2 texts model =
|
||||||
MB.view
|
MB.view
|
||||||
{ start =
|
{ start =
|
||||||
[ MB.SecondaryButton
|
[ MB.SecondaryButton
|
||||||
{ tagger = GoBack
|
{ tagger = GoBack
|
||||||
, label = "Back"
|
, label = texts.basics.cancel
|
||||||
, icon = Just "fa fa-arrow-left"
|
, icon = Just "fa fa-arrow-left"
|
||||||
, title = "Back to list"
|
, title = texts.basics.backToList
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
, end =
|
, end =
|
||||||
[ MB.CustomButton
|
[ MB.CustomButton
|
||||||
{ tagger = RequestDelete
|
{ tagger = RequestDelete
|
||||||
, label = "Delete"
|
, label = texts.basics.delete
|
||||||
, icon = Just "fa fa-trash"
|
, icon = Just "fa fa-trash"
|
||||||
, title = "Delete this folder"
|
, title = texts.deleteThisFolder
|
||||||
, inputClass =
|
, inputClass =
|
||||||
[ ( S.deleteButton, True )
|
[ ( S.deleteButton, True )
|
||||||
, ( "hidden", model.folder.id == "" )
|
, ( "hidden", model.folder.id == "" )
|
||||||
|
@ -20,6 +20,7 @@ import Data.Flags exposing (Flags)
|
|||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Http
|
import Http
|
||||||
|
import Messages.Comp.FolderManage exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
|
|
||||||
|
|
||||||
@ -168,50 +169,54 @@ update flags msg model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : Flags -> Model -> Html Msg
|
view2 : Texts -> Flags -> Model -> Html Msg
|
||||||
view2 flags model =
|
view2 texts flags model =
|
||||||
case model.detailModel of
|
case model.detailModel of
|
||||||
Just dm ->
|
Just dm ->
|
||||||
viewDetail2 flags dm
|
viewDetail2 texts flags dm
|
||||||
|
|
||||||
Nothing ->
|
Nothing ->
|
||||||
viewTable2 model
|
viewTable2 texts model
|
||||||
|
|
||||||
|
|
||||||
viewDetail2 : Flags -> Comp.FolderDetail.Model -> Html Msg
|
viewDetail2 : Texts -> Flags -> Comp.FolderDetail.Model -> Html Msg
|
||||||
viewDetail2 flags model =
|
viewDetail2 texts flags model =
|
||||||
div []
|
div []
|
||||||
[ if model.folder.id == "" then
|
[ if model.folder.id == "" then
|
||||||
h3 [ class S.header2 ]
|
h3 [ class S.header2 ]
|
||||||
[ text "Create new Folder"
|
[ text texts.createNewFolder
|
||||||
]
|
]
|
||||||
|
|
||||||
else
|
else
|
||||||
h3 [ class S.header2 ]
|
h3 [ class S.header2 ]
|
||||||
[ text model.folder.name
|
[ text model.folder.name
|
||||||
, div [ class "opacity-50 text-sm" ]
|
, div [ class "opacity-50 text-sm" ]
|
||||||
[ text "Id: "
|
[ text (texts.basics.id ++ ": ")
|
||||||
, text model.folder.id
|
, text model.folder.id
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, Html.map DetailMsg (Comp.FolderDetail.view2 flags model)
|
, Html.map DetailMsg
|
||||||
|
(Comp.FolderDetail.view2 texts.folderDetail
|
||||||
|
flags
|
||||||
|
model
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewTable2 : Model -> Html Msg
|
viewTable2 : Texts -> Model -> Html Msg
|
||||||
viewTable2 model =
|
viewTable2 texts model =
|
||||||
div [ class "flex flex-col" ]
|
div [ class "flex flex-col" ]
|
||||||
[ MB.view
|
[ MB.view
|
||||||
{ start =
|
{ start =
|
||||||
[ MB.TextInput
|
[ MB.TextInput
|
||||||
{ tagger = SetQuery
|
{ tagger = SetQuery
|
||||||
, value = model.query
|
, value = model.query
|
||||||
, placeholder = "Search…"
|
, placeholder = texts.basics.searchPlaceholder
|
||||||
, icon = Just "fa fa-search"
|
, icon = Just "fa fa-search"
|
||||||
}
|
}
|
||||||
, MB.Checkbox
|
, MB.Checkbox
|
||||||
{ tagger = \_ -> ToggleOwningOnly
|
{ tagger = \_ -> ToggleOwningOnly
|
||||||
, label = "Show owning folders only"
|
, label = texts.showOwningFoldersOnly
|
||||||
, value = model.owningOnly
|
, value = model.owningOnly
|
||||||
, id = "folder-toggle-owner"
|
, id = "folder-toggle-owner"
|
||||||
}
|
}
|
||||||
@ -219,14 +224,19 @@ viewTable2 model =
|
|||||||
, end =
|
, end =
|
||||||
[ MB.PrimaryButton
|
[ MB.PrimaryButton
|
||||||
{ tagger = InitNewFolder
|
{ tagger = InitNewFolder
|
||||||
, title = "Create a new folder"
|
, title = texts.createNewFolder
|
||||||
, icon = Just "fa fa-plus"
|
, icon = Just "fa fa-plus"
|
||||||
, label = "New Folder"
|
, label = texts.newFolder
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
, rootClasses = "mb-4"
|
, rootClasses = "mb-4"
|
||||||
}
|
}
|
||||||
, Html.map TableMsg (Comp.FolderTable.view2 model.tableModel model.folders)
|
, Html.map TableMsg
|
||||||
|
(Comp.FolderTable.view2
|
||||||
|
texts.folderTable
|
||||||
|
model.tableModel
|
||||||
|
model.folders
|
||||||
|
)
|
||||||
, div
|
, div
|
||||||
[ classList
|
[ classList
|
||||||
[ ( "ui dimmer", True )
|
[ ( "ui dimmer", True )
|
||||||
|
@ -156,25 +156,20 @@ viewDrop2 dropModel constr model =
|
|||||||
highlightDrop =
|
highlightDrop =
|
||||||
DD.getDropId dropModel == Just DD.FolderRemove
|
DD.getDropId dropModel == Just DD.FolderRemove
|
||||||
in
|
in
|
||||||
div [ class "ui list" ]
|
div []
|
||||||
[ div [ class "item" ]
|
[ div
|
||||||
[ i [ class "folder open icon" ] []
|
(classList
|
||||||
, div [ class "content" ]
|
[ ( "hidden", True )
|
||||||
[ div
|
, ( "current-drop-target", highlightDrop )
|
||||||
(classList
|
|
||||||
[ ( "hidden", True )
|
|
||||||
, ( "current-drop-target", highlightDrop )
|
|
||||||
]
|
|
||||||
:: DD.droppable FolderDDMsg DD.FolderRemove
|
|
||||||
-- note: re-enable this when adding a "no-folder selection"
|
|
||||||
-- this enables a drop target that removes a folder
|
|
||||||
)
|
|
||||||
[ text "Folders"
|
|
||||||
]
|
|
||||||
, div [ class "flex flex-col space-y-2 md:space-y-1" ]
|
|
||||||
(renderItems2 dropModel constr model)
|
|
||||||
]
|
]
|
||||||
|
:: DD.droppable FolderDDMsg DD.FolderRemove
|
||||||
|
-- note: re-enable this when adding a "no-folder selection"
|
||||||
|
-- this enables a drop target that removes a folder
|
||||||
|
)
|
||||||
|
[ text "Folders"
|
||||||
]
|
]
|
||||||
|
, div [ class "flex flex-col space-y-2 md:space-y-1" ]
|
||||||
|
(renderItems2 dropModel constr model)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import Api.Model.FolderItem exposing (FolderItem)
|
|||||||
import Comp.Basic as B
|
import Comp.Basic as B
|
||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
|
import Messages.Comp.FolderTable exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.Time
|
import Util.Time
|
||||||
|
|
||||||
@ -44,23 +45,27 @@ update msg model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : Model -> List FolderItem -> Html Msg
|
view2 : Texts -> Model -> List FolderItem -> Html Msg
|
||||||
view2 _ items =
|
view2 texts _ items =
|
||||||
table [ class S.tableMain ]
|
table [ class S.tableMain ]
|
||||||
[ thead []
|
[ thead []
|
||||||
[ tr []
|
[ tr []
|
||||||
[ th [ class "w-px whitespace-nowrap pr-1 md:pr-3" ] []
|
[ th [ class "w-px whitespace-nowrap pr-1 md:pr-3" ] []
|
||||||
, th [ class "text-left" ] [ text "Name" ]
|
, th [ class "text-left" ]
|
||||||
|
[ text texts.basics.name
|
||||||
|
]
|
||||||
, th [ class "text-left hidden sm:table-cell" ] [ text "Owner" ]
|
, th [ class "text-left hidden sm:table-cell" ] [ text "Owner" ]
|
||||||
, th [ class "text-center" ]
|
, th [ class "text-center" ]
|
||||||
[ span [ class "hidden sm:inline" ]
|
[ span [ class "hidden sm:inline" ]
|
||||||
[ text "#Member"
|
[ text texts.memberCount
|
||||||
]
|
]
|
||||||
, span [ class "sm:hidden" ]
|
, span [ class "sm:hidden" ]
|
||||||
[ text "#"
|
[ text "#"
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, th [ class "text-center" ] [ text "Created" ]
|
, th [ class "text-center" ]
|
||||||
|
[ text texts.basics.created
|
||||||
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, tbody []
|
, tbody []
|
||||||
|
@ -21,6 +21,7 @@ import Data.UiSettings exposing (UiSettings)
|
|||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onInput)
|
import Html.Events exposing (onInput)
|
||||||
|
import Messages.Comp.ImapSettingsForm exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.Maybe
|
import Util.Maybe
|
||||||
|
|
||||||
@ -45,21 +46,14 @@ emptyModel =
|
|||||||
{ settings = Api.Model.ImapSettings.empty
|
{ settings = Api.Model.ImapSettings.empty
|
||||||
, name = ""
|
, name = ""
|
||||||
, host = ""
|
, host = ""
|
||||||
, portField = Comp.IntField.init (Just 0) Nothing True "IMAP Port"
|
, portField = Comp.IntField.init (Just 0) Nothing True
|
||||||
, portNum = Nothing
|
, portNum = Nothing
|
||||||
, user = Nothing
|
, user = Nothing
|
||||||
, passField = Comp.PasswordInput.init
|
, passField = Comp.PasswordInput.init
|
||||||
, password = Nothing
|
, password = Nothing
|
||||||
, sslType =
|
, sslType =
|
||||||
Comp.Dropdown.makeSingleList
|
Comp.Dropdown.makeSingleList
|
||||||
{ makeOption =
|
{ options = Data.SSLType.all
|
||||||
\s ->
|
|
||||||
{ value = Data.SSLType.toString s
|
|
||||||
, text = Data.SSLType.label s
|
|
||||||
, additional = ""
|
|
||||||
}
|
|
||||||
, placeholder = ""
|
|
||||||
, options = Data.SSLType.all
|
|
||||||
, selected = Just Data.SSLType.None
|
, selected = Just Data.SSLType.None
|
||||||
}
|
}
|
||||||
, ignoreCertificates = False
|
, ignoreCertificates = False
|
||||||
@ -72,21 +66,14 @@ init ems =
|
|||||||
{ settings = ems
|
{ settings = ems
|
||||||
, name = ems.name
|
, name = ems.name
|
||||||
, host = ems.imapHost
|
, host = ems.imapHost
|
||||||
, portField = Comp.IntField.init (Just 0) Nothing True "IMAP Port"
|
, portField = Comp.IntField.init (Just 0) Nothing True
|
||||||
, portNum = ems.imapPort
|
, portNum = ems.imapPort
|
||||||
, user = ems.imapUser
|
, user = ems.imapUser
|
||||||
, passField = Comp.PasswordInput.init
|
, passField = Comp.PasswordInput.init
|
||||||
, password = ems.imapPassword
|
, password = ems.imapPassword
|
||||||
, sslType =
|
, sslType =
|
||||||
Comp.Dropdown.makeSingleList
|
Comp.Dropdown.makeSingleList
|
||||||
{ makeOption =
|
{ options = Data.SSLType.all
|
||||||
\s ->
|
|
||||||
{ value = Data.SSLType.toString s
|
|
||||||
, text = Data.SSLType.label s
|
|
||||||
, additional = ""
|
|
||||||
}
|
|
||||||
, placeholder = ""
|
|
||||||
, options = Data.SSLType.all
|
|
||||||
, selected =
|
, selected =
|
||||||
Data.SSLType.fromString ems.sslType
|
Data.SSLType.fromString ems.sslType
|
||||||
|> Maybe.withDefault Data.SSLType.None
|
|> Maybe.withDefault Data.SSLType.None
|
||||||
@ -176,20 +163,32 @@ update msg model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : UiSettings -> Model -> Html Msg
|
view2 : Texts -> UiSettings -> Model -> Html Msg
|
||||||
view2 settings model =
|
view2 texts settings model =
|
||||||
|
let
|
||||||
|
sslCfg =
|
||||||
|
{ makeOption =
|
||||||
|
\s ->
|
||||||
|
{ text = texts.sslTypeLabel s
|
||||||
|
, additional = ""
|
||||||
|
}
|
||||||
|
, placeholder = ""
|
||||||
|
, labelColor = \_ -> \_ -> ""
|
||||||
|
, style = DS.mainStyle
|
||||||
|
}
|
||||||
|
in
|
||||||
div
|
div
|
||||||
[ class "grid grid-cols-4 gap-y-4 gap-x-2" ]
|
[ class "grid grid-cols-4 gap-y-4 gap-x-2" ]
|
||||||
[ div [ class "col-span-4" ]
|
[ div [ class "col-span-4" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "Name"
|
[ text texts.basics.name
|
||||||
, B.inputRequired
|
, B.inputRequired
|
||||||
]
|
]
|
||||||
, input
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
, value model.name
|
, value model.name
|
||||||
, onInput SetName
|
, onInput SetName
|
||||||
, placeholder "Connection name, e.g. 'gmail.com'"
|
, placeholder texts.connectionNamePlaceholder
|
||||||
, class S.textInput
|
, class S.textInput
|
||||||
, classList [ ( S.inputErrorBorder, model.name == "" ) ]
|
, classList [ ( S.inputErrorBorder, model.name == "" ) ]
|
||||||
]
|
]
|
||||||
@ -198,17 +197,17 @@ view2 settings model =
|
|||||||
[ class S.message
|
[ class S.message
|
||||||
, class "mt-2"
|
, class "mt-2"
|
||||||
]
|
]
|
||||||
[ text "The connection name must not contain whitespace or special characters."
|
[ text texts.connectionNameInfo
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div [ class "col-span-3" ]
|
, div [ class "col-span-3" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "IMAP Host"
|
[ text texts.imapHost
|
||||||
, B.inputRequired
|
, B.inputRequired
|
||||||
]
|
]
|
||||||
, input
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
, placeholder "IMAP host name, e.g. 'mail.gmail.com'"
|
, placeholder texts.imapHostPlaceholder
|
||||||
, value model.host
|
, value model.host
|
||||||
, onInput SetHost
|
, onInput SetHost
|
||||||
, class S.textInput
|
, class S.textInput
|
||||||
@ -217,18 +216,21 @@ view2 settings model =
|
|||||||
[]
|
[]
|
||||||
]
|
]
|
||||||
, Html.map PortMsg
|
, Html.map PortMsg
|
||||||
(Comp.IntField.viewWithInfo2 ""
|
(Comp.IntField.view
|
||||||
model.portNum
|
{ label = texts.imapPort
|
||||||
""
|
, info = ""
|
||||||
|
, number = model.portNum
|
||||||
|
, classes = ""
|
||||||
|
}
|
||||||
model.portField
|
model.portField
|
||||||
)
|
)
|
||||||
, div [ class "col-span-4 sm:col-span-2" ]
|
, div [ class "col-span-4 sm:col-span-2" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "IMAP User"
|
[ text texts.imapUser
|
||||||
]
|
]
|
||||||
, input
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
, placeholder "IMAP Username, e.g. 'your.name@gmail.com'"
|
, placeholder texts.imapUserPlaceholder
|
||||||
, Maybe.withDefault "" model.user |> value
|
, Maybe.withDefault "" model.user |> value
|
||||||
, onInput SetUser
|
, onInput SetUser
|
||||||
, class S.textInput
|
, class S.textInput
|
||||||
@ -237,9 +239,10 @@ view2 settings model =
|
|||||||
]
|
]
|
||||||
, div [ class "col-span-4 sm:col-span-2" ]
|
, div [ class "col-span-4 sm:col-span-2" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "IMAP Password" ]
|
[ text texts.imapPassword ]
|
||||||
, Html.map PassMsg
|
, Html.map PassMsg
|
||||||
(Comp.PasswordInput.view2
|
(Comp.PasswordInput.view2
|
||||||
|
{ placeholder = texts.imapPasswordPlaceholder }
|
||||||
model.password
|
model.password
|
||||||
False
|
False
|
||||||
model.passField
|
model.passField
|
||||||
@ -247,11 +250,11 @@ view2 settings model =
|
|||||||
]
|
]
|
||||||
, div [ class "col-span-4 sm:col-span-2" ]
|
, div [ class "col-span-4 sm:col-span-2" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "SSL"
|
[ text texts.ssl
|
||||||
]
|
]
|
||||||
, Html.map SSLTypeMsg
|
, Html.map SSLTypeMsg
|
||||||
(Comp.Dropdown.view2
|
(Comp.Dropdown.view2
|
||||||
DS.mainStyle
|
sslCfg
|
||||||
settings
|
settings
|
||||||
model.sslType
|
model.sslType
|
||||||
)
|
)
|
||||||
@ -260,7 +263,7 @@ view2 settings model =
|
|||||||
[ MB.viewItem <|
|
[ MB.viewItem <|
|
||||||
MB.Checkbox
|
MB.Checkbox
|
||||||
{ tagger = \_ -> ToggleCheckCert
|
{ tagger = \_ -> ToggleCheckCert
|
||||||
, label = "Ignore certificate check"
|
, label = texts.ignoreCertCheck
|
||||||
, value = model.ignoreCertificates
|
, value = model.ignoreCertificates
|
||||||
, id = "imap-no-cert-check"
|
, id = "imap-no-cert-check"
|
||||||
}
|
}
|
||||||
@ -269,12 +272,12 @@ view2 settings model =
|
|||||||
[ MB.viewItem <|
|
[ MB.viewItem <|
|
||||||
MB.Checkbox
|
MB.Checkbox
|
||||||
{ tagger = \_ -> ToggleUseOAuth
|
{ tagger = \_ -> ToggleUseOAuth
|
||||||
, label = "Enable OAuth2 authentication"
|
, label = texts.enableOAuth2
|
||||||
, value = model.useOAuthToken
|
, value = model.useOAuthToken
|
||||||
, id = "imap-use-oauth"
|
, id = "imap-use-oauth"
|
||||||
}
|
}
|
||||||
, div [ class "opacity-50 text-sm" ]
|
, div [ class "opacity-50 text-sm" ]
|
||||||
[ text "Enabling this, allows to connect via XOAuth using the password as access token."
|
[ text texts.oauth2Info
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
@ -21,6 +21,7 @@ import Data.UiSettings exposing (UiSettings)
|
|||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Http
|
import Http
|
||||||
|
import Messages.Comp.ImapSettingsManage exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.Http
|
import Util.Http
|
||||||
|
|
||||||
@ -206,74 +207,77 @@ update flags msg model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : UiSettings -> Model -> Html Msg
|
view2 : Texts -> UiSettings -> Model -> Html Msg
|
||||||
view2 settings model =
|
view2 texts settings model =
|
||||||
case model.viewMode of
|
case model.viewMode of
|
||||||
Table ->
|
Table ->
|
||||||
viewTable2 model
|
viewTable2 texts model
|
||||||
|
|
||||||
Form ->
|
Form ->
|
||||||
viewForm2 settings model
|
viewForm2 texts settings model
|
||||||
|
|
||||||
|
|
||||||
viewTable2 : Model -> Html Msg
|
viewTable2 : Texts -> Model -> Html Msg
|
||||||
viewTable2 model =
|
viewTable2 texts model =
|
||||||
div []
|
div []
|
||||||
[ MB.view
|
[ MB.view
|
||||||
{ start =
|
{ start =
|
||||||
[ MB.TextInput
|
[ MB.TextInput
|
||||||
{ tagger = SetQuery
|
{ tagger = SetQuery
|
||||||
, value = model.query
|
, value = model.query
|
||||||
, placeholder = "Search…"
|
, placeholder = texts.basics.searchPlaceholder
|
||||||
, icon = Just "fa fa-search"
|
, icon = Just "fa fa-search"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
, end =
|
, end =
|
||||||
[ MB.PrimaryButton
|
[ MB.PrimaryButton
|
||||||
{ tagger = InitNew
|
{ tagger = InitNew
|
||||||
, title = "Add new SMTP settings"
|
, title = texts.addNewImapSettings
|
||||||
, icon = Just "fa fa-plus"
|
, icon = Just "fa fa-plus"
|
||||||
, label = "New Settings"
|
, label = texts.newSettings
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
, rootClasses = "mb-4"
|
, rootClasses = "mb-4"
|
||||||
}
|
}
|
||||||
, Html.map TableMsg
|
, Html.map TableMsg
|
||||||
(Comp.ImapSettingsTable.view2
|
(Comp.ImapSettingsTable.view2
|
||||||
|
texts.imapTable
|
||||||
model.tableModel
|
model.tableModel
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewForm2 : UiSettings -> Model -> Html Msg
|
viewForm2 : Texts -> UiSettings -> Model -> Html Msg
|
||||||
viewForm2 settings model =
|
viewForm2 texts settings model =
|
||||||
let
|
let
|
||||||
dimmerSettings =
|
dimmerSettings =
|
||||||
Comp.YesNoDimmer.defaultSettings2 "Really delete this mail-box connection?"
|
Comp.YesNoDimmer.defaultSettings texts.reallyDeleteSettings
|
||||||
|
texts.basics.yes
|
||||||
|
texts.basics.no
|
||||||
in
|
in
|
||||||
div [ class "flex flex-col md:relative" ]
|
div [ class "flex flex-col md:relative" ]
|
||||||
[ MB.view
|
[ MB.view
|
||||||
{ start =
|
{ start =
|
||||||
[ MB.PrimaryButton
|
[ MB.PrimaryButton
|
||||||
{ tagger = Submit
|
{ tagger = Submit
|
||||||
, title = "Submit this form"
|
, title = texts.basics.submitThisForm
|
||||||
, icon = Just "fa fa-save"
|
, icon = Just "fa fa-save"
|
||||||
, label = "Submit"
|
, label = texts.basics.submit
|
||||||
}
|
}
|
||||||
, MB.SecondaryButton
|
, MB.SecondaryButton
|
||||||
{ tagger = SetViewMode Table
|
{ tagger = SetViewMode Table
|
||||||
, title = "Back to list"
|
, title = texts.basics.backToList
|
||||||
, icon = Just "fa fa-arrow-left"
|
, icon = Just "fa fa-arrow-left"
|
||||||
, label = "Cancel"
|
, label = texts.basics.cancel
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
, end =
|
, end =
|
||||||
if model.formModel.settings.name /= "" then
|
if model.formModel.settings.name /= "" then
|
||||||
[ MB.DeleteButton
|
[ MB.DeleteButton
|
||||||
{ tagger = RequestDelete
|
{ tagger = RequestDelete
|
||||||
, title = "Delete this settings entry"
|
, title = texts.deleteThisEntry
|
||||||
, icon = Just "fa fa-trash"
|
, icon = Just "fa fa-trash"
|
||||||
, label = "Delete"
|
, label = texts.basics.delete
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -292,6 +296,7 @@ viewForm2 settings model =
|
|||||||
]
|
]
|
||||||
, Html.map FormMsg
|
, Html.map FormMsg
|
||||||
(Comp.ImapSettingsForm.view2
|
(Comp.ImapSettingsForm.view2
|
||||||
|
texts.imapForm
|
||||||
settings
|
settings
|
||||||
model.formModel
|
model.formModel
|
||||||
)
|
)
|
||||||
@ -301,5 +306,8 @@ viewForm2 settings model =
|
|||||||
dimmerSettings
|
dimmerSettings
|
||||||
model.deleteConfirm
|
model.deleteConfirm
|
||||||
)
|
)
|
||||||
, B.loadingDimmer model.loading
|
, B.loadingDimmer
|
||||||
|
{ active = model.loading
|
||||||
|
, label = texts.basics.loading
|
||||||
|
}
|
||||||
]
|
]
|
||||||
|
@ -11,6 +11,7 @@ import Api.Model.ImapSettings exposing (ImapSettings)
|
|||||||
import Comp.Basic as B
|
import Comp.Basic as B
|
||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
|
import Messages.Comp.ImapSettingsTable exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
|
|
||||||
|
|
||||||
@ -47,14 +48,14 @@ update msg model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : Model -> Html Msg
|
view2 : Texts -> Model -> Html Msg
|
||||||
view2 model =
|
view2 texts model =
|
||||||
table [ class S.tableMain ]
|
table [ class S.tableMain ]
|
||||||
[ thead []
|
[ thead []
|
||||||
[ tr []
|
[ tr []
|
||||||
[ th [] []
|
[ th [] []
|
||||||
, th [ class "text-left mr-2" ] [ text "Name" ]
|
, th [ class "text-left mr-2" ] [ text texts.basics.name ]
|
||||||
, th [ class "text-left mr-2" ] [ text "Host/Port" ]
|
, th [ class "text-left mr-2" ] [ text texts.hostPort ]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, tbody []
|
, tbody []
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
module Comp.IntField exposing
|
module Comp.IntField exposing
|
||||||
( Model
|
( Model
|
||||||
, Msg
|
, Msg
|
||||||
|
, ViewSettings
|
||||||
, init
|
, init
|
||||||
, update
|
, update
|
||||||
, viewWithInfo2
|
, view
|
||||||
)
|
)
|
||||||
|
|
||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
@ -16,7 +17,6 @@ import Styles as S
|
|||||||
type alias Model =
|
type alias Model =
|
||||||
{ min : Maybe Int
|
{ min : Maybe Int
|
||||||
, max : Maybe Int
|
, max : Maybe Int
|
||||||
, label : String
|
|
||||||
, error : Maybe String
|
, error : Maybe String
|
||||||
, lastInput : String
|
, lastInput : String
|
||||||
, optional : Bool
|
, optional : Bool
|
||||||
@ -27,11 +27,10 @@ type Msg
|
|||||||
= SetValue String
|
= SetValue String
|
||||||
|
|
||||||
|
|
||||||
init : Maybe Int -> Maybe Int -> Bool -> String -> Model
|
init : Maybe Int -> Maybe Int -> Bool -> Model
|
||||||
init min max opt label =
|
init min max opt =
|
||||||
{ min = min
|
{ min = min
|
||||||
, max = max
|
, max = max
|
||||||
, label = label
|
|
||||||
, error = Nothing
|
, error = Nothing
|
||||||
, lastInput = ""
|
, lastInput = ""
|
||||||
, optional = opt
|
, optional = opt
|
||||||
@ -98,20 +97,28 @@ update msg model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
viewWithInfo2 : String -> Maybe Int -> String -> Model -> Html Msg
|
type alias ViewSettings =
|
||||||
viewWithInfo2 info nval classes model =
|
{ label : String
|
||||||
|
, info : String
|
||||||
|
, number : Maybe Int
|
||||||
|
, classes : String
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
view : ViewSettings -> Model -> Html Msg
|
||||||
|
view cfg model =
|
||||||
div
|
div
|
||||||
[ classList
|
[ classList
|
||||||
[ ( classes, True )
|
[ ( cfg.classes, True )
|
||||||
, ( "error", model.error /= Nothing )
|
, ( "error", model.error /= Nothing )
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text model.label
|
[ text cfg.label
|
||||||
]
|
]
|
||||||
, input
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
, Maybe.map String.fromInt nval
|
, Maybe.map String.fromInt cfg.number
|
||||||
|> Maybe.withDefault model.lastInput
|
|> Maybe.withDefault model.lastInput
|
||||||
|> value
|
|> value
|
||||||
, onInput SetValue
|
, onInput SetValue
|
||||||
@ -120,11 +127,11 @@ viewWithInfo2 info nval classes model =
|
|||||||
[]
|
[]
|
||||||
, span
|
, span
|
||||||
[ classList
|
[ classList
|
||||||
[ ( "hidden", info == "" )
|
[ ( "hidden", cfg.info == "" )
|
||||||
]
|
]
|
||||||
, class "opacity-50 text-sm"
|
, class "opacity-50 text-sm"
|
||||||
]
|
]
|
||||||
[ Markdown.toHtml [] info
|
[ Markdown.toHtml [] cfg.info
|
||||||
]
|
]
|
||||||
, div
|
, div
|
||||||
[ classList
|
[ classList
|
||||||
@ -135,3 +142,16 @@ viewWithInfo2 info nval classes model =
|
|||||||
[ Maybe.withDefault "" model.error |> text
|
[ Maybe.withDefault "" model.error |> text
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
viewWithInfo2 : String -> String -> Maybe Int -> String -> Model -> Html Msg
|
||||||
|
viewWithInfo2 label info nval classes model =
|
||||||
|
let
|
||||||
|
cfg =
|
||||||
|
{ label = label
|
||||||
|
, info = info
|
||||||
|
, number = nval
|
||||||
|
, classes = classes
|
||||||
|
}
|
||||||
|
in
|
||||||
|
view cfg model
|
||||||
|
@ -23,6 +23,7 @@ import Html exposing (..)
|
|||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onClick)
|
import Html.Events exposing (onClick)
|
||||||
import Markdown
|
import Markdown
|
||||||
|
import Messages.Comp.ItemCard exposing (Texts)
|
||||||
import Page exposing (Page(..))
|
import Page exposing (Page(..))
|
||||||
import Set exposing (Set)
|
import Set exposing (Set)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
@ -135,12 +136,11 @@ update ddm msg model =
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- View
|
|
||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : ViewConfig -> UiSettings -> Model -> ItemLight -> Html Msg
|
view2 : Texts -> ViewConfig -> UiSettings -> Model -> ItemLight -> Html Msg
|
||||||
view2 cfg settings model item =
|
view2 texts cfg settings model item =
|
||||||
let
|
let
|
||||||
isConfirmed =
|
isConfirmed =
|
||||||
item.state /= "created"
|
item.state /= "created"
|
||||||
@ -200,11 +200,11 @@ view2 cfg settings model item =
|
|||||||
[ previewImage2 settings cardAction model item
|
[ previewImage2 settings cardAction model item
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
++ [ mainContent2 cardAction cardColor isConfirmed settings cfg item
|
++ [ mainContent2 texts cardAction cardColor isConfirmed settings cfg item
|
||||||
, metaDataContent2 settings item
|
, metaDataContent2 texts settings item
|
||||||
, notesContent2 settings item
|
, notesContent2 settings item
|
||||||
, fulltextResultsContent2 item
|
, fulltextResultsContent2 item
|
||||||
, previewMenu2 settings model item (currentAttachment model item)
|
, previewMenu2 texts settings model item (currentAttachment model item)
|
||||||
, selectedDimmer
|
, selectedDimmer
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@ -221,8 +221,8 @@ fulltextResultsContent2 item =
|
|||||||
(List.map renderHighlightEntry2 item.highlighting)
|
(List.map renderHighlightEntry2 item.highlighting)
|
||||||
|
|
||||||
|
|
||||||
metaDataContent2 : UiSettings -> ItemLight -> Html Msg
|
metaDataContent2 : Texts -> UiSettings -> ItemLight -> Html Msg
|
||||||
metaDataContent2 settings item =
|
metaDataContent2 texts settings item =
|
||||||
let
|
let
|
||||||
fieldHidden f =
|
fieldHidden f =
|
||||||
Data.UiSettings.fieldHidden settings f
|
Data.UiSettings.fieldHidden settings f
|
||||||
@ -234,7 +234,7 @@ metaDataContent2 settings item =
|
|||||||
[ ( "hidden", fieldHidden Data.Fields.Folder )
|
[ ( "hidden", fieldHidden Data.Fields.Folder )
|
||||||
]
|
]
|
||||||
, class "hover:opacity-60"
|
, class "hover:opacity-60"
|
||||||
, title "Folder"
|
, title texts.basics.folder
|
||||||
]
|
]
|
||||||
[ Icons.folderIcon2 "mr-2"
|
[ Icons.folderIcon2 "mr-2"
|
||||||
, Comp.LinkTarget.makeFolderLink item
|
, Comp.LinkTarget.makeFolderLink item
|
||||||
@ -273,8 +273,16 @@ notesContent2 settings item =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
mainContent2 : List (Attribute Msg) -> String -> Bool -> UiSettings -> ViewConfig -> ItemLight -> Html Msg
|
mainContent2 :
|
||||||
mainContent2 cardAction cardColor isConfirmed settings _ item =
|
Texts
|
||||||
|
-> List (Attribute Msg)
|
||||||
|
-> String
|
||||||
|
-> Bool
|
||||||
|
-> UiSettings
|
||||||
|
-> ViewConfig
|
||||||
|
-> ItemLight
|
||||||
|
-> Html Msg
|
||||||
|
mainContent2 texts cardAction cardColor isConfirmed settings _ item =
|
||||||
let
|
let
|
||||||
dirIcon =
|
dirIcon =
|
||||||
i
|
i
|
||||||
@ -303,7 +311,7 @@ mainContent2 cardAction cardColor isConfirmed settings _ item =
|
|||||||
&& fieldHidden Data.Fields.CorrPerson
|
&& fieldHidden Data.Fields.CorrPerson
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
, title "Correspondent"
|
, title texts.basics.correspondent
|
||||||
]
|
]
|
||||||
(Icons.correspondentIcon2 "mr-2 w-4 text-center"
|
(Icons.correspondentIcon2 "mr-2 w-4 text-center"
|
||||||
:: Comp.LinkTarget.makeCorrLink item [ ( "hover:opacity-75", True ) ] SetLinkTarget
|
:: Comp.LinkTarget.makeCorrLink item [ ( "hover:opacity-75", True ) ] SetLinkTarget
|
||||||
@ -315,7 +323,7 @@ mainContent2 cardAction cardColor isConfirmed settings _ item =
|
|||||||
&& fieldHidden Data.Fields.ConcEquip
|
&& fieldHidden Data.Fields.ConcEquip
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
, title "Concerning"
|
, title texts.basics.concerning
|
||||||
]
|
]
|
||||||
(Icons.concernedIcon2 "mr-2 w-4 text-center"
|
(Icons.concernedIcon2 "mr-2 w-4 text-center"
|
||||||
:: Comp.LinkTarget.makeConcLink item [ ( "hover:opacity-75", True ) ] SetLinkTarget
|
:: Comp.LinkTarget.makeConcLink item [ ( "hover:opacity-75", True ) ] SetLinkTarget
|
||||||
@ -332,7 +340,7 @@ mainContent2 cardAction cardColor isConfirmed settings _ item =
|
|||||||
, ( cardColor, True )
|
, ( cardColor, True )
|
||||||
, ( "hidden", isConfirmed )
|
, ( "hidden", isConfirmed )
|
||||||
]
|
]
|
||||||
, title "New"
|
, title texts.new
|
||||||
]
|
]
|
||||||
[ i [ class "ml-2 fa fa-exclamation-circle" ] []
|
[ i [ class "ml-2 fa fa-exclamation-circle" ] []
|
||||||
]
|
]
|
||||||
@ -432,8 +440,8 @@ previewImage2 settings cardAction model item =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
previewMenu2 : UiSettings -> Model -> ItemLight -> Maybe AttachmentLight -> Html Msg
|
previewMenu2 : Texts -> UiSettings -> Model -> ItemLight -> Maybe AttachmentLight -> Html Msg
|
||||||
previewMenu2 settings model item mainAttach =
|
previewMenu2 texts settings model item mainAttach =
|
||||||
let
|
let
|
||||||
pageCount =
|
pageCount =
|
||||||
Maybe.andThen .pageCount mainAttach
|
Maybe.andThen .pageCount mainAttach
|
||||||
@ -470,7 +478,7 @@ previewMenu2 settings model item mainAttach =
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
, class "label font-semibold text-sm border-gray-300 dark:border-bluegray-600"
|
, class "label font-semibold text-sm border-gray-300 dark:border-bluegray-600"
|
||||||
, title ("Due on " ++ dueDate)
|
, title (texts.dueOn ++ " " ++ dueDate)
|
||||||
]
|
]
|
||||||
[ Icons.dueDateIcon2 "mr-2"
|
[ Icons.dueDateIcon2 "mr-2"
|
||||||
, text (" " ++ dueDate)
|
, text (" " ++ dueDate)
|
||||||
@ -482,7 +490,7 @@ previewMenu2 settings model item mainAttach =
|
|||||||
, class "px-2 py-1 border rounded "
|
, class "px-2 py-1 border rounded "
|
||||||
, href attachUrl
|
, href attachUrl
|
||||||
, target "_self"
|
, target "_self"
|
||||||
, title "Open attachment file"
|
, title texts.openAttachmentFile
|
||||||
]
|
]
|
||||||
[ i [ class "fa fa-eye" ] []
|
[ i [ class "fa fa-eye" ] []
|
||||||
]
|
]
|
||||||
@ -490,7 +498,7 @@ previewMenu2 settings model item mainAttach =
|
|||||||
[ class S.secondaryBasicButtonPlain
|
[ class S.secondaryBasicButtonPlain
|
||||||
, class "px-2 py-1 border rounded ml-2"
|
, class "px-2 py-1 border rounded ml-2"
|
||||||
, Page.href (ItemDetailPage item.id)
|
, Page.href (ItemDetailPage item.id)
|
||||||
, title "Go to detail view"
|
, title texts.gotoDetail
|
||||||
]
|
]
|
||||||
[ i [ class "fa fa-edit" ] []
|
[ i [ class "fa fa-edit" ] []
|
||||||
]
|
]
|
||||||
@ -510,7 +518,7 @@ previewMenu2 settings model item mainAttach =
|
|||||||
[ a
|
[ a
|
||||||
[ class S.secondaryBasicButtonPlain
|
[ class S.secondaryBasicButtonPlain
|
||||||
, class "px-2 py-1 border rounded-l block"
|
, class "px-2 py-1 border rounded-l block"
|
||||||
, title "Cycle attachments"
|
, title texts.cycleAttachments
|
||||||
, href "#"
|
, href "#"
|
||||||
, onClick (CyclePreview item)
|
, onClick (CyclePreview item)
|
||||||
]
|
]
|
||||||
|
@ -22,6 +22,7 @@ import Data.UiSettings exposing (UiSettings)
|
|||||||
import Dict exposing (Dict)
|
import Dict exposing (Dict)
|
||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
|
import Messages.Comp.ItemCardList exposing (Texts)
|
||||||
import Page exposing (Page(..))
|
import Page exposing (Page(..))
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.ItemDragDrop as DD
|
import Util.ItemDragDrop as DD
|
||||||
@ -148,19 +149,19 @@ type alias ViewConfig =
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
view2 : ViewConfig -> UiSettings -> Model -> Html Msg
|
view2 : Texts -> ViewConfig -> UiSettings -> Model -> Html Msg
|
||||||
view2 cfg settings model =
|
view2 texts cfg settings model =
|
||||||
div
|
div
|
||||||
[ classList
|
[ classList
|
||||||
[ ( "ds-item-list", True )
|
[ ( "ds-item-list", True )
|
||||||
, ( "ds-multi-select-mode", isMultiSelectMode cfg )
|
, ( "ds-multi-select-mode", isMultiSelectMode cfg )
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
(List.map (viewGroup2 model cfg settings) model.results.groups)
|
(List.map (viewGroup2 texts model cfg settings) model.results.groups)
|
||||||
|
|
||||||
|
|
||||||
viewGroup2 : Model -> ViewConfig -> UiSettings -> ItemLightGroup -> Html Msg
|
viewGroup2 : Texts -> Model -> ViewConfig -> UiSettings -> ItemLightGroup -> Html Msg
|
||||||
viewGroup2 model cfg settings group =
|
viewGroup2 texts model cfg settings group =
|
||||||
div [ class "ds-item-group" ]
|
div [ class "ds-item-group" ]
|
||||||
[ div
|
[ div
|
||||||
[ class "flex py-0 mt-2 flex flex-row items-center"
|
[ class "flex py-0 mt-2 flex flex-row items-center"
|
||||||
@ -185,12 +186,12 @@ viewGroup2 model cfg settings group =
|
|||||||
[]
|
[]
|
||||||
]
|
]
|
||||||
, div [ class "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4 gap-2" ]
|
, div [ class "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4 gap-2" ]
|
||||||
(List.map (viewItem2 model cfg settings) group.items)
|
(List.map (viewItem2 texts model cfg settings) group.items)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewItem2 : Model -> ViewConfig -> UiSettings -> ItemLight -> Html Msg
|
viewItem2 : Texts -> Model -> ViewConfig -> UiSettings -> ItemLight -> Html Msg
|
||||||
viewItem2 model cfg settings item =
|
viewItem2 texts model cfg settings item =
|
||||||
let
|
let
|
||||||
currentClass =
|
currentClass =
|
||||||
if cfg.current == Just item.id then
|
if cfg.current == Just item.id then
|
||||||
@ -207,7 +208,7 @@ viewItem2 model cfg settings item =
|
|||||||
|> Maybe.withDefault Comp.ItemCard.init
|
|> Maybe.withDefault Comp.ItemCard.init
|
||||||
|
|
||||||
cardHtml =
|
cardHtml =
|
||||||
Comp.ItemCard.view2 vvcfg settings cardModel item
|
Comp.ItemCard.view2 texts.itemCard vvcfg settings cardModel item
|
||||||
in
|
in
|
||||||
Html.map (ItemCardMsg item) cardHtml
|
Html.map (ItemCardMsg item) cardHtml
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import Data.Flags exposing (Flags)
|
|||||||
import Data.ItemNav exposing (ItemNav)
|
import Data.ItemNav exposing (ItemNav)
|
||||||
import Data.UiSettings exposing (UiSettings)
|
import Data.UiSettings exposing (UiSettings)
|
||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
|
import Messages.Comp.ItemDetail exposing (Texts)
|
||||||
import Page exposing (Page(..))
|
import Page exposing (Page(..))
|
||||||
|
|
||||||
|
|
||||||
@ -30,6 +31,6 @@ update =
|
|||||||
Comp.ItemDetail.Update.update
|
Comp.ItemDetail.Update.update
|
||||||
|
|
||||||
|
|
||||||
view2 : ItemNav -> UiSettings -> Model -> Html Msg
|
view2 : Texts -> ItemNav -> UiSettings -> Model -> Html Msg
|
||||||
view2 =
|
view2 =
|
||||||
Comp.ItemDetail.View2.view
|
Comp.ItemDetail.View2.view
|
||||||
|
@ -3,20 +3,20 @@ module Comp.ItemDetail.AddFilesForm exposing (view)
|
|||||||
import Comp.Dropzone
|
import Comp.Dropzone
|
||||||
import Comp.ItemDetail.Model exposing (..)
|
import Comp.ItemDetail.Model exposing (..)
|
||||||
import Comp.Progress
|
import Comp.Progress
|
||||||
import Data.DropdownStyle
|
|
||||||
import Dict
|
import Dict
|
||||||
import File exposing (File)
|
import File exposing (File)
|
||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onCheck, onClick, onInput)
|
import Html.Events exposing (onClick)
|
||||||
|
import Messages.Comp.ItemDetail.AddFilesForm exposing (Texts)
|
||||||
import Set
|
import Set
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.File exposing (makeFileId)
|
import Util.File exposing (makeFileId)
|
||||||
import Util.Size
|
import Util.Size
|
||||||
|
|
||||||
|
|
||||||
view : Model -> Html Msg
|
view : Texts -> Model -> Html Msg
|
||||||
view model =
|
view texts model =
|
||||||
div
|
div
|
||||||
[ classList
|
[ classList
|
||||||
[ ( "hidden", not model.addFilesOpen )
|
[ ( "hidden", not model.addFilesOpen )
|
||||||
@ -25,24 +25,24 @@ view model =
|
|||||||
, class S.box
|
, class S.box
|
||||||
]
|
]
|
||||||
[ div [ class "text-lg font-bold" ]
|
[ div [ class "text-lg font-bold" ]
|
||||||
[ text "Add more files to this item"
|
[ text texts.addMoreFilesToItem
|
||||||
]
|
]
|
||||||
, Html.map AddFilesMsg
|
, Html.map AddFilesMsg
|
||||||
(Comp.Dropzone.view2 model.addFilesModel)
|
(Comp.Dropzone.view2 texts.dropzone model.addFilesModel)
|
||||||
, div [ class "flex flex-row space-x-2 mt-2" ]
|
, div [ class "flex flex-row space-x-2 mt-2" ]
|
||||||
[ button
|
[ button
|
||||||
[ class S.primaryButton
|
[ class S.primaryButton
|
||||||
, href "#"
|
, href "#"
|
||||||
, onClick AddFilesSubmitUpload
|
, onClick AddFilesSubmitUpload
|
||||||
]
|
]
|
||||||
[ text "Submit"
|
[ text texts.basics.submit
|
||||||
]
|
]
|
||||||
, button
|
, button
|
||||||
[ class S.secondaryButton
|
[ class S.secondaryButton
|
||||||
, href "#"
|
, href "#"
|
||||||
, onClick AddFilesReset
|
, onClick AddFilesReset
|
||||||
]
|
]
|
||||||
[ text "Reset"
|
[ text texts.reset
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div
|
, div
|
||||||
@ -52,14 +52,13 @@ view model =
|
|||||||
]
|
]
|
||||||
, class "mt-2"
|
, class "mt-2"
|
||||||
]
|
]
|
||||||
[ text "All files have been uploaded. They are being processed, some data "
|
[ text texts.filesSubmittedInfo
|
||||||
, text "may not be available immediately. "
|
|
||||||
, a
|
, a
|
||||||
[ class S.successMessageLink
|
[ class S.successMessageLink
|
||||||
, href "#"
|
, href "#"
|
||||||
, onClick ReloadItem
|
, onClick ReloadItem
|
||||||
]
|
]
|
||||||
[ text "Refresh now"
|
[ text texts.refreshNow
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div
|
, div
|
||||||
|
@ -3,7 +3,7 @@ module Comp.ItemDetail.EditForm exposing (formTabs, view2)
|
|||||||
import Comp.CustomFieldMultiInput
|
import Comp.CustomFieldMultiInput
|
||||||
import Comp.DatePicker
|
import Comp.DatePicker
|
||||||
import Comp.Dropdown
|
import Comp.Dropdown
|
||||||
import Comp.ItemDetail.FieldTabState as FTabState
|
import Comp.ItemDetail.FieldTabState as FTabState exposing (EditTab(..))
|
||||||
import Comp.ItemDetail.Model
|
import Comp.ItemDetail.Model
|
||||||
exposing
|
exposing
|
||||||
( Model
|
( Model
|
||||||
@ -14,8 +14,10 @@ import Comp.ItemDetail.Model
|
|||||||
)
|
)
|
||||||
import Comp.KeyInput
|
import Comp.KeyInput
|
||||||
import Comp.Tabs as TB
|
import Comp.Tabs as TB
|
||||||
|
import Data.Direction
|
||||||
import Data.DropdownStyle
|
import Data.DropdownStyle
|
||||||
import Data.Fields
|
import Data.Fields
|
||||||
|
import Data.Flags exposing (Flags)
|
||||||
import Data.Icons as Icons
|
import Data.Icons as Icons
|
||||||
import Data.UiSettings exposing (UiSettings)
|
import Data.UiSettings exposing (UiSettings)
|
||||||
import Dict
|
import Dict
|
||||||
@ -23,15 +25,18 @@ import Html exposing (..)
|
|||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onClick, onInput)
|
import Html.Events exposing (onClick, onInput)
|
||||||
import Markdown
|
import Markdown
|
||||||
|
import Messages.Comp.ItemDetail.EditForm exposing (Texts)
|
||||||
import Page exposing (Page(..))
|
import Page exposing (Page(..))
|
||||||
import Set exposing (Set)
|
import Set exposing (Set)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.Folder
|
import Util.Folder
|
||||||
|
import Util.Person
|
||||||
|
import Util.Tag
|
||||||
import Util.Time
|
import Util.Time
|
||||||
|
|
||||||
|
|
||||||
view2 : UiSettings -> Model -> Html Msg
|
view2 : Texts -> Flags -> UiSettings -> Model -> Html Msg
|
||||||
view2 settings model =
|
view2 texts flags settings model =
|
||||||
let
|
let
|
||||||
keyAttr =
|
keyAttr =
|
||||||
if settings.itemDetailShortcuts then
|
if settings.itemDetailShortcuts then
|
||||||
@ -44,10 +49,10 @@ view2 settings model =
|
|||||||
TB.searchMenuStyle
|
TB.searchMenuStyle
|
||||||
|
|
||||||
tabs =
|
tabs =
|
||||||
formTabs settings model
|
formTabs texts flags settings model
|
||||||
|
|
||||||
allTabNames =
|
allTabNames =
|
||||||
List.map .title tabs
|
List.map .name tabs
|
||||||
|> Set.fromList
|
|> Set.fromList
|
||||||
in
|
in
|
||||||
div (class "flex flex-col relative" :: keyAttr)
|
div (class "flex flex-col relative" :: keyAttr)
|
||||||
@ -57,8 +62,8 @@ view2 settings model =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
formTabs : UiSettings -> Model -> List (TB.Tab Msg)
|
formTabs : Texts -> Flags -> UiSettings -> Model -> List (TB.Tab Msg)
|
||||||
formTabs settings model =
|
formTabs texts flags settings model =
|
||||||
let
|
let
|
||||||
dds =
|
dds =
|
||||||
Data.DropdownStyle.sidebarStyle
|
Data.DropdownStyle.sidebarStyle
|
||||||
@ -92,10 +97,12 @@ formTabs settings model =
|
|||||||
Data.UiSettings.fieldVisible settings field
|
Data.UiSettings.fieldVisible settings field
|
||||||
|
|
||||||
customFieldSettings =
|
customFieldSettings =
|
||||||
Comp.CustomFieldMultiInput.ViewSettings
|
{ showAddButton = True
|
||||||
True
|
, classes = ""
|
||||||
"field"
|
, fieldIcon = \f -> Dict.get f.id model.customFieldSavingIcon
|
||||||
(\f -> Dict.get f.id model.customFieldSavingIcon)
|
, style = dds
|
||||||
|
, createCustomFieldTitle = texts.createNewCustomField
|
||||||
|
}
|
||||||
|
|
||||||
optional fields html =
|
optional fields html =
|
||||||
if
|
if
|
||||||
@ -106,8 +113,41 @@ formTabs settings model =
|
|||||||
|
|
||||||
else
|
else
|
||||||
span [ class "invisible hidden" ] []
|
span [ class "invisible hidden" ] []
|
||||||
|
|
||||||
|
directionCfg =
|
||||||
|
{ makeOption =
|
||||||
|
\entry ->
|
||||||
|
{ text = Data.Direction.toString entry
|
||||||
|
, additional = ""
|
||||||
|
}
|
||||||
|
, placeholder = texts.chooseDirection
|
||||||
|
, labelColor = \_ -> \_ -> ""
|
||||||
|
, style = dds
|
||||||
|
}
|
||||||
|
|
||||||
|
folderCfg =
|
||||||
|
{ makeOption = Util.Folder.mkFolderOption flags model.allFolders
|
||||||
|
, placeholder = texts.selectPlaceholder
|
||||||
|
, labelColor = \_ -> \_ -> ""
|
||||||
|
, style = dds
|
||||||
|
}
|
||||||
|
|
||||||
|
idNameCfg =
|
||||||
|
{ makeOption = \e -> { text = e.name, additional = "" }
|
||||||
|
, labelColor = \_ -> \_ -> ""
|
||||||
|
, placeholder = texts.selectPlaceholder
|
||||||
|
, style = dds
|
||||||
|
}
|
||||||
|
|
||||||
|
personCfg =
|
||||||
|
{ makeOption = \p -> Util.Person.mkPersonOption p model.allPersons
|
||||||
|
, labelColor = \_ -> \_ -> ""
|
||||||
|
, placeholder = texts.selectPlaceholder
|
||||||
|
, style = dds
|
||||||
|
}
|
||||||
in
|
in
|
||||||
[ { title = "Name"
|
[ { name = FTabState.tabName TabName
|
||||||
|
, title = texts.basics.name
|
||||||
, titleRight = []
|
, titleRight = []
|
||||||
, info = Nothing
|
, info = Nothing
|
||||||
, body =
|
, body =
|
||||||
@ -133,7 +173,8 @@ formTabs settings model =
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
, { title = "Date"
|
, { name = FTabState.tabName TabDate
|
||||||
|
, title = texts.basics.date
|
||||||
, titleRight = []
|
, titleRight = []
|
||||||
, info = Nothing
|
, info = Nothing
|
||||||
, body =
|
, body =
|
||||||
@ -154,16 +195,21 @@ formTabs settings model =
|
|||||||
]
|
]
|
||||||
, Icons.dateIcon2 S.dateInputIcon
|
, Icons.dateIcon2 S.dateInputIcon
|
||||||
]
|
]
|
||||||
, renderItemDateSuggestions model
|
, renderItemDateSuggestions texts model
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
, { title = "Tags"
|
, { name = FTabState.tabName TabTags
|
||||||
|
, title = texts.basics.tags
|
||||||
, titleRight = []
|
, titleRight = []
|
||||||
, info = Nothing
|
, info = Nothing
|
||||||
, body =
|
, body =
|
||||||
[ div [ class "mb-4 flex flex-col" ]
|
[ div [ class "mb-4 flex flex-col" ]
|
||||||
[ Html.map TagDropdownMsg (Comp.Dropdown.view2 dds settings model.tagModel)
|
[ Html.map TagDropdownMsg
|
||||||
|
(Comp.Dropdown.view2 (Util.Tag.tagSettings texts.basics.chooseTag dds)
|
||||||
|
settings
|
||||||
|
model.tagModel
|
||||||
|
)
|
||||||
, div [ class "flex flex-row items-center justify-end" ]
|
, div [ class "flex flex-row items-center justify-end" ]
|
||||||
[ a
|
[ a
|
||||||
[ class S.secondaryButton
|
[ class S.secondaryButton
|
||||||
@ -177,14 +223,15 @@ formTabs settings model =
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
, { title = "Folder"
|
, { name = FTabState.tabName TabFolder
|
||||||
|
, title = texts.basics.folder
|
||||||
, titleRight = []
|
, titleRight = []
|
||||||
, info = Nothing
|
, info = Nothing
|
||||||
, body =
|
, body =
|
||||||
[ div [ class "mb-4" ]
|
[ div [ class "mb-4" ]
|
||||||
[ Html.map FolderDropdownMsg
|
[ Html.map FolderDropdownMsg
|
||||||
(Comp.Dropdown.view2
|
(Comp.Dropdown.view2
|
||||||
dds
|
folderCfg
|
||||||
settings
|
settings
|
||||||
model.folderModel
|
model.folderModel
|
||||||
)
|
)
|
||||||
@ -194,30 +241,28 @@ formTabs settings model =
|
|||||||
, ( "hidden", isFolderMember model )
|
, ( "hidden", isFolderMember model )
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
[ Markdown.toHtml [] """
|
[ Markdown.toHtml [] texts.folderNotOwnerWarning
|
||||||
You are **not a member** of this folder. This item will be **hidden**
|
|
||||||
from any search now. Use a folder where you are a member of to make this
|
|
||||||
item visible. This message will disappear then.
|
|
||||||
"""
|
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
, { title = "Custom Fields"
|
, { name = FTabState.tabName TabCustomFields
|
||||||
|
, title = texts.basics.customFields
|
||||||
, titleRight = []
|
, titleRight = []
|
||||||
, info = Nothing
|
, info = Nothing
|
||||||
, body =
|
, body =
|
||||||
[ div [ class "mb-4" ]
|
[ div [ class "mb-4" ]
|
||||||
[ Html.map CustomFieldMsg
|
[ Html.map CustomFieldMsg
|
||||||
(Comp.CustomFieldMultiInput.view2
|
(Comp.CustomFieldMultiInput.view2
|
||||||
dds
|
texts.customFieldInput
|
||||||
customFieldSettings
|
customFieldSettings
|
||||||
model.customFieldsModel
|
model.customFieldsModel
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
, { title = "Due Date"
|
, { name = FTabState.tabName TabDueDate
|
||||||
|
, title = texts.dueDateTab
|
||||||
, titleRight = []
|
, titleRight = []
|
||||||
, info = Nothing
|
, info = Nothing
|
||||||
, body =
|
, body =
|
||||||
@ -238,11 +283,12 @@ item visible. This message will disappear then.
|
|||||||
]
|
]
|
||||||
, Icons.dueDateIcon2 S.dateInputIcon
|
, Icons.dueDateIcon2 S.dateInputIcon
|
||||||
]
|
]
|
||||||
, renderDueDateSuggestions model
|
, renderDueDateSuggestions texts model
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
, { title = "Correspondent"
|
, { name = FTabState.tabName TabCorrespondent
|
||||||
|
, title = texts.basics.correspondent
|
||||||
, titleRight = []
|
, titleRight = []
|
||||||
, info = Nothing
|
, info = Nothing
|
||||||
, body =
|
, body =
|
||||||
@ -250,25 +296,34 @@ item visible. This message will disappear then.
|
|||||||
div [ class "mb-4" ]
|
div [ class "mb-4" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ Icons.organizationIcon2 "mr-2"
|
[ Icons.organizationIcon2 "mr-2"
|
||||||
, text "Organization"
|
, text texts.basics.organization
|
||||||
, addIconLink "Add new organization" StartCorrOrgModal
|
, addIconLink texts.addNewOrg StartCorrOrgModal
|
||||||
, editIconLink "Edit organization" model.corrOrgModel StartEditCorrOrgModal
|
, editIconLink texts.editOrg model.corrOrgModel StartEditCorrOrgModal
|
||||||
]
|
]
|
||||||
, Html.map OrgDropdownMsg (Comp.Dropdown.view2 dds settings model.corrOrgModel)
|
, Html.map OrgDropdownMsg
|
||||||
, renderOrgSuggestions model
|
(Comp.Dropdown.view2
|
||||||
|
(Comp.Dropdown.orgFormViewSettings texts.chooseOrg dds)
|
||||||
|
settings
|
||||||
|
model.corrOrgModel
|
||||||
|
)
|
||||||
|
, renderOrgSuggestions texts model
|
||||||
]
|
]
|
||||||
, optional [ Data.Fields.CorrPerson ] <|
|
, optional [ Data.Fields.CorrPerson ] <|
|
||||||
div [ class "mb-4" ]
|
div [ class "mb-4" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ Icons.personIcon2 "mr-2"
|
[ Icons.personIcon2 "mr-2"
|
||||||
, text "Person"
|
, text texts.basics.person
|
||||||
, addIconLink "Add new correspondent person" StartCorrPersonModal
|
, addIconLink texts.addNewCorrespondentPerson StartCorrPersonModal
|
||||||
, editIconLink "Edit person"
|
, editIconLink texts.editPerson
|
||||||
model.corrPersonModel
|
model.corrPersonModel
|
||||||
(StartEditPersonModal model.corrPersonModel)
|
(StartEditPersonModal model.corrPersonModel)
|
||||||
]
|
]
|
||||||
, Html.map CorrPersonMsg (Comp.Dropdown.view2 dds settings model.corrPersonModel)
|
, Html.map CorrPersonMsg
|
||||||
, renderCorrPersonSuggestions model
|
(Comp.Dropdown.view2 personCfg
|
||||||
|
settings
|
||||||
|
model.corrPersonModel
|
||||||
|
)
|
||||||
|
, renderCorrPersonSuggestions texts model
|
||||||
, div
|
, div
|
||||||
[ classList
|
[ classList
|
||||||
[ ( "hidden", personMatchesOrg model )
|
[ ( "hidden", personMatchesOrg model )
|
||||||
@ -277,12 +332,13 @@ item visible. This message will disappear then.
|
|||||||
, class "my-2"
|
, class "my-2"
|
||||||
]
|
]
|
||||||
[ i [ class "fa fa-info mr-2 " ] []
|
[ i [ class "fa fa-info mr-2 " ] []
|
||||||
, text "The selected person doesn't belong to the selected organization."
|
, text texts.personOrgInfo
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
, { title = "Concerning"
|
, { name = FTabState.tabName TabConcerning
|
||||||
|
, title = texts.basics.concerning
|
||||||
, titleRight = []
|
, titleRight = []
|
||||||
, info = Nothing
|
, info = Nothing
|
||||||
, body =
|
, body =
|
||||||
@ -290,48 +346,49 @@ item visible. This message will disappear then.
|
|||||||
div [ class "mb-4" ]
|
div [ class "mb-4" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ Icons.personIcon2 "mr-2"
|
[ Icons.personIcon2 "mr-2"
|
||||||
, text "Person"
|
, text texts.basics.person
|
||||||
, addIconLink "Add new concerning person" StartConcPersonModal
|
, addIconLink texts.addNewConcerningPerson StartConcPersonModal
|
||||||
, editIconLink "Edit person"
|
, editIconLink texts.editPerson
|
||||||
model.concPersonModel
|
model.concPersonModel
|
||||||
(StartEditPersonModal model.concPersonModel)
|
(StartEditPersonModal model.concPersonModel)
|
||||||
]
|
]
|
||||||
, Html.map ConcPersonMsg
|
, Html.map ConcPersonMsg
|
||||||
(Comp.Dropdown.view2
|
(Comp.Dropdown.view2
|
||||||
dds
|
personCfg
|
||||||
settings
|
settings
|
||||||
model.concPersonModel
|
model.concPersonModel
|
||||||
)
|
)
|
||||||
, renderConcPersonSuggestions model
|
, renderConcPersonSuggestions texts model
|
||||||
]
|
]
|
||||||
, optional [ Data.Fields.ConcEquip ] <|
|
, optional [ Data.Fields.ConcEquip ] <|
|
||||||
div [ class "mb-4" ]
|
div [ class "mb-4" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ Icons.equipmentIcon2 "mr-2"
|
[ Icons.equipmentIcon2 "mr-2"
|
||||||
, text "Equipment"
|
, text texts.basics.equipment
|
||||||
, addIconLink "Add new equipment" StartEquipModal
|
, addIconLink texts.addNewEquipment StartEquipModal
|
||||||
, editIconLink "Edit equipment"
|
, editIconLink texts.editEquipment
|
||||||
model.concEquipModel
|
model.concEquipModel
|
||||||
StartEditEquipModal
|
StartEditEquipModal
|
||||||
]
|
]
|
||||||
, Html.map ConcEquipMsg
|
, Html.map ConcEquipMsg
|
||||||
(Comp.Dropdown.view2
|
(Comp.Dropdown.view2
|
||||||
dds
|
idNameCfg
|
||||||
settings
|
settings
|
||||||
model.concEquipModel
|
model.concEquipModel
|
||||||
)
|
)
|
||||||
, renderConcEquipSuggestions model
|
, renderConcEquipSuggestions texts model
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
, { title = "Direction"
|
, { name = FTabState.tabName TabDirection
|
||||||
|
, title = texts.basics.direction
|
||||||
, titleRight = []
|
, titleRight = []
|
||||||
, info = Nothing
|
, info = Nothing
|
||||||
, body =
|
, body =
|
||||||
[ div [ class "mb-4" ]
|
[ div [ class "mb-4" ]
|
||||||
[ Html.map DirDropdownMsg
|
[ Html.map DirDropdownMsg
|
||||||
(Comp.Dropdown.view2
|
(Comp.Dropdown.view2
|
||||||
dds
|
directionCfg
|
||||||
settings
|
settings
|
||||||
model.directionModel
|
model.directionModel
|
||||||
)
|
)
|
||||||
@ -341,8 +398,8 @@ item visible. This message will disappear then.
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
renderSuggestions : Model -> (a -> String) -> List a -> (a -> Msg) -> Html Msg
|
renderSuggestions : Texts -> Model -> (a -> String) -> List a -> (a -> Msg) -> Html Msg
|
||||||
renderSuggestions model mkName idnames tagger =
|
renderSuggestions texts model mkName idnames tagger =
|
||||||
div
|
div
|
||||||
[ classList
|
[ classList
|
||||||
[ ( "hidden", model.item.state /= "created" )
|
[ ( "hidden", model.item.state /= "created" )
|
||||||
@ -350,7 +407,7 @@ renderSuggestions model mkName idnames tagger =
|
|||||||
, class "flex flex-col text-sm"
|
, class "flex flex-col text-sm"
|
||||||
]
|
]
|
||||||
[ div [ class "font-bold my-1" ]
|
[ div [ class "font-bold my-1" ]
|
||||||
[ text "Suggestions"
|
[ text texts.suggestions
|
||||||
]
|
]
|
||||||
, ul [ class "list-disc ml-6" ] <|
|
, ul [ class "list-disc ml-6" ] <|
|
||||||
(idnames
|
(idnames
|
||||||
@ -369,49 +426,55 @@ renderSuggestions model mkName idnames tagger =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
renderOrgSuggestions : Model -> Html Msg
|
renderOrgSuggestions : Texts -> Model -> Html Msg
|
||||||
renderOrgSuggestions model =
|
renderOrgSuggestions texts model =
|
||||||
renderSuggestions model
|
renderSuggestions texts
|
||||||
|
model
|
||||||
.name
|
.name
|
||||||
(List.take 6 model.itemProposals.corrOrg)
|
(List.take 6 model.itemProposals.corrOrg)
|
||||||
SetCorrOrgSuggestion
|
SetCorrOrgSuggestion
|
||||||
|
|
||||||
|
|
||||||
renderCorrPersonSuggestions : Model -> Html Msg
|
renderCorrPersonSuggestions : Texts -> Model -> Html Msg
|
||||||
renderCorrPersonSuggestions model =
|
renderCorrPersonSuggestions texts model =
|
||||||
renderSuggestions model
|
renderSuggestions texts
|
||||||
|
model
|
||||||
.name
|
.name
|
||||||
(List.take 6 model.itemProposals.corrPerson)
|
(List.take 6 model.itemProposals.corrPerson)
|
||||||
SetCorrPersonSuggestion
|
SetCorrPersonSuggestion
|
||||||
|
|
||||||
|
|
||||||
renderConcPersonSuggestions : Model -> Html Msg
|
renderConcPersonSuggestions : Texts -> Model -> Html Msg
|
||||||
renderConcPersonSuggestions model =
|
renderConcPersonSuggestions texts model =
|
||||||
renderSuggestions model
|
renderSuggestions texts
|
||||||
|
model
|
||||||
.name
|
.name
|
||||||
(List.take 6 model.itemProposals.concPerson)
|
(List.take 6 model.itemProposals.concPerson)
|
||||||
SetConcPersonSuggestion
|
SetConcPersonSuggestion
|
||||||
|
|
||||||
|
|
||||||
renderConcEquipSuggestions : Model -> Html Msg
|
renderConcEquipSuggestions : Texts -> Model -> Html Msg
|
||||||
renderConcEquipSuggestions model =
|
renderConcEquipSuggestions texts model =
|
||||||
renderSuggestions model
|
renderSuggestions texts
|
||||||
|
model
|
||||||
.name
|
.name
|
||||||
(List.take 6 model.itemProposals.concEquipment)
|
(List.take 6 model.itemProposals.concEquipment)
|
||||||
SetConcEquipSuggestion
|
SetConcEquipSuggestion
|
||||||
|
|
||||||
|
|
||||||
renderItemDateSuggestions : Model -> Html Msg
|
renderItemDateSuggestions : Texts -> Model -> Html Msg
|
||||||
renderItemDateSuggestions model =
|
renderItemDateSuggestions texts model =
|
||||||
renderSuggestions model
|
renderSuggestions texts
|
||||||
|
model
|
||||||
Util.Time.formatDate
|
Util.Time.formatDate
|
||||||
(List.take 6 model.itemProposals.itemDate)
|
(List.take 6 model.itemProposals.itemDate)
|
||||||
SetItemDateSuggestion
|
SetItemDateSuggestion
|
||||||
|
|
||||||
|
|
||||||
renderDueDateSuggestions : Model -> Html Msg
|
renderDueDateSuggestions : Texts -> Model -> Html Msg
|
||||||
renderDueDateSuggestions model =
|
renderDueDateSuggestions texts model =
|
||||||
renderSuggestions model
|
renderSuggestions texts
|
||||||
|
model
|
||||||
Util.Time.formatDate
|
Util.Time.formatDate
|
||||||
(List.take 6 model.itemProposals.dueDate)
|
(List.take 6 model.itemProposals.dueDate)
|
||||||
SetDueDateSuggestion
|
SetDueDateSuggestion
|
||||||
@ -445,4 +508,4 @@ tabState settings allNames model =
|
|||||||
FTabState.tabState settings
|
FTabState.tabState settings
|
||||||
openTabs
|
openTabs
|
||||||
Nothing
|
Nothing
|
||||||
(.title >> ToggleAkkordionTab)
|
(.name >> ToggleAkkordionTab)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
module Comp.ItemDetail.FieldTabState exposing (tabState)
|
module Comp.ItemDetail.FieldTabState exposing (EditTab(..), allTabs, findTab, tabName, tabState)
|
||||||
|
|
||||||
import Comp.CustomFieldMultiInput
|
import Comp.CustomFieldMultiInput
|
||||||
import Comp.Tabs as TB
|
import Comp.Tabs as TB
|
||||||
@ -7,6 +7,102 @@ import Data.UiSettings exposing (UiSettings)
|
|||||||
import Set exposing (Set)
|
import Set exposing (Set)
|
||||||
|
|
||||||
|
|
||||||
|
type EditTab
|
||||||
|
= TabName
|
||||||
|
| TabDate
|
||||||
|
| TabTags
|
||||||
|
| TabFolder
|
||||||
|
| TabCustomFields
|
||||||
|
| TabDueDate
|
||||||
|
| TabCorrespondent
|
||||||
|
| TabConcerning
|
||||||
|
| TabDirection
|
||||||
|
| TabConfirmUnconfirm
|
||||||
|
|
||||||
|
|
||||||
|
allTabs : List EditTab
|
||||||
|
allTabs =
|
||||||
|
[ TabName
|
||||||
|
, TabDate
|
||||||
|
, TabTags
|
||||||
|
, TabFolder
|
||||||
|
, TabCustomFields
|
||||||
|
, TabDueDate
|
||||||
|
, TabCorrespondent
|
||||||
|
, TabConcerning
|
||||||
|
, TabDirection
|
||||||
|
, TabConfirmUnconfirm
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
tabName : EditTab -> String
|
||||||
|
tabName tab =
|
||||||
|
case tab of
|
||||||
|
TabName ->
|
||||||
|
"name"
|
||||||
|
|
||||||
|
TabTags ->
|
||||||
|
"tags"
|
||||||
|
|
||||||
|
TabDate ->
|
||||||
|
"date"
|
||||||
|
|
||||||
|
TabFolder ->
|
||||||
|
"folder"
|
||||||
|
|
||||||
|
TabCustomFields ->
|
||||||
|
"custom-fields"
|
||||||
|
|
||||||
|
TabDueDate ->
|
||||||
|
"due-date"
|
||||||
|
|
||||||
|
TabCorrespondent ->
|
||||||
|
"correspondent"
|
||||||
|
|
||||||
|
TabConcerning ->
|
||||||
|
"concerning"
|
||||||
|
|
||||||
|
TabDirection ->
|
||||||
|
"direction"
|
||||||
|
|
||||||
|
TabConfirmUnconfirm ->
|
||||||
|
"confirm-unconfirm"
|
||||||
|
|
||||||
|
|
||||||
|
findTab : TB.Tab msg -> Maybe EditTab
|
||||||
|
findTab tab =
|
||||||
|
case tab.name of
|
||||||
|
"name" ->
|
||||||
|
Just TabName
|
||||||
|
|
||||||
|
"tags" ->
|
||||||
|
Just TabTags
|
||||||
|
|
||||||
|
"date" ->
|
||||||
|
Just TabDate
|
||||||
|
|
||||||
|
"folder" ->
|
||||||
|
Just TabFolder
|
||||||
|
|
||||||
|
"custom-fields" ->
|
||||||
|
Just TabCustomFields
|
||||||
|
|
||||||
|
"due-date" ->
|
||||||
|
Just TabDueDate
|
||||||
|
|
||||||
|
"correspondent" ->
|
||||||
|
Just TabCorrespondent
|
||||||
|
|
||||||
|
"concerning" ->
|
||||||
|
Just TabConcerning
|
||||||
|
|
||||||
|
"direction" ->
|
||||||
|
Just TabDirection
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
Nothing
|
||||||
|
|
||||||
|
|
||||||
tabState :
|
tabState :
|
||||||
UiSettings
|
UiSettings
|
||||||
-> Set String
|
-> Set String
|
||||||
@ -20,32 +116,32 @@ tabState settings openTabs cfmodel toggle tab =
|
|||||||
Data.UiSettings.fieldHidden settings f
|
Data.UiSettings.fieldHidden settings f
|
||||||
|
|
||||||
hidden =
|
hidden =
|
||||||
case tab.title of
|
case findTab tab of
|
||||||
"Tags" ->
|
Just TabTags ->
|
||||||
isHidden Data.Fields.Tag
|
isHidden Data.Fields.Tag
|
||||||
|
|
||||||
"Folder" ->
|
Just TabFolder ->
|
||||||
isHidden Data.Fields.Folder
|
isHidden Data.Fields.Folder
|
||||||
|
|
||||||
"Correspondent" ->
|
Just TabCorrespondent ->
|
||||||
isHidden Data.Fields.CorrOrg && isHidden Data.Fields.CorrPerson
|
isHidden Data.Fields.CorrOrg && isHidden Data.Fields.CorrPerson
|
||||||
|
|
||||||
"Concerning" ->
|
Just TabConcerning ->
|
||||||
isHidden Data.Fields.ConcEquip && isHidden Data.Fields.ConcPerson
|
isHidden Data.Fields.ConcEquip && isHidden Data.Fields.ConcPerson
|
||||||
|
|
||||||
"Custom Fields" ->
|
Just TabCustomFields ->
|
||||||
isHidden Data.Fields.CustomFields
|
isHidden Data.Fields.CustomFields
|
||||||
|| (Maybe.map Comp.CustomFieldMultiInput.isEmpty cfmodel
|
|| (Maybe.map Comp.CustomFieldMultiInput.isEmpty cfmodel
|
||||||
|> Maybe.withDefault False
|
|> Maybe.withDefault False
|
||||||
)
|
)
|
||||||
|
|
||||||
"Date" ->
|
Just TabDate ->
|
||||||
isHidden Data.Fields.Date
|
isHidden Data.Fields.Date
|
||||||
|
|
||||||
"Due Date" ->
|
Just TabDueDate ->
|
||||||
isHidden Data.Fields.DueDate
|
isHidden Data.Fields.DueDate
|
||||||
|
|
||||||
"Direction" ->
|
Just TabDirection ->
|
||||||
isHidden Data.Fields.Direction
|
isHidden Data.Fields.Direction
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
@ -55,7 +151,7 @@ tabState settings openTabs cfmodel toggle tab =
|
|||||||
if hidden then
|
if hidden then
|
||||||
TB.Hidden
|
TB.Hidden
|
||||||
|
|
||||||
else if Set.member tab.title openTabs then
|
else if Set.member tab.name openTabs then
|
||||||
TB.Open
|
TB.Open
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -15,19 +15,20 @@ import Data.Icons as Icons
|
|||||||
import Data.UiSettings exposing (UiSettings)
|
import Data.UiSettings exposing (UiSettings)
|
||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
|
import Messages.Comp.ItemDetail.ItemInfoHeader exposing (Texts)
|
||||||
import Page exposing (Page(..))
|
import Page exposing (Page(..))
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.Maybe
|
import Util.Maybe
|
||||||
import Util.Time
|
import Util.Time
|
||||||
|
|
||||||
|
|
||||||
view : UiSettings -> Model -> Html Msg
|
view : Texts -> UiSettings -> Model -> Html Msg
|
||||||
view settings model =
|
view texts settings model =
|
||||||
let
|
let
|
||||||
date =
|
date =
|
||||||
( div
|
( div
|
||||||
[ class "ml-2 sm:ml-0 whitespace-nowrap py-1 whitespace-nowrap opacity-75"
|
[ class "ml-2 sm:ml-0 whitespace-nowrap py-1 whitespace-nowrap opacity-75"
|
||||||
, title "Item Date"
|
, title texts.itemDate
|
||||||
]
|
]
|
||||||
[ Icons.dateIcon2 "mr-2"
|
[ Icons.dateIcon2 "mr-2"
|
||||||
, Maybe.withDefault model.item.created model.item.itemDate
|
, Maybe.withDefault model.item.created model.item.itemDate
|
||||||
@ -47,7 +48,7 @@ view settings model =
|
|||||||
( div
|
( div
|
||||||
[ class "ml-2 sm:ml-4 py-1 max-w-min whitespace-nowrap opacity-100"
|
[ class "ml-2 sm:ml-4 py-1 max-w-min whitespace-nowrap opacity-100"
|
||||||
, class S.basicLabel
|
, class S.basicLabel
|
||||||
, title "Due Date"
|
, title texts.dueDate
|
||||||
]
|
]
|
||||||
[ Icons.dueDateIcon2 "mr-2"
|
[ Icons.dueDateIcon2 "mr-2"
|
||||||
, Maybe.map Util.Time.formatDate model.item.dueDate
|
, Maybe.map Util.Time.formatDate model.item.dueDate
|
||||||
@ -61,7 +62,7 @@ view settings model =
|
|||||||
corr =
|
corr =
|
||||||
( div
|
( div
|
||||||
[ class itemStyle
|
[ class itemStyle
|
||||||
, title "Correspondent"
|
, title texts.basics.correspondent
|
||||||
]
|
]
|
||||||
(Icons.correspondentIcon2 "mr-2"
|
(Icons.correspondentIcon2 "mr-2"
|
||||||
:: Comp.LinkTarget.makeCorrLink model.item
|
:: Comp.LinkTarget.makeCorrLink model.item
|
||||||
@ -75,7 +76,7 @@ view settings model =
|
|||||||
conc =
|
conc =
|
||||||
( div
|
( div
|
||||||
[ class itemStyle
|
[ class itemStyle
|
||||||
, title "Concerning"
|
, title texts.basics.concerning
|
||||||
]
|
]
|
||||||
(Icons.concernedIcon2 "mr-2"
|
(Icons.concernedIcon2 "mr-2"
|
||||||
:: Comp.LinkTarget.makeConcLink model.item
|
:: Comp.LinkTarget.makeConcLink model.item
|
||||||
@ -89,7 +90,7 @@ view settings model =
|
|||||||
itemfolder =
|
itemfolder =
|
||||||
( div
|
( div
|
||||||
[ class itemStyle
|
[ class itemStyle
|
||||||
, title "Folder"
|
, title texts.basics.folder
|
||||||
]
|
]
|
||||||
[ Icons.folderIcon2 "mr-2"
|
[ Icons.folderIcon2 "mr-2"
|
||||||
, Comp.LinkTarget.makeFolderLink model.item
|
, Comp.LinkTarget.makeFolderLink model.item
|
||||||
@ -102,7 +103,7 @@ view settings model =
|
|||||||
src =
|
src =
|
||||||
( div
|
( div
|
||||||
[ class itemStyle
|
[ class itemStyle
|
||||||
, title "Source"
|
, title texts.source
|
||||||
]
|
]
|
||||||
[ Icons.sourceIcon2 "mr-2"
|
[ Icons.sourceIcon2 "mr-2"
|
||||||
, Comp.LinkTarget.makeSourceLink [ ( linkStyle, True ) ]
|
, Comp.LinkTarget.makeSourceLink [ ( linkStyle, True ) ]
|
||||||
@ -132,7 +133,7 @@ view settings model =
|
|||||||
]
|
]
|
||||||
, class "ml-3 text-base label bg-blue-500 dark:bg-lightblue-500 text-white rounded-lg"
|
, class "ml-3 text-base label bg-blue-500 dark:bg-lightblue-500 text-white rounded-lg"
|
||||||
]
|
]
|
||||||
[ text "New"
|
[ text texts.new
|
||||||
, i [ class "fa fa-exclamation ml-2" ] []
|
, i [ class "fa fa-exclamation ml-2" ] []
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
@ -39,7 +39,6 @@ import Comp.KeyInput
|
|||||||
import Comp.LinkTarget exposing (LinkTarget)
|
import Comp.LinkTarget exposing (LinkTarget)
|
||||||
import Comp.MarkdownInput
|
import Comp.MarkdownInput
|
||||||
import Comp.SentMails
|
import Comp.SentMails
|
||||||
import Comp.YesNoDimmer
|
|
||||||
import Data.Direction exposing (Direction)
|
import Data.Direction exposing (Direction)
|
||||||
import Data.Fields exposing (Field)
|
import Data.Fields exposing (Field)
|
||||||
import DatePicker exposing (DatePicker)
|
import DatePicker exposing (DatePicker)
|
||||||
@ -136,45 +135,17 @@ emptyModel =
|
|||||||
, visibleAttach = 0
|
, visibleAttach = 0
|
||||||
, attachMenuOpen = False
|
, attachMenuOpen = False
|
||||||
, menuOpen = False
|
, menuOpen = False
|
||||||
, tagModel =
|
, tagModel = Util.Tag.makeDropdownModel
|
||||||
Util.Tag.makeDropdownModel2
|
|
||||||
, directionModel =
|
, directionModel =
|
||||||
Comp.Dropdown.makeSingleList
|
Comp.Dropdown.makeSingleList
|
||||||
{ makeOption =
|
{ options = Data.Direction.all
|
||||||
\entry ->
|
|
||||||
{ value = Data.Direction.toString entry
|
|
||||||
, text = Data.Direction.toString entry
|
|
||||||
, additional = ""
|
|
||||||
}
|
|
||||||
, options = Data.Direction.all
|
|
||||||
, placeholder = "Choose a direction…"
|
|
||||||
, selected = Nothing
|
, selected = Nothing
|
||||||
}
|
}
|
||||||
, corrOrgModel =
|
, corrOrgModel = Comp.Dropdown.makeSingle
|
||||||
Comp.Dropdown.makeSingle
|
, corrPersonModel = Comp.Dropdown.makeSingle
|
||||||
{ makeOption = \e -> { value = e.id, text = e.name, additional = "" }
|
, concPersonModel = Comp.Dropdown.makeSingle
|
||||||
, placeholder = ""
|
, concEquipModel = Comp.Dropdown.makeSingle
|
||||||
}
|
, folderModel = Comp.Dropdown.makeSingle
|
||||||
, corrPersonModel =
|
|
||||||
Comp.Dropdown.makeSingle
|
|
||||||
{ makeOption = \e -> { value = e.id, text = e.name, additional = "" }
|
|
||||||
, placeholder = ""
|
|
||||||
}
|
|
||||||
, concPersonModel =
|
|
||||||
Comp.Dropdown.makeSingle
|
|
||||||
{ makeOption = \e -> { value = e.id, text = e.name, additional = "" }
|
|
||||||
, placeholder = ""
|
|
||||||
}
|
|
||||||
, concEquipModel =
|
|
||||||
Comp.Dropdown.makeSingle
|
|
||||||
{ makeOption = \e -> { value = e.id, text = e.name, additional = "" }
|
|
||||||
, placeholder = ""
|
|
||||||
}
|
|
||||||
, folderModel =
|
|
||||||
Comp.Dropdown.makeSingle
|
|
||||||
{ makeOption = \e -> { value = e.id, text = e.name, additional = "" }
|
|
||||||
, placeholder = ""
|
|
||||||
}
|
|
||||||
, allFolders = []
|
, allFolders = []
|
||||||
, nameModel = ""
|
, nameModel = ""
|
||||||
, nameState = SaveSuccess
|
, nameState = SaveSuccess
|
||||||
|
@ -22,7 +22,7 @@ import Comp.CustomFieldMultiInput
|
|||||||
import Comp.DatePicker
|
import Comp.DatePicker
|
||||||
import Comp.DetailEdit
|
import Comp.DetailEdit
|
||||||
import Comp.Dropdown exposing (isDropdownChangeMsg)
|
import Comp.Dropdown exposing (isDropdownChangeMsg)
|
||||||
import Comp.ItemDetail.FieldTabState as FTabState
|
import Comp.ItemDetail.FieldTabState as FTabState exposing (EditTab(..), tabName)
|
||||||
import Comp.ItemDetail.FormChange exposing (FormChange(..))
|
import Comp.ItemDetail.FormChange exposing (FormChange(..))
|
||||||
import Comp.Tabs as TB
|
import Comp.Tabs as TB
|
||||||
import Data.CustomFieldChange exposing (CustomFieldChange(..))
|
import Data.CustomFieldChange exposing (CustomFieldChange(..))
|
||||||
@ -39,6 +39,7 @@ import Html.Attributes exposing (..)
|
|||||||
import Html.Events exposing (onClick, onInput)
|
import Html.Events exposing (onClick, onInput)
|
||||||
import Http
|
import Http
|
||||||
import Markdown
|
import Markdown
|
||||||
|
import Messages.Comp.ItemDetail.MultiEditMenu exposing (Texts)
|
||||||
import Page exposing (Page(..))
|
import Page exposing (Page(..))
|
||||||
import Set exposing (Set)
|
import Set exposing (Set)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
@ -117,45 +118,17 @@ type Msg
|
|||||||
|
|
||||||
init : Model
|
init : Model
|
||||||
init =
|
init =
|
||||||
{ tagModel =
|
{ tagModel = Util.Tag.makeDropdownModel
|
||||||
Util.Tag.makeDropdownModel2
|
|
||||||
, directionModel =
|
, directionModel =
|
||||||
Comp.Dropdown.makeSingleList
|
Comp.Dropdown.makeSingleList
|
||||||
{ makeOption =
|
{ options = Data.Direction.all
|
||||||
\entry ->
|
|
||||||
{ value = Data.Direction.toString entry
|
|
||||||
, text = Data.Direction.toString entry
|
|
||||||
, additional = ""
|
|
||||||
}
|
|
||||||
, options = Data.Direction.all
|
|
||||||
, placeholder = "Choose a direction…"
|
|
||||||
, selected = Nothing
|
, selected = Nothing
|
||||||
}
|
}
|
||||||
, corrOrgModel =
|
, corrOrgModel = Comp.Dropdown.makeSingle
|
||||||
Comp.Dropdown.makeSingle
|
, corrPersonModel = Comp.Dropdown.makeSingle
|
||||||
{ makeOption = \e -> { value = e.id, text = e.name, additional = "" }
|
, concPersonModel = Comp.Dropdown.makeSingle
|
||||||
, placeholder = ""
|
, concEquipModel = Comp.Dropdown.makeSingle
|
||||||
}
|
, folderModel = Comp.Dropdown.makeSingle
|
||||||
, corrPersonModel =
|
|
||||||
Comp.Dropdown.makeSingle
|
|
||||||
{ makeOption = \e -> { value = e.id, text = e.name, additional = "" }
|
|
||||||
, placeholder = ""
|
|
||||||
}
|
|
||||||
, concPersonModel =
|
|
||||||
Comp.Dropdown.makeSingle
|
|
||||||
{ makeOption = \e -> { value = e.id, text = e.name, additional = "" }
|
|
||||||
, placeholder = ""
|
|
||||||
}
|
|
||||||
, concEquipModel =
|
|
||||||
Comp.Dropdown.makeSingle
|
|
||||||
{ makeOption = \e -> { value = e.id, text = e.name, additional = "" }
|
|
||||||
, placeholder = ""
|
|
||||||
}
|
|
||||||
, folderModel =
|
|
||||||
Comp.Dropdown.makeSingle
|
|
||||||
{ makeOption = \e -> { value = e.id, text = e.name, additional = "" }
|
|
||||||
, placeholder = ""
|
|
||||||
}
|
|
||||||
, allFolders = []
|
, allFolders = []
|
||||||
, nameModel = ""
|
, nameModel = ""
|
||||||
, nameSaveThrottle = Throttle.create 1
|
, nameSaveThrottle = Throttle.create 1
|
||||||
@ -310,13 +283,7 @@ update flags msg model =
|
|||||||
GetFolderResp (Ok fs) ->
|
GetFolderResp (Ok fs) ->
|
||||||
let
|
let
|
||||||
model_ =
|
model_ =
|
||||||
{ model
|
{ model | allFolders = fs.items }
|
||||||
| allFolders = fs.items
|
|
||||||
, folderModel =
|
|
||||||
Comp.Dropdown.setMkOption
|
|
||||||
(mkFolderOption flags fs.items)
|
|
||||||
model.folderModel
|
|
||||||
}
|
|
||||||
|
|
||||||
mkIdName fitem =
|
mkIdName fitem =
|
||||||
IdName fitem.id fitem.name
|
IdName fitem.id fitem.name
|
||||||
@ -593,14 +560,14 @@ update flags msg model =
|
|||||||
in
|
in
|
||||||
UpdateResult model_ cmd_ Sub.none change
|
UpdateResult model_ cmd_ Sub.none change
|
||||||
|
|
||||||
ToggleAkkordionTab title ->
|
ToggleAkkordionTab name ->
|
||||||
let
|
let
|
||||||
tabs =
|
tabs =
|
||||||
if Set.member title model.openTabs then
|
if Set.member name model.openTabs then
|
||||||
Set.remove title model.openTabs
|
Set.remove name model.openTabs
|
||||||
|
|
||||||
else
|
else
|
||||||
Set.insert title model.openTabs
|
Set.insert name model.openTabs
|
||||||
in
|
in
|
||||||
UpdateResult { model | openTabs = tabs } Cmd.none Sub.none NoFormChange
|
UpdateResult { model | openTabs = tabs } Cmd.none Sub.none NoFormChange
|
||||||
|
|
||||||
@ -635,13 +602,13 @@ defaultViewConfig =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : ViewConfig -> UiSettings -> Model -> Html Msg
|
view2 : Texts -> Flags -> ViewConfig -> UiSettings -> Model -> Html Msg
|
||||||
view2 =
|
view2 =
|
||||||
renderEditForm2
|
renderEditForm2
|
||||||
|
|
||||||
|
|
||||||
renderEditForm2 : ViewConfig -> UiSettings -> Model -> Html Msg
|
renderEditForm2 : Texts -> Flags -> ViewConfig -> UiSettings -> Model -> Html Msg
|
||||||
renderEditForm2 cfg settings model =
|
renderEditForm2 texts flags cfg settings model =
|
||||||
let
|
let
|
||||||
fieldVisible field =
|
fieldVisible field =
|
||||||
Data.UiSettings.fieldVisible settings field
|
Data.UiSettings.fieldVisible settings field
|
||||||
@ -670,13 +637,13 @@ renderEditForm2 cfg settings model =
|
|||||||
tagModeMsg =
|
tagModeMsg =
|
||||||
case model.tagEditMode of
|
case model.tagEditMode of
|
||||||
AddTags ->
|
AddTags ->
|
||||||
"Tags chosen here are *added* to all selected items."
|
texts.tagModeAddInfo
|
||||||
|
|
||||||
RemoveTags ->
|
RemoveTags ->
|
||||||
"Tags chosen here are *removed* from all selected items."
|
texts.tagModeRemoveInfo
|
||||||
|
|
||||||
ReplaceTags ->
|
ReplaceTags ->
|
||||||
"Tags chosen here *replace* those on selected items."
|
texts.tagModeReplaceInfo
|
||||||
|
|
||||||
customFieldIcon field =
|
customFieldIcon field =
|
||||||
case cfg.customFieldState field.id of
|
case cfg.customFieldState field.id of
|
||||||
@ -690,22 +657,50 @@ renderEditForm2 cfg settings model =
|
|||||||
Just "fa fa-sync-alt animate-spin"
|
Just "fa fa-sync-alt animate-spin"
|
||||||
|
|
||||||
customFieldSettings =
|
customFieldSettings =
|
||||||
Comp.CustomFieldMultiInput.ViewSettings
|
{ showAddButton = False
|
||||||
False
|
, classes = "mb-4"
|
||||||
"mb-4"
|
, fieldIcon = customFieldIcon
|
||||||
customFieldIcon
|
, style = dds
|
||||||
|
, createCustomFieldTitle = ""
|
||||||
|
}
|
||||||
|
|
||||||
dds =
|
dds =
|
||||||
Data.DropdownStyle.sidebarStyle
|
Data.DropdownStyle.sidebarStyle
|
||||||
|
|
||||||
tabStyle =
|
tabStyle =
|
||||||
TB.searchMenuStyle
|
TB.searchMenuStyle
|
||||||
|
|
||||||
|
folderCfg =
|
||||||
|
{ makeOption = Util.Folder.mkFolderOption flags model.allFolders
|
||||||
|
, placeholder = ""
|
||||||
|
, labelColor = \_ -> \_ -> ""
|
||||||
|
, style = dds
|
||||||
|
}
|
||||||
|
|
||||||
|
idNameCfg =
|
||||||
|
{ makeOption = \e -> { text = e.name, additional = "" }
|
||||||
|
, labelColor = \_ -> \_ -> ""
|
||||||
|
, placeholder = texts.selectPlaceholder
|
||||||
|
, style = dds
|
||||||
|
}
|
||||||
|
|
||||||
|
directionCfg =
|
||||||
|
{ makeOption =
|
||||||
|
\entry ->
|
||||||
|
{ text = Data.Direction.toString entry
|
||||||
|
, additional = ""
|
||||||
|
}
|
||||||
|
, placeholder = texts.chooseDirection
|
||||||
|
, labelColor = \_ -> \_ -> ""
|
||||||
|
, style = dds
|
||||||
|
}
|
||||||
in
|
in
|
||||||
div [ class cfg.menuClass, class "mt-2" ]
|
div [ class cfg.menuClass, class "mt-2" ]
|
||||||
[ TB.akkordion
|
[ TB.akkordion
|
||||||
tabStyle
|
tabStyle
|
||||||
(tabState settings model)
|
(tabState settings model)
|
||||||
[ { title = "Confirm/Unconfirm item metadata"
|
[ { name = tabName TabConfirmUnconfirm
|
||||||
|
, title = texts.confirmUnconfirm
|
||||||
, titleRight = []
|
, titleRight = []
|
||||||
, info = Nothing
|
, info = Nothing
|
||||||
, body =
|
, body =
|
||||||
@ -717,69 +712,77 @@ renderEditForm2 cfg settings model =
|
|||||||
, class "flex-grow"
|
, class "flex-grow"
|
||||||
, onClick (ConfirmMsg True)
|
, onClick (ConfirmMsg True)
|
||||||
]
|
]
|
||||||
[ text "Confirm"
|
[ text texts.confirm
|
||||||
]
|
]
|
||||||
, button
|
, button
|
||||||
[ class S.secondaryButton
|
[ class S.secondaryButton
|
||||||
, class "flex-grow"
|
, class "flex-grow"
|
||||||
, onClick (ConfirmMsg False)
|
, onClick (ConfirmMsg False)
|
||||||
]
|
]
|
||||||
[ text "Unconfirm"
|
[ text texts.unconfirm
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
, { title = "Tags"
|
, { name = tabName TabTags
|
||||||
|
, title = texts.basics.tags
|
||||||
, titleRight = []
|
, titleRight = []
|
||||||
, info = Nothing
|
, info = Nothing
|
||||||
, body =
|
, body =
|
||||||
[ div [ class "field" ]
|
[ div [ class "field" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ Icons.tagsIcon2 ""
|
[ Icons.tagsIcon2 ""
|
||||||
, text "Tags"
|
, text texts.basics.tags
|
||||||
, a
|
, a
|
||||||
[ class "float-right"
|
[ class "float-right"
|
||||||
, class S.link
|
, class S.link
|
||||||
, href "#"
|
, href "#"
|
||||||
, title "Change tag edit mode"
|
, title texts.changeTagMode
|
||||||
, onClick ToggleTagEditMode
|
, onClick ToggleTagEditMode
|
||||||
]
|
]
|
||||||
[ tagModeIcon
|
[ tagModeIcon
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, Html.map TagDropdownMsg (Comp.Dropdown.view2 dds settings model.tagModel)
|
, Html.map TagDropdownMsg
|
||||||
|
(Comp.Dropdown.view2 (Util.Tag.tagSettings texts.basics.chooseTag dds)
|
||||||
|
settings
|
||||||
|
model.tagModel
|
||||||
|
)
|
||||||
, Markdown.toHtml [ class "opacity-50 text-sm" ] tagModeMsg
|
, Markdown.toHtml [ class "opacity-50 text-sm" ] tagModeMsg
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
, { title = "Folder"
|
, { name = tabName TabFolder
|
||||||
|
, title = texts.basics.folder
|
||||||
, titleRight = []
|
, titleRight = []
|
||||||
, info = Nothing
|
, info = Nothing
|
||||||
, body =
|
, body =
|
||||||
[ Html.map FolderDropdownMsg (Comp.Dropdown.view2 dds settings model.folderModel)
|
[ Html.map FolderDropdownMsg (Comp.Dropdown.view2 folderCfg settings model.folderModel)
|
||||||
, div
|
, div
|
||||||
[ classList
|
[ classList
|
||||||
[ ( S.message, True )
|
[ ( S.message, True )
|
||||||
, ( "hidden", isFolderMember model )
|
, ( "hidden", isFolderMember model )
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
[ Markdown.toHtml [] """
|
[ Markdown.toHtml [] texts.folderNotOwnerWarning
|
||||||
You are **not a member** of this folder. This item will be **hidden**
|
|
||||||
from any search now. Use a folder where you are a member of to make this
|
|
||||||
item visible. This message will disappear then.
|
|
||||||
"""
|
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
, { title = "Custom Fields"
|
, { name = tabName TabCustomFields
|
||||||
|
, title = texts.basics.customFields
|
||||||
, titleRight = []
|
, titleRight = []
|
||||||
, info = Nothing
|
, info = Nothing
|
||||||
, body =
|
, body =
|
||||||
[ Html.map CustomFieldMsg
|
[ Html.map CustomFieldMsg
|
||||||
(Comp.CustomFieldMultiInput.view2 dds customFieldSettings model.customFieldModel)
|
(Comp.CustomFieldMultiInput.view2
|
||||||
|
texts.customFieldMultiInput
|
||||||
|
customFieldSettings
|
||||||
|
model.customFieldModel
|
||||||
|
)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
, { title = "Date"
|
, { name = tabName TabDate
|
||||||
|
, title = texts.basics.date
|
||||||
, titleRight = []
|
, titleRight = []
|
||||||
, info = Nothing
|
, info = Nothing
|
||||||
, body =
|
, body =
|
||||||
@ -801,7 +804,8 @@ item visible. This message will disappear then.
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
, { title = "Due Date"
|
, { name = tabName TabDueDate
|
||||||
|
, title = texts.dueDateTab
|
||||||
, titleRight = []
|
, titleRight = []
|
||||||
, info = Nothing
|
, info = Nothing
|
||||||
, body =
|
, body =
|
||||||
@ -823,7 +827,8 @@ item visible. This message will disappear then.
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
, { title = "Correspondent"
|
, { name = tabName TabCorrespondent
|
||||||
|
, title = texts.basics.correspondent
|
||||||
, titleRight = []
|
, titleRight = []
|
||||||
, info = Nothing
|
, info = Nothing
|
||||||
, body =
|
, body =
|
||||||
@ -832,24 +837,35 @@ item visible. This message will disappear then.
|
|||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ Icons.organizationIcon2 ""
|
[ Icons.organizationIcon2 ""
|
||||||
, span [ class "ml-2" ]
|
, span [ class "ml-2" ]
|
||||||
[ text "Organization"
|
[ text texts.basics.organization
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, Html.map OrgDropdownMsg (Comp.Dropdown.view2 dds settings model.corrOrgModel)
|
, Html.map OrgDropdownMsg
|
||||||
|
(Comp.Dropdown.view2
|
||||||
|
idNameCfg
|
||||||
|
settings
|
||||||
|
model.corrOrgModel
|
||||||
|
)
|
||||||
]
|
]
|
||||||
, optional [ Data.Fields.CorrPerson ] <|
|
, optional [ Data.Fields.CorrPerson ] <|
|
||||||
div [ class "mb-4" ]
|
div [ class "mb-4" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ Icons.personIcon2 ""
|
[ Icons.personIcon2 ""
|
||||||
, span [ class "ml-2" ]
|
, span [ class "ml-2" ]
|
||||||
[ text "Person"
|
[ text texts.basics.person
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, Html.map CorrPersonMsg (Comp.Dropdown.view2 dds settings model.corrPersonModel)
|
, Html.map CorrPersonMsg
|
||||||
|
(Comp.Dropdown.view2
|
||||||
|
idNameCfg
|
||||||
|
settings
|
||||||
|
model.corrPersonModel
|
||||||
|
)
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
, { title = "Concerning"
|
, { name = tabName TabConcerning
|
||||||
|
, title = texts.basics.concerning
|
||||||
, titleRight = []
|
, titleRight = []
|
||||||
, info = Nothing
|
, info = Nothing
|
||||||
, body =
|
, body =
|
||||||
@ -858,29 +874,35 @@ item visible. This message will disappear then.
|
|||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ Icons.personIcon2 ""
|
[ Icons.personIcon2 ""
|
||||||
, span [ class "ml-2" ]
|
, span [ class "ml-2" ]
|
||||||
[ text "Person" ]
|
[ text texts.basics.person ]
|
||||||
]
|
]
|
||||||
, Html.map ConcPersonMsg (Comp.Dropdown.view2 dds settings model.concPersonModel)
|
, Html.map ConcPersonMsg (Comp.Dropdown.view2 idNameCfg settings model.concPersonModel)
|
||||||
]
|
]
|
||||||
, optional [ Data.Fields.ConcEquip ] <|
|
, optional [ Data.Fields.ConcEquip ] <|
|
||||||
div [ class "mb-4" ]
|
div [ class "mb-4" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ Icons.equipmentIcon2 ""
|
[ Icons.equipmentIcon2 ""
|
||||||
, span [ class "ml-2" ]
|
, span [ class "ml-2" ]
|
||||||
[ text "Equipment" ]
|
[ text texts.basics.equipment ]
|
||||||
]
|
]
|
||||||
, Html.map ConcEquipMsg (Comp.Dropdown.view2 dds settings model.concEquipModel)
|
, Html.map ConcEquipMsg
|
||||||
|
(Comp.Dropdown.view2 idNameCfg
|
||||||
|
settings
|
||||||
|
model.concEquipModel
|
||||||
|
)
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
, { title = "Direction"
|
, { name = tabName TabDirection
|
||||||
|
, title = texts.basics.direction
|
||||||
, titleRight = []
|
, titleRight = []
|
||||||
, info = Nothing
|
, info = Nothing
|
||||||
, body =
|
, body =
|
||||||
[ Html.map DirDropdownMsg (Comp.Dropdown.view2 dds settings model.directionModel)
|
[ Html.map DirDropdownMsg (Comp.Dropdown.view2 directionCfg settings model.directionModel)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
, { title = "Name"
|
, { name = tabName TabName
|
||||||
|
, title = texts.basics.name
|
||||||
, titleRight = []
|
, titleRight = []
|
||||||
, info = Nothing
|
, info = Nothing
|
||||||
, body =
|
, body =
|
||||||
@ -895,9 +917,15 @@ item visible. This message will disappear then.
|
|||||||
, span [ class S.inputLeftIconOnly ]
|
, span [ class S.inputLeftIconOnly ]
|
||||||
[ i
|
[ i
|
||||||
[ classList
|
[ classList
|
||||||
[ ( "text-green-500 fa fa-check", cfg.nameState == SaveSuccess )
|
[ ( "text-green-500 fa fa-check"
|
||||||
, ( "text-red-500 fa fa-exclamation-triangle", cfg.nameState == SaveFailed )
|
, cfg.nameState == SaveSuccess
|
||||||
, ( "sync fa fa-circle-notch animate-spin", cfg.nameState == Saving )
|
)
|
||||||
|
, ( "text-red-500 fa fa-exclamation-triangle"
|
||||||
|
, cfg.nameState == SaveFailed
|
||||||
|
)
|
||||||
|
, ( "sync fa fa-circle-notch animate-spin"
|
||||||
|
, cfg.nameState == Saving
|
||||||
|
)
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
[]
|
[]
|
||||||
@ -914,7 +942,7 @@ tabState settings model tab =
|
|||||||
FTabState.tabState settings
|
FTabState.tabState settings
|
||||||
model.openTabs
|
model.openTabs
|
||||||
(Just model.customFieldModel)
|
(Just model.customFieldModel)
|
||||||
(.title >> ToggleAkkordionTab)
|
(.name >> ToggleAkkordionTab)
|
||||||
tab
|
tab
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,19 +12,20 @@ import Html exposing (..)
|
|||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onClick)
|
import Html.Events exposing (onClick)
|
||||||
import Markdown
|
import Markdown
|
||||||
|
import Messages.Comp.ItemDetail.Notes exposing (Texts)
|
||||||
import Page exposing (Page(..))
|
import Page exposing (Page(..))
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.String
|
import Util.String
|
||||||
|
|
||||||
|
|
||||||
view : Model -> Html Msg
|
view : Texts -> Model -> Html Msg
|
||||||
view model =
|
view texts model =
|
||||||
case model.notesField of
|
case model.notesField of
|
||||||
ViewNotes ->
|
ViewNotes ->
|
||||||
div [ class "flex flex-col ds-item-detail-notes" ]
|
div [ class "flex flex-col ds-item-detail-notes" ]
|
||||||
[ div [ class "flex flex-row items-center border-b dark:border-bluegray-600" ]
|
[ div [ class "flex flex-row items-center border-b dark:border-bluegray-600" ]
|
||||||
[ div [ class "flex-grow font-bold text-lg" ]
|
[ div [ class "flex-grow font-bold text-lg" ]
|
||||||
[ text "Notes"
|
[ text texts.notes
|
||||||
]
|
]
|
||||||
, div [ class "" ]
|
, div [ class "" ]
|
||||||
[ a
|
[ a
|
||||||
@ -33,7 +34,7 @@ view model =
|
|||||||
, href "#"
|
, href "#"
|
||||||
]
|
]
|
||||||
[ i [ class "fa fa-edit mr-2" ] []
|
[ i [ class "fa fa-edit mr-2" ] []
|
||||||
, text "Edit"
|
, text texts.basics.edit
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -55,14 +56,14 @@ view model =
|
|||||||
[ div [ class "flex flex-col" ]
|
[ div [ class "flex flex-col" ]
|
||||||
[ div [ class "flex flex-row items-center" ]
|
[ div [ class "flex flex-row items-center" ]
|
||||||
[ div [ class "font-bold text-lg" ]
|
[ div [ class "font-bold text-lg" ]
|
||||||
[ text "Notes"
|
[ text texts.notes
|
||||||
]
|
]
|
||||||
, div [ class "flex flex-grow justify-end text-sm" ]
|
, div [ class "flex flex-grow justify-end text-sm" ]
|
||||||
[ Html.map NotesEditMsg
|
[ Html.map NotesEditMsg
|
||||||
(Comp.MarkdownInput.viewEditLink2 classes mm)
|
(Comp.MarkdownInput.viewEditLink2 texts.basics.edit classes mm)
|
||||||
, span [ class "px-3" ] [ text "•" ]
|
, span [ class "px-3" ] [ text "•" ]
|
||||||
, Html.map NotesEditMsg
|
, Html.map NotesEditMsg
|
||||||
(Comp.MarkdownInput.viewPreviewLink2 classes mm)
|
(Comp.MarkdownInput.viewPreviewLink2 texts.preview classes mm)
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -73,7 +74,9 @@ view model =
|
|||||||
mm
|
mm
|
||||||
)
|
)
|
||||||
, div [ class "text-sm flex justify-end" ]
|
, div [ class "text-sm flex justify-end" ]
|
||||||
[ Comp.MarkdownInput.viewCheatLink2 S.link mm
|
[ Comp.MarkdownInput.viewCheatLink2 texts.supportsMarkdown
|
||||||
|
S.link
|
||||||
|
mm
|
||||||
]
|
]
|
||||||
, div [ class "flex flex-row mt-1" ]
|
, div [ class "flex flex-row mt-1" ]
|
||||||
[ a
|
[ a
|
||||||
@ -82,7 +85,7 @@ view model =
|
|||||||
, onClick SaveNotes
|
, onClick SaveNotes
|
||||||
]
|
]
|
||||||
[ i [ class "fa fa-save font-thin mr-2" ] []
|
[ i [ class "fa fa-save font-thin mr-2" ] []
|
||||||
, text "Save"
|
, text texts.basics.submit
|
||||||
]
|
]
|
||||||
, a
|
, a
|
||||||
[ classList
|
[ classList
|
||||||
@ -94,7 +97,7 @@ view model =
|
|||||||
, onClick ToggleEditNotes
|
, onClick ToggleEditNotes
|
||||||
]
|
]
|
||||||
[ i [ class "fa fa-times mr-2" ] []
|
[ i [ class "fa fa-times mr-2" ] []
|
||||||
, text "Cancel"
|
, text texts.basics.cancel
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
@ -18,6 +18,7 @@ import Html exposing (..)
|
|||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onClick, onInput)
|
import Html.Events exposing (onClick, onInput)
|
||||||
import Html5.DragDrop as DD
|
import Html5.DragDrop as DD
|
||||||
|
import Messages.Comp.ItemDetail.SingleAttachment exposing (Texts)
|
||||||
import Page exposing (Page(..))
|
import Page exposing (Page(..))
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.Maybe
|
import Util.Maybe
|
||||||
@ -25,8 +26,8 @@ import Util.Size
|
|||||||
import Util.String
|
import Util.String
|
||||||
|
|
||||||
|
|
||||||
view : UiSettings -> Model -> Int -> Attachment -> Html Msg
|
view : Texts -> UiSettings -> Model -> Int -> Attachment -> Html Msg
|
||||||
view settings model pos attach =
|
view texts settings model pos attach =
|
||||||
let
|
let
|
||||||
fileUrl =
|
fileUrl =
|
||||||
Api.fileURL attach.id
|
Api.fileURL attach.id
|
||||||
@ -42,15 +43,16 @@ view settings model pos attach =
|
|||||||
[ class "flex flex-row px-2 py-2 text-sm"
|
[ class "flex flex-row px-2 py-2 text-sm"
|
||||||
, class S.border
|
, class S.border
|
||||||
]
|
]
|
||||||
[ attachHeader settings model pos attach
|
[ attachHeader texts settings model pos attach
|
||||||
]
|
]
|
||||||
, editAttachmentName model attach
|
, editAttachmentName model attach
|
||||||
, attachmentSelect model pos attach
|
, attachmentSelect texts model pos attach
|
||||||
, if isAttachMetaOpen model attach.id then
|
, if isAttachMetaOpen model attach.id then
|
||||||
case Dict.get attach.id model.attachMeta of
|
case Dict.get attach.id model.attachMeta of
|
||||||
Just am ->
|
Just am ->
|
||||||
Html.map (AttachMetaMsg attach.id)
|
Html.map (AttachMetaMsg attach.id)
|
||||||
(Comp.AttachmentMeta.view2
|
(Comp.AttachmentMeta.view2
|
||||||
|
texts.attachmentMeta
|
||||||
[ class "border-r border-l border-b dark:border-bluegray-600 px-2" ]
|
[ class "border-r border-l border-b dark:border-bluegray-600 px-2" ]
|
||||||
am
|
am
|
||||||
)
|
)
|
||||||
@ -94,11 +96,11 @@ view settings model pos attach =
|
|||||||
- native view
|
- native view
|
||||||
|
|
||||||
-}
|
-}
|
||||||
attachHeader : UiSettings -> Model -> Int -> Attachment -> Html Msg
|
attachHeader : Texts -> UiSettings -> Model -> Int -> Attachment -> Html Msg
|
||||||
attachHeader settings model _ attach =
|
attachHeader texts settings model _ attach =
|
||||||
let
|
let
|
||||||
attachName =
|
attachName =
|
||||||
Maybe.withDefault "No name" attach.name
|
Maybe.withDefault texts.noName attach.name
|
||||||
|
|
||||||
fileUrl =
|
fileUrl =
|
||||||
Api.fileURL attach.id
|
Api.fileURL attach.id
|
||||||
@ -138,7 +140,7 @@ attachHeader settings model _ attach =
|
|||||||
, a
|
, a
|
||||||
[ href fileUrl
|
[ href fileUrl
|
||||||
, target "_new"
|
, target "_new"
|
||||||
, title "Open file in new tab"
|
, title texts.openFileInNewTab
|
||||||
, class S.secondaryBasicButton
|
, class S.secondaryBasicButton
|
||||||
, class "ml-2"
|
, class "ml-2"
|
||||||
]
|
]
|
||||||
@ -155,21 +157,21 @@ attachHeader settings model _ attach =
|
|||||||
, menuOpen = model.attachmentDropdownOpen
|
, menuOpen = model.attachmentDropdownOpen
|
||||||
, items =
|
, items =
|
||||||
[ { icon = "fa fa-download"
|
[ { icon = "fa fa-download"
|
||||||
, label = "Download file"
|
, label = texts.downloadFile
|
||||||
, attrs =
|
, attrs =
|
||||||
[ download attachName
|
[ download attachName
|
||||||
, href fileUrl
|
, href fileUrl
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
, { icon = "fa fa-file"
|
, { icon = "fa fa-file"
|
||||||
, label = "Rename file"
|
, label = texts.renameFile
|
||||||
, attrs =
|
, attrs =
|
||||||
[ href "#"
|
[ href "#"
|
||||||
, onClick (EditAttachNameStart attach.id)
|
, onClick (EditAttachNameStart attach.id)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
, { icon = "fa fa-file-archive"
|
, { icon = "fa fa-file-archive"
|
||||||
, label = "Download original archive"
|
, label = texts.downloadOriginalArchiveFile
|
||||||
, attrs =
|
, attrs =
|
||||||
[ href (fileUrl ++ "/archive")
|
[ href (fileUrl ++ "/archive")
|
||||||
, target "_new"
|
, target "_new"
|
||||||
@ -177,7 +179,7 @@ attachHeader settings model _ attach =
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
, { icon = "fa fa-external-link-alt"
|
, { icon = "fa fa-external-link-alt"
|
||||||
, label = "Original file"
|
, label = texts.originalFile
|
||||||
, attrs =
|
, attrs =
|
||||||
[ href (fileUrl ++ "/original")
|
[ href (fileUrl ++ "/original")
|
||||||
, target "_new"
|
, target "_new"
|
||||||
@ -190,7 +192,7 @@ attachHeader settings model _ attach =
|
|||||||
|
|
||||||
else
|
else
|
||||||
"fa fa-toggle-off"
|
"fa fa-toggle-off"
|
||||||
, label = "Render pdf by browser"
|
, label = texts.renderPdfByBrowser
|
||||||
, attrs =
|
, attrs =
|
||||||
[ onClick (TogglePdfNativeView settings.nativePdfPreview)
|
[ onClick (TogglePdfNativeView settings.nativePdfPreview)
|
||||||
, href "#"
|
, href "#"
|
||||||
@ -202,21 +204,21 @@ attachHeader settings model _ attach =
|
|||||||
|
|
||||||
else
|
else
|
||||||
"fa fa-toggle-off"
|
"fa fa-toggle-off"
|
||||||
, label = "View extracted data"
|
, label = texts.viewExtractedData
|
||||||
, attrs =
|
, attrs =
|
||||||
[ onClick (AttachMetaClick attach.id)
|
[ onClick (AttachMetaClick attach.id)
|
||||||
, href "#"
|
, href "#"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
, { icon = "fa fa-redo-alt"
|
, { icon = "fa fa-redo-alt"
|
||||||
, label = "Re-process this file"
|
, label = texts.reprocessFile
|
||||||
, attrs =
|
, attrs =
|
||||||
[ onClick (RequestReprocessFile attach.id)
|
[ onClick (RequestReprocessFile attach.id)
|
||||||
, href "#"
|
, href "#"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
, { icon = "fa fa-trash"
|
, { icon = "fa fa-trash"
|
||||||
, label = "Delete this file"
|
, label = texts.deleteThisFile
|
||||||
, attrs =
|
, attrs =
|
||||||
[ onClick (RequestDeleteAttachment attach.id)
|
[ onClick (RequestDeleteAttachment attach.id)
|
||||||
, href "#"
|
, href "#"
|
||||||
@ -279,8 +281,8 @@ editAttachmentName model attach =
|
|||||||
span [ class "hidden" ] []
|
span [ class "hidden" ] []
|
||||||
|
|
||||||
|
|
||||||
attachmentSelect : Model -> Int -> Attachment -> Html Msg
|
attachmentSelect : Texts -> Model -> Int -> Attachment -> Html Msg
|
||||||
attachmentSelect model _ _ =
|
attachmentSelect texts model _ _ =
|
||||||
div
|
div
|
||||||
[ class "flex flex-row border-l border-r px-2 py-2 dark:border-bluegray-600 "
|
[ class "flex flex-row border-l border-r px-2 py-2 dark:border-bluegray-600 "
|
||||||
, class "overflow-x-auto overflow-y-none"
|
, class "overflow-x-auto overflow-y-none"
|
||||||
@ -288,11 +290,11 @@ attachmentSelect model _ _ =
|
|||||||
[ ( "hidden", not model.attachMenuOpen )
|
[ ( "hidden", not model.attachMenuOpen )
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
(List.indexedMap (menuItem model) model.item.attachments)
|
(List.indexedMap (menuItem texts model) model.item.attachments)
|
||||||
|
|
||||||
|
|
||||||
menuItem : Model -> Int -> Attachment -> Html Msg
|
menuItem : Texts -> Model -> Int -> Attachment -> Html Msg
|
||||||
menuItem model pos attach =
|
menuItem texts model pos attach =
|
||||||
let
|
let
|
||||||
highlight =
|
highlight =
|
||||||
let
|
let
|
||||||
@ -342,7 +344,7 @@ menuItem model pos attach =
|
|||||||
]
|
]
|
||||||
, div [ class "mt-1 text-sm break-all w-28 text-center" ]
|
, div [ class "mt-1 text-sm break-all w-28 text-center" ]
|
||||||
[ Maybe.map (Util.String.ellipsis 36) attach.name
|
[ Maybe.map (Util.String.ellipsis 36) attach.name
|
||||||
|> Maybe.withDefault "No Name"
|
|> Maybe.withDefault texts.noName
|
||||||
|> text
|
|> text
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
@ -24,6 +24,7 @@ import Comp.Dropdown exposing (isDropdownChangeMsg)
|
|||||||
import Comp.Dropzone
|
import Comp.Dropzone
|
||||||
import Comp.EquipmentForm
|
import Comp.EquipmentForm
|
||||||
import Comp.ItemDetail.EditForm
|
import Comp.ItemDetail.EditForm
|
||||||
|
import Comp.ItemDetail.FieldTabState as FTabState
|
||||||
import Comp.ItemDetail.Model
|
import Comp.ItemDetail.Model
|
||||||
exposing
|
exposing
|
||||||
( AttachmentRename
|
( AttachmentRename
|
||||||
@ -62,7 +63,6 @@ import Set exposing (Set)
|
|||||||
import Throttle
|
import Throttle
|
||||||
import Time
|
import Time
|
||||||
import Util.File exposing (makeFileId)
|
import Util.File exposing (makeFileId)
|
||||||
import Util.Folder exposing (mkFolderOption)
|
|
||||||
import Util.Http
|
import Util.Http
|
||||||
import Util.List
|
import Util.List
|
||||||
import Util.Maybe
|
import Util.Maybe
|
||||||
@ -551,6 +551,8 @@ update key flags inav settings msg model =
|
|||||||
Comp.ConfirmModal.defaultSettings
|
Comp.ConfirmModal.defaultSettings
|
||||||
DeleteItemConfirmed
|
DeleteItemConfirmed
|
||||||
ItemModalCancelled
|
ItemModalCancelled
|
||||||
|
"Ok"
|
||||||
|
"Cancel"
|
||||||
confirmMsg
|
confirmMsg
|
||||||
in
|
in
|
||||||
resultModel { model | itemModal = Just confirm }
|
resultModel { model | itemModal = Just confirm }
|
||||||
@ -576,13 +578,7 @@ update key flags inav settings msg model =
|
|||||||
GetFolderResp (Ok fs) ->
|
GetFolderResp (Ok fs) ->
|
||||||
let
|
let
|
||||||
model_ =
|
model_ =
|
||||||
{ model
|
{ model | allFolders = fs.items }
|
||||||
| allFolders = fs.items
|
|
||||||
, folderModel =
|
|
||||||
Comp.Dropdown.setMkOption
|
|
||||||
(mkFolderOption flags fs.items)
|
|
||||||
model.folderModel
|
|
||||||
}
|
|
||||||
|
|
||||||
mkIdName fitem =
|
mkIdName fitem =
|
||||||
IdName fitem.id fitem.name
|
IdName fitem.id fitem.name
|
||||||
@ -645,23 +641,8 @@ update key flags inav settings msg model =
|
|||||||
List.filter personFilter correspondent
|
List.filter personFilter correspondent
|
||||||
|> List.map (\e -> IdName e.id e.name)
|
|> List.map (\e -> IdName e.id e.name)
|
||||||
|
|
||||||
mkPersonOption idref =
|
|
||||||
let
|
|
||||||
org =
|
|
||||||
Dict.get idref.id personDict
|
|
||||||
|> Maybe.andThen .organization
|
|
||||||
|> Maybe.map .name
|
|
||||||
|> Maybe.map (Util.String.ellipsis 15)
|
|
||||||
|> Maybe.withDefault ""
|
|
||||||
in
|
|
||||||
Comp.Dropdown.Option idref.id idref.name org
|
|
||||||
|
|
||||||
model_ =
|
model_ =
|
||||||
{ model
|
{ model | allPersons = personDict }
|
||||||
| corrPersonModel = Comp.Dropdown.setMkOption mkPersonOption model.corrPersonModel
|
|
||||||
, concPersonModel = Comp.Dropdown.setMkOption mkPersonOption model.concPersonModel
|
|
||||||
, allPersons = personDict
|
|
||||||
}
|
|
||||||
|
|
||||||
res1 =
|
res1 =
|
||||||
update key
|
update key
|
||||||
@ -945,6 +926,8 @@ update key flags inav settings msg model =
|
|||||||
Comp.ConfirmModal.defaultSettings
|
Comp.ConfirmModal.defaultSettings
|
||||||
(DeleteAttachConfirmed id)
|
(DeleteAttachConfirmed id)
|
||||||
AttachModalCancelled
|
AttachModalCancelled
|
||||||
|
"Ok"
|
||||||
|
"Cancel"
|
||||||
"Really delete this file?"
|
"Really delete this file?"
|
||||||
|
|
||||||
model_ =
|
model_ =
|
||||||
@ -1491,22 +1474,21 @@ update key flags inav settings msg model =
|
|||||||
ToggleAttachmentDropdown ->
|
ToggleAttachmentDropdown ->
|
||||||
resultModel { model | attachmentDropdownOpen = not model.attachmentDropdownOpen }
|
resultModel { model | attachmentDropdownOpen = not model.attachmentDropdownOpen }
|
||||||
|
|
||||||
ToggleAkkordionTab title ->
|
ToggleAkkordionTab name ->
|
||||||
let
|
let
|
||||||
tabs =
|
tabs =
|
||||||
if Set.member title model.editMenuTabsOpen then
|
if Set.member name model.editMenuTabsOpen then
|
||||||
Set.remove title model.editMenuTabsOpen
|
Set.remove name model.editMenuTabsOpen
|
||||||
|
|
||||||
else
|
else
|
||||||
Set.insert title model.editMenuTabsOpen
|
Set.insert name model.editMenuTabsOpen
|
||||||
in
|
in
|
||||||
resultModel { model | editMenuTabsOpen = tabs }
|
resultModel { model | editMenuTabsOpen = tabs }
|
||||||
|
|
||||||
ToggleOpenAllAkkordionTabs ->
|
ToggleOpenAllAkkordionTabs ->
|
||||||
let
|
let
|
||||||
allNames =
|
allNames =
|
||||||
Comp.ItemDetail.EditForm.formTabs settings model
|
List.map FTabState.tabName FTabState.allTabs
|
||||||
|> List.map .title
|
|
||||||
|> Set.fromList
|
|> Set.fromList
|
||||||
|
|
||||||
next =
|
next =
|
||||||
@ -1533,6 +1515,8 @@ update key flags inav settings msg model =
|
|||||||
Comp.ConfirmModal.defaultSettings
|
Comp.ConfirmModal.defaultSettings
|
||||||
(ReprocessFileConfirmed id)
|
(ReprocessFileConfirmed id)
|
||||||
AttachModalCancelled
|
AttachModalCancelled
|
||||||
|
"Ok"
|
||||||
|
"Cancel"
|
||||||
confirmMsg
|
confirmMsg
|
||||||
|
|
||||||
model_ =
|
model_ =
|
||||||
@ -1568,6 +1552,8 @@ update key flags inav settings msg model =
|
|||||||
Comp.ConfirmModal.defaultSettings
|
Comp.ConfirmModal.defaultSettings
|
||||||
ReprocessItemConfirmed
|
ReprocessItemConfirmed
|
||||||
ItemModalCancelled
|
ItemModalCancelled
|
||||||
|
"Ok"
|
||||||
|
"Cancel"
|
||||||
confirmMsg
|
confirmMsg
|
||||||
|
|
||||||
model_ =
|
model_ =
|
||||||
|
@ -23,17 +23,18 @@ import Data.UiSettings exposing (UiSettings)
|
|||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onClick)
|
import Html.Events exposing (onClick)
|
||||||
|
import Messages.Comp.ItemDetail exposing (Texts)
|
||||||
import Page exposing (Page(..))
|
import Page exposing (Page(..))
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.Time
|
import Util.Time
|
||||||
|
|
||||||
|
|
||||||
view : ItemNav -> UiSettings -> Model -> Html Msg
|
view : Texts -> ItemNav -> UiSettings -> Model -> Html Msg
|
||||||
view inav settings model =
|
view texts inav settings model =
|
||||||
div [ class "flex flex-col h-full" ]
|
div [ class "flex flex-col h-full" ]
|
||||||
[ header settings model
|
[ header texts settings model
|
||||||
, menuBar inav settings model
|
, menuBar texts inav settings model
|
||||||
, body inav settings model
|
, body texts inav settings model
|
||||||
, itemModal model
|
, itemModal model
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -48,18 +49,18 @@ itemModal model =
|
|||||||
span [ class "hidden" ] []
|
span [ class "hidden" ] []
|
||||||
|
|
||||||
|
|
||||||
header : UiSettings -> Model -> Html Msg
|
header : Texts -> UiSettings -> Model -> Html Msg
|
||||||
header settings model =
|
header texts settings model =
|
||||||
div [ class "my-3" ]
|
div [ class "my-3" ]
|
||||||
[ Comp.ItemDetail.ItemInfoHeader.view settings model ]
|
[ Comp.ItemDetail.ItemInfoHeader.view texts.itemInfoHeader settings model ]
|
||||||
|
|
||||||
|
|
||||||
menuBar : ItemNav -> UiSettings -> Model -> Html Msg
|
menuBar : Texts -> ItemNav -> UiSettings -> Model -> Html Msg
|
||||||
menuBar inav settings model =
|
menuBar texts inav settings model =
|
||||||
let
|
let
|
||||||
keyDescr name =
|
keyDescr name =
|
||||||
if settings.itemDetailShortcuts && model.menuOpen then
|
if settings.itemDetailShortcuts && model.menuOpen then
|
||||||
" Key '" ++ name ++ "'."
|
" " ++ texts.key ++ "'" ++ name ++ "'."
|
||||||
|
|
||||||
else
|
else
|
||||||
""
|
""
|
||||||
@ -70,7 +71,7 @@ menuBar inav settings model =
|
|||||||
a
|
a
|
||||||
[ class S.secondaryBasicButton
|
[ class S.secondaryBasicButton
|
||||||
, Page.href HomePage
|
, Page.href HomePage
|
||||||
, title "Back to search results"
|
, title texts.backToSearchResults
|
||||||
]
|
]
|
||||||
[ i [ class "fa fa-arrow-left" ] []
|
[ i [ class "fa fa-arrow-left" ] []
|
||||||
]
|
]
|
||||||
@ -87,7 +88,7 @@ menuBar inav settings model =
|
|||||||
|> Maybe.withDefault (href "#")
|
|> Maybe.withDefault (href "#")
|
||||||
, disabled = inav.prev == Nothing
|
, disabled = inav.prev == Nothing
|
||||||
, attrs =
|
, attrs =
|
||||||
[ title ("Previous item." ++ keyDescr "Ctrl-,")
|
[ title (texts.previousItem ++ keyDescr "Ctrl-,")
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
, div
|
, div
|
||||||
@ -116,7 +117,7 @@ menuBar inav settings model =
|
|||||||
|> Maybe.withDefault (href "#")
|
|> Maybe.withDefault (href "#")
|
||||||
, disabled = inav.next == Nothing
|
, disabled = inav.next == Nothing
|
||||||
, attrs =
|
, attrs =
|
||||||
[ title ("Next item." ++ keyDescr "Ctrl-.")
|
[ title (texts.nextItem ++ keyDescr "Ctrl-.")
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -125,7 +126,7 @@ menuBar inav settings model =
|
|||||||
[ classList
|
[ classList
|
||||||
[ ( "bg-gray-200 dark:bg-bluegray-600", model.mailOpen )
|
[ ( "bg-gray-200 dark:bg-bluegray-600", model.mailOpen )
|
||||||
]
|
]
|
||||||
, title "Send Mail"
|
, title texts.sendMail
|
||||||
, onClick ToggleMail
|
, onClick ToggleMail
|
||||||
, class S.secondaryBasicButton
|
, class S.secondaryBasicButton
|
||||||
, href "#"
|
, href "#"
|
||||||
@ -141,7 +142,7 @@ menuBar inav settings model =
|
|||||||
title "Close"
|
title "Close"
|
||||||
|
|
||||||
else
|
else
|
||||||
title "Add more files to this item"
|
title texts.addMoreFiles
|
||||||
, onClick AddFilesToggle
|
, onClick AddFilesToggle
|
||||||
, class S.secondaryBasicButton
|
, class S.secondaryBasicButton
|
||||||
, href "#"
|
, href "#"
|
||||||
@ -153,11 +154,11 @@ menuBar inav settings model =
|
|||||||
[ class S.primaryButton
|
[ class S.primaryButton
|
||||||
, href "#"
|
, href "#"
|
||||||
, onClick ConfirmItem
|
, onClick ConfirmItem
|
||||||
, title "Confirm item metadata"
|
, title texts.confirmItemMetadata
|
||||||
, classList [ ( "hidden", model.item.state /= "created" ) ]
|
, classList [ ( "hidden", model.item.state /= "created" ) ]
|
||||||
]
|
]
|
||||||
[ i [ class "fa fa-check mr-2" ] []
|
[ i [ class "fa fa-check mr-2" ] []
|
||||||
, text "Confirm"
|
, text texts.confirm
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, end =
|
, end =
|
||||||
@ -166,7 +167,7 @@ menuBar inav settings model =
|
|||||||
[ class S.secondaryBasicButton
|
[ class S.secondaryBasicButton
|
||||||
, href "#"
|
, href "#"
|
||||||
, onClick UnconfirmItem
|
, onClick UnconfirmItem
|
||||||
, title "Un-confirm item metadata"
|
, title texts.unconfirmItemMetadata
|
||||||
, classList [ ( "hidden", model.item.state == "created" ) ]
|
, classList [ ( "hidden", model.item.state == "created" ) ]
|
||||||
]
|
]
|
||||||
[ i [ class "fa fa-eye-slash font-thin" ] []
|
[ i [ class "fa fa-eye-slash font-thin" ] []
|
||||||
@ -176,7 +177,7 @@ menuBar inav settings model =
|
|||||||
[ class S.secondaryBasicButton
|
[ class S.secondaryBasicButton
|
||||||
, href "#"
|
, href "#"
|
||||||
, onClick RequestReprocessItem
|
, onClick RequestReprocessItem
|
||||||
, title "Reprocess this item"
|
, title texts.reprocessItem
|
||||||
]
|
]
|
||||||
[ i [ class "fa fa-redo" ] []
|
[ i [ class "fa fa-redo" ] []
|
||||||
]
|
]
|
||||||
@ -185,7 +186,7 @@ menuBar inav settings model =
|
|||||||
[ class S.deleteButton
|
[ class S.deleteButton
|
||||||
, href "#"
|
, href "#"
|
||||||
, onClick RequestDelete
|
, onClick RequestDelete
|
||||||
, title "Delete this item"
|
, title texts.deleteThisItem
|
||||||
]
|
]
|
||||||
[ i [ class "fa fa-trash" ] []
|
[ i [ class "fa fa-trash" ] []
|
||||||
]
|
]
|
||||||
@ -194,21 +195,21 @@ menuBar inav settings model =
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
body : ItemNav -> UiSettings -> Model -> Html Msg
|
body : Texts -> ItemNav -> UiSettings -> Model -> Html Msg
|
||||||
body inav settings model =
|
body texts _ settings model =
|
||||||
div [ class "grid gap-2 grid-cols-1 md:grid-cols-3 h-full" ]
|
div [ class "grid gap-2 grid-cols-1 md:grid-cols-3 h-full" ]
|
||||||
[ leftArea settings model
|
[ leftArea texts settings model
|
||||||
, rightArea settings model
|
, rightArea texts settings model
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
leftArea : UiSettings -> Model -> Html Msg
|
leftArea : Texts -> UiSettings -> Model -> Html Msg
|
||||||
leftArea settings model =
|
leftArea texts settings model =
|
||||||
div [ class "w-full md:order-first md:mr-2 flex flex-col" ]
|
div [ class "w-full md:order-first md:mr-2 flex flex-col" ]
|
||||||
[ addDetailForm settings model
|
[ addDetailForm texts settings model
|
||||||
, sendMailForm settings model
|
, sendMailForm texts settings model
|
||||||
, Comp.ItemDetail.AddFilesForm.view model
|
, Comp.ItemDetail.AddFilesForm.view texts.addFilesForm model
|
||||||
, Comp.ItemDetail.Notes.view model
|
, Comp.ItemDetail.Notes.view texts.notes model
|
||||||
, div
|
, div
|
||||||
[ classList
|
[ classList
|
||||||
[ ( "hidden", Comp.SentMails.isEmpty model.sentMails )
|
[ ( "hidden", Comp.SentMails.isEmpty model.sentMails )
|
||||||
@ -216,29 +217,29 @@ leftArea settings model =
|
|||||||
, class "mt-4 "
|
, class "mt-4 "
|
||||||
]
|
]
|
||||||
[ h3 [ class "flex flex-row items-center border-b dark:border-bluegray-600 font-bold text-lg" ]
|
[ h3 [ class "flex flex-row items-center border-b dark:border-bluegray-600 font-bold text-lg" ]
|
||||||
[ text "Sent E-Mails"
|
[ text texts.sentEmails
|
||||||
]
|
]
|
||||||
, Html.map SentMailsMsg (Comp.SentMails.view2 model.sentMails)
|
, Html.map SentMailsMsg (Comp.SentMails.view2 texts.sentMails model.sentMails)
|
||||||
]
|
]
|
||||||
, div [ class "flex-grow" ] []
|
, div [ class "flex-grow" ] []
|
||||||
, itemIdInfo model
|
, itemIdInfo texts model
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
rightArea : UiSettings -> Model -> Html Msg
|
rightArea : Texts -> UiSettings -> Model -> Html Msg
|
||||||
rightArea settings model =
|
rightArea texts settings model =
|
||||||
div [ class "md:col-span-2 h-full" ]
|
div [ class "md:col-span-2 h-full" ]
|
||||||
(attachmentsBody settings model)
|
(attachmentsBody texts settings model)
|
||||||
|
|
||||||
|
|
||||||
attachmentsBody : UiSettings -> Model -> List (Html Msg)
|
attachmentsBody : Texts -> UiSettings -> Model -> List (Html Msg)
|
||||||
attachmentsBody settings model =
|
attachmentsBody texts settings model =
|
||||||
List.indexedMap (Comp.ItemDetail.SingleAttachment.view settings model)
|
List.indexedMap (Comp.ItemDetail.SingleAttachment.view texts.singleAttachment settings model)
|
||||||
model.item.attachments
|
model.item.attachments
|
||||||
|
|
||||||
|
|
||||||
sendMailForm : UiSettings -> Model -> Html Msg
|
sendMailForm : Texts -> UiSettings -> Model -> Html Msg
|
||||||
sendMailForm settings model =
|
sendMailForm texts settings model =
|
||||||
div
|
div
|
||||||
[ classList
|
[ classList
|
||||||
[ ( "hidden", not model.mailOpen )
|
[ ( "hidden", not model.mailOpen )
|
||||||
@ -247,10 +248,13 @@ sendMailForm settings model =
|
|||||||
, class "mb-4 px-2 py-2"
|
, class "mb-4 px-2 py-2"
|
||||||
]
|
]
|
||||||
[ div [ class "text-lg font-bold" ]
|
[ div [ class "text-lg font-bold" ]
|
||||||
[ text "Send this item via E-Mail"
|
[ text texts.sendThisItemViaEmail
|
||||||
]
|
]
|
||||||
, B.loadingDimmer model.mailSending
|
, B.loadingDimmer
|
||||||
, Html.map ItemMailMsg (Comp.ItemMail.view2 settings model.itemMail)
|
{ active = model.mailSending
|
||||||
|
, label = texts.sendingMailNow
|
||||||
|
}
|
||||||
|
, Html.map ItemMailMsg (Comp.ItemMail.view2 texts.itemMail settings model.itemMail)
|
||||||
, div
|
, div
|
||||||
[ classList
|
[ classList
|
||||||
[ ( S.errorMessage
|
[ ( S.errorMessage
|
||||||
@ -273,26 +277,26 @@ sendMailForm settings model =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
itemIdInfo : Model -> Html msg
|
itemIdInfo : Texts -> Model -> Html msg
|
||||||
itemIdInfo model =
|
itemIdInfo texts model =
|
||||||
div [ class "flex flex-col opacity-50 text-xs pb-1 mt-3 border-t dark:border-bluegray-600" ]
|
div [ class "flex flex-col opacity-50 text-xs pb-1 mt-3 border-t dark:border-bluegray-600" ]
|
||||||
[ div
|
[ div
|
||||||
[ class "inline-flex items-center"
|
[ class "inline-flex items-center"
|
||||||
, title "Item ID"
|
, title texts.itemId
|
||||||
]
|
]
|
||||||
[ i [ class "fa fa-bullseye mr-2" ] []
|
[ i [ class "fa fa-bullseye mr-2" ] []
|
||||||
, text model.item.id
|
, text model.item.id
|
||||||
]
|
]
|
||||||
, div
|
, div
|
||||||
[ class "inline-flex items-center"
|
[ class "inline-flex items-center"
|
||||||
, title "Created on"
|
, title texts.createdOn
|
||||||
]
|
]
|
||||||
[ i [ class "fa fa-sun font-thin mr-2" ] []
|
[ i [ class "fa fa-sun font-thin mr-2" ] []
|
||||||
, Util.Time.formatDateTime model.item.created |> text
|
, Util.Time.formatDateTime model.item.created |> text
|
||||||
]
|
]
|
||||||
, div
|
, div
|
||||||
[ class "inline-flex items-center"
|
[ class "inline-flex items-center"
|
||||||
, title "Last update on"
|
, title texts.lastUpdateOn
|
||||||
]
|
]
|
||||||
[ i [ class "fa fa-pencil-alt mr-2" ] []
|
[ i [ class "fa fa-pencil-alt mr-2" ] []
|
||||||
, Util.Time.formatDateTime model.item.updated |> text
|
, Util.Time.formatDateTime model.item.updated |> text
|
||||||
@ -300,8 +304,8 @@ itemIdInfo model =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
addDetailForm : UiSettings -> Model -> Html Msg
|
addDetailForm : Texts -> UiSettings -> Model -> Html Msg
|
||||||
addDetailForm settings model =
|
addDetailForm texts settings model =
|
||||||
case model.modalEdit of
|
case model.modalEdit of
|
||||||
Just mm ->
|
Just mm ->
|
||||||
div
|
div
|
||||||
@ -309,7 +313,7 @@ addDetailForm settings model =
|
|||||||
, class S.box
|
, class S.box
|
||||||
]
|
]
|
||||||
[ Comp.DetailEdit.formHeading S.header3 mm
|
[ Comp.DetailEdit.formHeading S.header3 mm
|
||||||
, Html.map ModalEditMsg (Comp.DetailEdit.view2 [] settings mm)
|
, Html.map ModalEditMsg (Comp.DetailEdit.view2 texts.detailEdit [] settings mm)
|
||||||
]
|
]
|
||||||
|
|
||||||
Nothing ->
|
Nothing ->
|
||||||
|
@ -23,6 +23,7 @@ import Html exposing (..)
|
|||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onClick, onInput)
|
import Html.Events exposing (onClick, onInput)
|
||||||
import Http
|
import Http
|
||||||
|
import Messages.Comp.ItemMail exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.Http
|
import Util.Http
|
||||||
|
|
||||||
@ -69,11 +70,7 @@ type FormAction
|
|||||||
|
|
||||||
emptyModel : Model
|
emptyModel : Model
|
||||||
emptyModel =
|
emptyModel =
|
||||||
{ connectionModel =
|
{ connectionModel = Comp.Dropdown.makeSingle
|
||||||
Comp.Dropdown.makeSingle
|
|
||||||
{ makeOption = \a -> { value = a, text = a, additional = "" }
|
|
||||||
, placeholder = "Select connection..."
|
|
||||||
}
|
|
||||||
, subject = ""
|
, subject = ""
|
||||||
, recipients = []
|
, recipients = []
|
||||||
, recipientsModel = Comp.EmailInput.init
|
, recipientsModel = Comp.EmailInput.init
|
||||||
@ -160,9 +157,7 @@ update flags msg model =
|
|||||||
|
|
||||||
cm =
|
cm =
|
||||||
Comp.Dropdown.makeSingleList
|
Comp.Dropdown.makeSingleList
|
||||||
{ makeOption = \a -> { value = a, text = a, additional = "" }
|
{ options = names
|
||||||
, placeholder = "Select Connection..."
|
|
||||||
, options = names
|
|
||||||
, selected = List.head names
|
, selected = List.head names
|
||||||
}
|
}
|
||||||
in
|
in
|
||||||
@ -224,21 +219,33 @@ isValid model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : UiSettings -> Model -> Html Msg
|
view2 : Texts -> UiSettings -> Model -> Html Msg
|
||||||
view2 settings model =
|
view2 texts settings model =
|
||||||
let
|
let
|
||||||
dds =
|
dds =
|
||||||
Data.DropdownStyle.mainStyle
|
Data.DropdownStyle.mainStyle
|
||||||
|
|
||||||
|
connectionCfg =
|
||||||
|
{ makeOption = \a -> { text = a, additional = "" }
|
||||||
|
, placeholder = texts.selectConnection
|
||||||
|
, labelColor = \_ -> \_ -> ""
|
||||||
|
, style = dds
|
||||||
|
}
|
||||||
in
|
in
|
||||||
div
|
div
|
||||||
[ class "flex flex-col"
|
[ class "flex flex-col"
|
||||||
]
|
]
|
||||||
[ div [ class "mb-4" ]
|
[ div [ class "mb-4" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "Send via"
|
[ text texts.sendVia
|
||||||
, B.inputRequired
|
, B.inputRequired
|
||||||
]
|
]
|
||||||
, Html.map ConnMsg (Comp.Dropdown.view2 dds settings model.connectionModel)
|
, Html.map ConnMsg
|
||||||
|
(Comp.Dropdown.view2
|
||||||
|
connectionCfg
|
||||||
|
settings
|
||||||
|
model.connectionModel
|
||||||
|
)
|
||||||
]
|
]
|
||||||
, div
|
, div
|
||||||
[ class S.errorMessage
|
[ class S.errorMessage
|
||||||
@ -250,29 +257,38 @@ view2 settings model =
|
|||||||
[ label
|
[ label
|
||||||
[ class S.inputLabel
|
[ class S.inputLabel
|
||||||
]
|
]
|
||||||
[ text "Recipient(s)"
|
[ text texts.recipients
|
||||||
, B.inputRequired
|
, B.inputRequired
|
||||||
]
|
]
|
||||||
, Html.map RecipientMsg
|
, Html.map RecipientMsg
|
||||||
(Comp.EmailInput.view2 dds model.recipients model.recipientsModel)
|
(Comp.EmailInput.view2 { style = dds, placeholder = appendDots texts.recipients }
|
||||||
|
model.recipients
|
||||||
|
model.recipientsModel
|
||||||
|
)
|
||||||
]
|
]
|
||||||
, div [ class "mb-4" ]
|
, div [ class "mb-4" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "CC(s)"
|
[ text texts.ccRecipients
|
||||||
]
|
]
|
||||||
, Html.map CCRecipientMsg
|
, Html.map CCRecipientMsg
|
||||||
(Comp.EmailInput.view2 dds model.ccRecipients model.ccRecipientsModel)
|
(Comp.EmailInput.view2 { style = dds, placeholder = appendDots texts.ccRecipients }
|
||||||
|
model.ccRecipients
|
||||||
|
model.ccRecipientsModel
|
||||||
|
)
|
||||||
]
|
]
|
||||||
, div [ class "mb-4" ]
|
, div [ class "mb-4" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "BCC(s)"
|
[ text texts.bccRecipients
|
||||||
]
|
]
|
||||||
, Html.map BCCRecipientMsg
|
, Html.map BCCRecipientMsg
|
||||||
(Comp.EmailInput.view2 dds model.bccRecipients model.bccRecipientsModel)
|
(Comp.EmailInput.view2 { style = dds, placeholder = appendDots texts.bccRecipients }
|
||||||
|
model.bccRecipients
|
||||||
|
model.bccRecipientsModel
|
||||||
|
)
|
||||||
]
|
]
|
||||||
, div [ class "mb-4" ]
|
, div [ class "mb-4" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "Subject"
|
[ text texts.subject
|
||||||
, B.inputRequired
|
, B.inputRequired
|
||||||
]
|
]
|
||||||
, input
|
, input
|
||||||
@ -285,7 +301,7 @@ view2 settings model =
|
|||||||
]
|
]
|
||||||
, div [ class "mb-4" ]
|
, div [ class "mb-4" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "Body"
|
[ text texts.body
|
||||||
, B.inputRequired
|
, B.inputRequired
|
||||||
]
|
]
|
||||||
, textarea
|
, textarea
|
||||||
@ -298,7 +314,7 @@ view2 settings model =
|
|||||||
, MB.viewItem <|
|
, MB.viewItem <|
|
||||||
MB.Checkbox
|
MB.Checkbox
|
||||||
{ tagger = \_ -> ToggleAttachAll
|
{ tagger = \_ -> ToggleAttachAll
|
||||||
, label = "Include all item attachments"
|
, label = texts.includeAllAttachments
|
||||||
, value = model.attachAll
|
, value = model.attachAll
|
||||||
, id = "item-send-mail-attach-all"
|
, id = "item-send-mail-attach-all"
|
||||||
}
|
}
|
||||||
@ -311,7 +327,7 @@ view2 settings model =
|
|||||||
, disabled = not (isValid model)
|
, disabled = not (isValid model)
|
||||||
}
|
}
|
||||||
, B.secondaryButton
|
, B.secondaryButton
|
||||||
{ label = "Cancel"
|
{ label = texts.basics.cancel
|
||||||
, icon = "fa fa-times"
|
, icon = "fa fa-times"
|
||||||
, handler = onClick Cancel
|
, handler = onClick Cancel
|
||||||
, attrs = [ href "#" ]
|
, attrs = [ href "#" ]
|
||||||
@ -319,3 +335,8 @@ view2 settings model =
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
appendDots : String -> String
|
||||||
|
appendDots name =
|
||||||
|
name ++ "…"
|
||||||
|
@ -68,48 +68,48 @@ viewContent2 txt model =
|
|||||||
splitDisplay2 txt
|
splitDisplay2 txt
|
||||||
|
|
||||||
|
|
||||||
viewEditLink2 : (Bool -> Attribute Msg) -> Model -> Html Msg
|
viewEditLink2 : String -> (Bool -> Attribute Msg) -> Model -> Html Msg
|
||||||
viewEditLink2 classes model =
|
viewEditLink2 label classes model =
|
||||||
a
|
a
|
||||||
[ onClick (SetDisplay Edit)
|
[ onClick (SetDisplay Edit)
|
||||||
, classes (model.display == Edit)
|
, classes (model.display == Edit)
|
||||||
, href "#"
|
, href "#"
|
||||||
]
|
]
|
||||||
[ text "Edit"
|
[ text label
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewPreviewLink2 : (Bool -> Attribute Msg) -> Model -> Html Msg
|
viewPreviewLink2 : String -> (Bool -> Attribute Msg) -> Model -> Html Msg
|
||||||
viewPreviewLink2 classes model =
|
viewPreviewLink2 label classes model =
|
||||||
a
|
a
|
||||||
[ onClick (SetDisplay Preview)
|
[ onClick (SetDisplay Preview)
|
||||||
, classes (model.display == Preview)
|
, classes (model.display == Preview)
|
||||||
, href "#"
|
, href "#"
|
||||||
]
|
]
|
||||||
[ text "Preview"
|
[ text label
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewSplitLink2 : (Bool -> Attribute Msg) -> Model -> Html Msg
|
viewSplitLink2 : String -> (Bool -> Attribute Msg) -> Model -> Html Msg
|
||||||
viewSplitLink2 classes model =
|
viewSplitLink2 label classes model =
|
||||||
a
|
a
|
||||||
[ onClick (SetDisplay Split)
|
[ onClick (SetDisplay Split)
|
||||||
, classes (model.display == Split)
|
, classes (model.display == Split)
|
||||||
, href "#"
|
, href "#"
|
||||||
]
|
]
|
||||||
[ text "Split"
|
[ text label
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewCheatLink2 : String -> Model -> Html msg
|
viewCheatLink2 : String -> String -> Model -> Html msg
|
||||||
viewCheatLink2 classes model =
|
viewCheatLink2 label classes model =
|
||||||
a
|
a
|
||||||
[ class classes
|
[ class classes
|
||||||
, target "_new"
|
, target "_new"
|
||||||
, href model.cheatSheetUrl
|
, href model.cheatSheetUrl
|
||||||
]
|
]
|
||||||
[ i [ class "fa fa-question mr-2" ] []
|
[ i [ class "fa fa-question mr-2" ] []
|
||||||
, text "Supports Markdown"
|
, text label
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,6 +30,8 @@ import Html exposing (..)
|
|||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onInput)
|
import Html.Events exposing (onInput)
|
||||||
import Http
|
import Http
|
||||||
|
import Markdown
|
||||||
|
import Messages.Comp.NotificationForm exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.Http
|
import Util.Http
|
||||||
import Util.Maybe
|
import Util.Maybe
|
||||||
@ -144,17 +146,13 @@ init flags =
|
|||||||
Comp.CalEventInput.initDefault
|
Comp.CalEventInput.initDefault
|
||||||
in
|
in
|
||||||
( { settings = Api.Model.NotificationSettings.empty
|
( { settings = Api.Model.NotificationSettings.empty
|
||||||
, connectionModel =
|
, connectionModel = Comp.Dropdown.makeSingle
|
||||||
Comp.Dropdown.makeSingle
|
, tagInclModel = Util.Tag.makeDropdownModel
|
||||||
{ makeOption = \a -> { value = a, text = a, additional = "" }
|
, tagExclModel = Util.Tag.makeDropdownModel
|
||||||
, placeholder = "Select connection..."
|
|
||||||
}
|
|
||||||
, tagInclModel = Util.Tag.makeDropdownModel2
|
|
||||||
, tagExclModel = Util.Tag.makeDropdownModel2
|
|
||||||
, recipients = []
|
, recipients = []
|
||||||
, recipientsModel = Comp.EmailInput.init
|
, recipientsModel = Comp.EmailInput.init
|
||||||
, remindDays = Just 1
|
, remindDays = Just 1
|
||||||
, remindDaysModel = Comp.IntField.init (Just 1) Nothing True "Remind Days"
|
, remindDaysModel = Comp.IntField.init (Just 1) Nothing True
|
||||||
, enabled = False
|
, enabled = False
|
||||||
, capOverdue = False
|
, capOverdue = False
|
||||||
, schedule = initialSchedule
|
, schedule = initialSchedule
|
||||||
@ -298,9 +296,7 @@ update flags msg model =
|
|||||||
|
|
||||||
cm =
|
cm =
|
||||||
Comp.Dropdown.makeSingleList
|
Comp.Dropdown.makeSingleList
|
||||||
{ makeOption = \a -> { value = a, text = a, additional = "" }
|
{ options = names
|
||||||
, placeholder = "Select Connection..."
|
|
||||||
, options = names
|
|
||||||
, selected = List.head names
|
, selected = List.head names
|
||||||
}
|
}
|
||||||
in
|
in
|
||||||
@ -480,19 +476,28 @@ isFormSuccess model =
|
|||||||
|> Maybe.withDefault False
|
|> Maybe.withDefault False
|
||||||
|
|
||||||
|
|
||||||
view2 : String -> UiSettings -> Model -> Html Msg
|
view2 : Texts -> String -> UiSettings -> Model -> Html Msg
|
||||||
view2 extraClasses settings model =
|
view2 texts extraClasses settings model =
|
||||||
let
|
let
|
||||||
dimmerSettings =
|
dimmerSettings =
|
||||||
Comp.YesNoDimmer.defaultSettings2 "Really delete this notification task?"
|
Comp.YesNoDimmer.defaultSettings texts.reallyDeleteTask
|
||||||
|
texts.basics.yes
|
||||||
|
texts.basics.no
|
||||||
|
|
||||||
startOnceBtn =
|
startOnceBtn =
|
||||||
MB.SecondaryButton
|
MB.SecondaryButton
|
||||||
{ tagger = StartOnce
|
{ tagger = StartOnce
|
||||||
, label = "Start Once"
|
, label = texts.startOnce
|
||||||
, title = "Start this task now"
|
, title = texts.startTaskNow
|
||||||
, icon = Just "fa fa-play"
|
, icon = Just "fa fa-play"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connectionCfg =
|
||||||
|
{ makeOption = \a -> { text = a, additional = "" }
|
||||||
|
, placeholder = texts.selectConnection
|
||||||
|
, labelColor = \_ -> \_ -> ""
|
||||||
|
, style = DS.mainStyle
|
||||||
|
}
|
||||||
in
|
in
|
||||||
div
|
div
|
||||||
[ class "flex flex-col md:relative"
|
[ class "flex flex-col md:relative"
|
||||||
@ -503,19 +508,22 @@ view2 extraClasses settings model =
|
|||||||
dimmerSettings
|
dimmerSettings
|
||||||
model.yesNoDelete
|
model.yesNoDelete
|
||||||
)
|
)
|
||||||
, B.loadingDimmer (model.loading > 0)
|
, B.loadingDimmer
|
||||||
|
{ active = model.loading > 0
|
||||||
|
, label = texts.basics.loading
|
||||||
|
}
|
||||||
, MB.view
|
, MB.view
|
||||||
{ start =
|
{ start =
|
||||||
[ MB.PrimaryButton
|
[ MB.PrimaryButton
|
||||||
{ tagger = Submit
|
{ tagger = Submit
|
||||||
, label = "Submit"
|
, label = texts.basics.submit
|
||||||
, title = "Save"
|
, title = texts.basics.submitThisForm
|
||||||
, icon = Just "fa fa-save"
|
, icon = Just "fa fa-save"
|
||||||
}
|
}
|
||||||
, MB.SecondaryButton
|
, MB.SecondaryButton
|
||||||
{ tagger = Cancel
|
{ tagger = Cancel
|
||||||
, label = "Cancel"
|
, label = texts.basics.cancel
|
||||||
, title = "Back to list"
|
, title = texts.basics.backToList
|
||||||
, icon = Just "fa fa-arrow-left"
|
, icon = Just "fa fa-arrow-left"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -524,8 +532,8 @@ view2 extraClasses settings model =
|
|||||||
[ startOnceBtn
|
[ startOnceBtn
|
||||||
, MB.DeleteButton
|
, MB.DeleteButton
|
||||||
{ tagger = RequestDelete
|
{ tagger = RequestDelete
|
||||||
, label = "Delete"
|
, label = texts.basics.delete
|
||||||
, title = "Delete this task"
|
, title = texts.deleteThisTask
|
||||||
, icon = Just "fa fa-trash"
|
, icon = Just "fa fa-trash"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -551,14 +559,14 @@ view2 extraClasses settings model =
|
|||||||
[ MB.viewItem <|
|
[ MB.viewItem <|
|
||||||
MB.Checkbox
|
MB.Checkbox
|
||||||
{ tagger = \_ -> ToggleEnabled
|
{ tagger = \_ -> ToggleEnabled
|
||||||
, label = "Enable or disable this task."
|
, label = texts.enableDisable
|
||||||
, value = model.enabled
|
, value = model.enabled
|
||||||
, id = "notify-enabled"
|
, id = "notify-enabled"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
, div [ class "mb-4" ]
|
, div [ class "mb-4" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "Summary"
|
[ text texts.summary
|
||||||
]
|
]
|
||||||
, input
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
@ -569,72 +577,74 @@ view2 extraClasses settings model =
|
|||||||
]
|
]
|
||||||
[]
|
[]
|
||||||
, span [ class "opacity-50 text-sm" ]
|
, span [ class "opacity-50 text-sm" ]
|
||||||
[ text "Some human readable name, only for displaying"
|
[ text texts.summaryInfo
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div [ class "mb-4" ]
|
, div [ class "mb-4" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "Send via"
|
[ text texts.sendVia
|
||||||
, B.inputRequired
|
, B.inputRequired
|
||||||
]
|
]
|
||||||
, Html.map ConnMsg
|
, Html.map ConnMsg
|
||||||
(Comp.Dropdown.view2
|
(Comp.Dropdown.view2
|
||||||
DS.mainStyle
|
connectionCfg
|
||||||
settings
|
settings
|
||||||
model.connectionModel
|
model.connectionModel
|
||||||
)
|
)
|
||||||
, span [ class "opacity-50 text-sm" ]
|
, span [ class "opacity-50 text-sm" ]
|
||||||
[ text "The SMTP connection to use when sending notification mails."
|
[ text texts.sendViaInfo
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div [ class "mb-4" ]
|
, div [ class "mb-4" ]
|
||||||
[ label
|
[ label
|
||||||
[ class S.inputLabel
|
[ class S.inputLabel
|
||||||
]
|
]
|
||||||
[ text "Recipient(s)"
|
[ text texts.recipients
|
||||||
, B.inputRequired
|
, B.inputRequired
|
||||||
]
|
]
|
||||||
, Html.map RecipientMsg
|
, Html.map RecipientMsg
|
||||||
(Comp.EmailInput.view2
|
(Comp.EmailInput.view2
|
||||||
DS.mainStyle
|
{ style = DS.mainStyle, placeholder = texts.recipients }
|
||||||
model.recipients
|
model.recipients
|
||||||
model.recipientsModel
|
model.recipientsModel
|
||||||
)
|
)
|
||||||
, span [ class "opacity-50 text-sm" ]
|
, span [ class "opacity-50 text-sm" ]
|
||||||
[ text "One or more mail addresses, confirm each by pressing 'Return'."
|
[ text texts.recipientsInfo
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div [ class "mb-4" ]
|
, div [ class "mb-4" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "Tags Include (and)" ]
|
[ text texts.tagsInclude ]
|
||||||
, Html.map TagIncMsg
|
, Html.map TagIncMsg
|
||||||
(Comp.Dropdown.view2
|
(Comp.Dropdown.view2
|
||||||
DS.mainStyle
|
(Util.Tag.tagSettings texts.basics.chooseTag DS.mainStyle)
|
||||||
settings
|
settings
|
||||||
model.tagInclModel
|
model.tagInclModel
|
||||||
)
|
)
|
||||||
, span [ class "opacity-50 text-sm" ]
|
, span [ class "opacity-50 text-sm" ]
|
||||||
[ text "Items must have all the tags specified here."
|
[ text texts.tagsIncludeInfo
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div [ class "mb-4" ]
|
, div [ class "mb-4" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "Tags Exclude (or)" ]
|
[ text texts.tagsExclude ]
|
||||||
, Html.map TagExcMsg
|
, Html.map TagExcMsg
|
||||||
(Comp.Dropdown.view2
|
(Comp.Dropdown.view2
|
||||||
DS.mainStyle
|
(Util.Tag.tagSettings texts.basics.chooseTag DS.mainStyle)
|
||||||
settings
|
settings
|
||||||
model.tagExclModel
|
model.tagExclModel
|
||||||
)
|
)
|
||||||
, span [ class "small-info" ]
|
, span [ class "small-info" ]
|
||||||
[ text "Items must not have any tag specified here."
|
[ text texts.tagsExcludeInfo
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, Html.map RemindDaysMsg
|
, Html.map RemindDaysMsg
|
||||||
(Comp.IntField.viewWithInfo2
|
(Comp.IntField.view
|
||||||
"Select items with a due date *lower than* `today+remindDays`"
|
{ label = texts.remindDaysLabel
|
||||||
model.remindDays
|
, info = texts.remindDaysInfo
|
||||||
"mb-4"
|
, number = model.remindDays
|
||||||
|
, classes = "mb-4"
|
||||||
|
}
|
||||||
model.remindDaysModel
|
model.remindDaysModel
|
||||||
)
|
)
|
||||||
, div [ class "mb-4" ]
|
, div [ class "mb-4" ]
|
||||||
@ -643,20 +653,15 @@ view2 extraClasses settings model =
|
|||||||
{ tagger = \_ -> ToggleCapOverdue
|
{ tagger = \_ -> ToggleCapOverdue
|
||||||
, id = "notify-toggle-cap-overdue"
|
, id = "notify-toggle-cap-overdue"
|
||||||
, value = model.capOverdue
|
, value = model.capOverdue
|
||||||
, label = "Cap overdue items"
|
, label = texts.capOverdue
|
||||||
}
|
}
|
||||||
, div [ class "opacity-50 text-sm" ]
|
, div [ class "opacity-50 text-sm" ]
|
||||||
[ text "If checked, only items with a due date"
|
[ Markdown.toHtml [] texts.capOverdueInfo
|
||||||
, em [ class "font-italic" ]
|
|
||||||
[ text " greater than " ]
|
|
||||||
, code [ class "font-mono" ]
|
|
||||||
[ text "today-remindDays" ]
|
|
||||||
, text " are considered."
|
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div [ class "mb-4" ]
|
, div [ class "mb-4" ]
|
||||||
[ label [ class S.inputLabel ]
|
[ label [ class S.inputLabel ]
|
||||||
[ text "Schedule"
|
[ text texts.schedule
|
||||||
, a
|
, a
|
||||||
[ class "float-right"
|
[ class "float-right"
|
||||||
, class S.link
|
, class S.link
|
||||||
@ -665,20 +670,19 @@ view2 extraClasses settings model =
|
|||||||
]
|
]
|
||||||
[ i [ class "fa fa-question" ] []
|
[ i [ class "fa fa-question" ] []
|
||||||
, span [ class "pl-2" ]
|
, span [ class "pl-2" ]
|
||||||
[ text "Click here for help"
|
[ text texts.scheduleClickForHelp
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, Html.map CalEventMsg
|
, Html.map CalEventMsg
|
||||||
(Comp.CalEventInput.view2 ""
|
(Comp.CalEventInput.view2
|
||||||
|
texts.calEventInput
|
||||||
|
""
|
||||||
(Data.Validated.value model.schedule)
|
(Data.Validated.value model.schedule)
|
||||||
model.scheduleModel
|
model.scheduleModel
|
||||||
)
|
)
|
||||||
, span [ class "opacity-50 text-sm" ]
|
, span [ class "opacity-50 text-sm" ]
|
||||||
[ text "Specify how often and when this task should run. "
|
[ text texts.scheduleInfo
|
||||||
, text "Use English 3-letter weekdays. Either a single value, "
|
|
||||||
, text "a list (ex. 1,2,3), a range (ex. 1..3) or a '*' (meaning all) "
|
|
||||||
, text "is allowed for each part."
|
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
@ -11,6 +11,7 @@ import Api.Model.NotificationSettings exposing (NotificationSettings)
|
|||||||
import Comp.Basic as B
|
import Comp.Basic as B
|
||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
|
import Messages.Comp.NotificationTable exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.Html
|
import Util.Html
|
||||||
|
|
||||||
@ -44,8 +45,8 @@ update msg model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : Model -> List NotificationSettings -> Html Msg
|
view2 : Texts -> Model -> List NotificationSettings -> Html Msg
|
||||||
view2 _ items =
|
view2 texts _ items =
|
||||||
div []
|
div []
|
||||||
[ table [ class S.tableMain ]
|
[ table [ class S.tableMain ]
|
||||||
[ thead []
|
[ thead []
|
||||||
@ -54,13 +55,13 @@ view2 _ items =
|
|||||||
, th [ class "text-center mr-2" ]
|
, th [ class "text-center mr-2" ]
|
||||||
[ i [ class "fa fa-check" ] []
|
[ i [ class "fa fa-check" ] []
|
||||||
]
|
]
|
||||||
, th [ class "text-left " ] [ text "Summary" ]
|
, th [ class "text-left " ] [ text texts.summary ]
|
||||||
, th [ class "text-left hidden sm:table-cell mr-2" ]
|
, th [ class "text-left hidden sm:table-cell mr-2" ]
|
||||||
[ text "Schedule" ]
|
[ text texts.schedule ]
|
||||||
, th [ class "text-left mr-2" ]
|
, th [ class "text-left mr-2" ]
|
||||||
[ text "Connection" ]
|
[ text texts.connection ]
|
||||||
, th [ class "text-left hidden sm:table-cell mr-2" ]
|
, th [ class "text-left hidden sm:table-cell mr-2" ]
|
||||||
[ text "Recipients" ]
|
[ text texts.recipients ]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, tbody []
|
, tbody []
|
||||||
|
@ -18,6 +18,7 @@ import Data.UiSettings exposing (UiSettings)
|
|||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Http
|
import Http
|
||||||
|
import Messages.Comp.NotificationManage exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.Http
|
import Util.Http
|
||||||
|
|
||||||
@ -212,8 +213,8 @@ update flags msg model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : UiSettings -> Model -> Html Msg
|
view2 : Texts -> UiSettings -> Model -> Html Msg
|
||||||
view2 settings model =
|
view2 texts settings model =
|
||||||
div [ class "flex flex-col" ]
|
div [ class "flex flex-col" ]
|
||||||
(div
|
(div
|
||||||
[ classList
|
[ classList
|
||||||
@ -229,34 +230,38 @@ view2 settings model =
|
|||||||
]
|
]
|
||||||
:: (case model.detailModel of
|
:: (case model.detailModel of
|
||||||
Just msett ->
|
Just msett ->
|
||||||
viewForm2 settings msett
|
viewForm2 texts settings msett
|
||||||
|
|
||||||
Nothing ->
|
Nothing ->
|
||||||
viewList2 model
|
viewList2 texts model
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
viewForm2 : UiSettings -> Comp.NotificationForm.Model -> List (Html Msg)
|
viewForm2 : Texts -> UiSettings -> Comp.NotificationForm.Model -> List (Html Msg)
|
||||||
viewForm2 settings model =
|
viewForm2 texts settings model =
|
||||||
[ Html.map DetailMsg
|
[ Html.map DetailMsg
|
||||||
(Comp.NotificationForm.view2 "flex flex-col" settings model)
|
(Comp.NotificationForm.view2 texts.notificationForm "flex flex-col" settings model)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewList2 : Model -> List (Html Msg)
|
viewList2 : Texts -> Model -> List (Html Msg)
|
||||||
viewList2 model =
|
viewList2 texts model =
|
||||||
[ MB.view
|
[ MB.view
|
||||||
{ start =
|
{ start =
|
||||||
[ MB.PrimaryButton
|
[ MB.PrimaryButton
|
||||||
{ tagger = NewTask
|
{ tagger = NewTask
|
||||||
, label = "New Task"
|
, label = texts.newTask
|
||||||
, icon = Just "fa fa-plus"
|
, icon = Just "fa fa-plus"
|
||||||
, title = "Create a new notification task"
|
, title = texts.createNewTask
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
, end = []
|
, end = []
|
||||||
, rootClasses = "mb-4"
|
, rootClasses = "mb-4"
|
||||||
}
|
}
|
||||||
, Html.map ListMsg (Comp.NotificationList.view2 model.listModel model.items)
|
, Html.map ListMsg
|
||||||
|
(Comp.NotificationList.view2 texts.notificationTable
|
||||||
|
model.listModel
|
||||||
|
model.items
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
@ -13,12 +13,14 @@ import Comp.AddressForm
|
|||||||
import Comp.Basic as B
|
import Comp.Basic as B
|
||||||
import Comp.ContactField
|
import Comp.ContactField
|
||||||
import Comp.FixedDropdown
|
import Comp.FixedDropdown
|
||||||
|
import Data.DropdownStyle as DS
|
||||||
import Data.Flags exposing (Flags)
|
import Data.Flags exposing (Flags)
|
||||||
import Data.OrgUse exposing (OrgUse)
|
import Data.OrgUse exposing (OrgUse)
|
||||||
import Data.UiSettings exposing (UiSettings)
|
import Data.UiSettings exposing (UiSettings)
|
||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onInput)
|
import Html.Events exposing (onInput)
|
||||||
|
import Messages.Comp.OrgForm exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.Maybe
|
import Util.Maybe
|
||||||
|
|
||||||
@ -45,9 +47,7 @@ emptyModel =
|
|||||||
, shortName = Nothing
|
, shortName = Nothing
|
||||||
, use = Data.OrgUse.Correspondent
|
, use = Data.OrgUse.Correspondent
|
||||||
, useModel =
|
, useModel =
|
||||||
Comp.FixedDropdown.initMap
|
Comp.FixedDropdown.init Data.OrgUse.all
|
||||||
Data.OrgUse.label
|
|
||||||
Data.OrgUse.all
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -147,14 +147,20 @@ update flags msg model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
makeUseItem : Model -> Maybe (Comp.FixedDropdown.Item OrgUse)
|
view2 : Texts -> Bool -> UiSettings -> Model -> Html Msg
|
||||||
makeUseItem model =
|
view2 texts mobile settings model =
|
||||||
Just <|
|
let
|
||||||
Comp.FixedDropdown.Item model.use (Data.OrgUse.label model.use)
|
orgUseCfg =
|
||||||
|
{ display = texts.orgUseLabel
|
||||||
|
, icon = \_ -> Nothing
|
||||||
|
, style = DS.mainStyle
|
||||||
|
}
|
||||||
|
|
||||||
|
contactTypeCfg =
|
||||||
view2 : Bool -> UiSettings -> Model -> Html Msg
|
{ mobile = mobile
|
||||||
view2 mobile settings model =
|
, contactTypeLabel = texts.contactTypeLabel
|
||||||
|
}
|
||||||
|
in
|
||||||
div [ class "flex flex-col" ]
|
div [ class "flex flex-col" ]
|
||||||
[ div
|
[ div
|
||||||
[ class "mb-4" ]
|
[ class "mb-4" ]
|
||||||
@ -162,13 +168,13 @@ view2 mobile settings model =
|
|||||||
[ for "orgname"
|
[ for "orgname"
|
||||||
, class S.inputLabel
|
, class S.inputLabel
|
||||||
]
|
]
|
||||||
[ text "Name"
|
[ text texts.basics.name
|
||||||
, B.inputRequired
|
, B.inputRequired
|
||||||
]
|
]
|
||||||
, input
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
, onInput SetName
|
, onInput SetName
|
||||||
, placeholder "Name"
|
, placeholder texts.basics.name
|
||||||
, value model.name
|
, value model.name
|
||||||
, name "orgname"
|
, name "orgname"
|
||||||
, class S.textInput
|
, class S.textInput
|
||||||
@ -184,12 +190,12 @@ view2 mobile settings model =
|
|||||||
[ for "org-short-name"
|
[ for "org-short-name"
|
||||||
, class S.inputLabel
|
, class S.inputLabel
|
||||||
]
|
]
|
||||||
[ text "Short Name"
|
[ text texts.shortName
|
||||||
]
|
]
|
||||||
, input
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
, onInput SetShortName
|
, onInput SetShortName
|
||||||
, placeholder "Abbreviation"
|
, placeholder texts.shortName
|
||||||
, Maybe.withDefault "" model.shortName
|
, Maybe.withDefault "" model.shortName
|
||||||
|> value
|
|> value
|
||||||
, name "org-short-name"
|
, name "org-short-name"
|
||||||
@ -201,35 +207,40 @@ view2 mobile settings model =
|
|||||||
[ label
|
[ label
|
||||||
[ class S.inputLabel
|
[ class S.inputLabel
|
||||||
]
|
]
|
||||||
[ text "Use" ]
|
[ text texts.use
|
||||||
|
]
|
||||||
, Html.map UseDropdownMsg
|
, Html.map UseDropdownMsg
|
||||||
(Comp.FixedDropdown.view2 (makeUseItem model) model.useModel)
|
(Comp.FixedDropdown.viewStyled2 orgUseCfg
|
||||||
|
False
|
||||||
|
(Just model.use)
|
||||||
|
model.useModel
|
||||||
|
)
|
||||||
, span [ class "opacity-50 text-sm" ]
|
, span [ class "opacity-50 text-sm" ]
|
||||||
[ case model.use of
|
[ case model.use of
|
||||||
Data.OrgUse.Correspondent ->
|
Data.OrgUse.Correspondent ->
|
||||||
text "Use as correspondent"
|
text texts.useAsCorrespondent
|
||||||
|
|
||||||
Data.OrgUse.Disabled ->
|
Data.OrgUse.Disabled ->
|
||||||
text "Do not use for suggestions."
|
text texts.dontUseForSuggestions
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div [ class "mb-4" ]
|
, div [ class "mb-4" ]
|
||||||
[ h3 [ class S.header3 ]
|
[ h3 [ class S.header3 ]
|
||||||
[ text "Address"
|
[ text texts.address
|
||||||
]
|
]
|
||||||
, Html.map AddressMsg
|
, Html.map AddressMsg
|
||||||
(Comp.AddressForm.view2 settings model.addressModel)
|
(Comp.AddressForm.view2 texts.addressForm settings model.addressModel)
|
||||||
]
|
]
|
||||||
, div [ class "mb-4" ]
|
, div [ class "mb-4" ]
|
||||||
[ h3 [ class S.header3 ]
|
[ h3 [ class S.header3 ]
|
||||||
[ text "Contacts"
|
[ text texts.contacts
|
||||||
]
|
]
|
||||||
, Html.map ContactMsg
|
, Html.map ContactMsg
|
||||||
(Comp.ContactField.view2 mobile settings model.contactModel)
|
(Comp.ContactField.view2 contactTypeCfg settings model.contactModel)
|
||||||
]
|
]
|
||||||
, div [ class "mb-4" ]
|
, div [ class "mb-4" ]
|
||||||
[ h3 [ class S.header3 ]
|
[ h3 [ class S.header3 ]
|
||||||
[ text "Notes"
|
[ text texts.notes
|
||||||
]
|
]
|
||||||
, div [ class "" ]
|
, div [ class "" ]
|
||||||
[ textarea
|
[ textarea
|
||||||
|
@ -21,6 +21,7 @@ import Html exposing (..)
|
|||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onSubmit)
|
import Html.Events exposing (onSubmit)
|
||||||
import Http
|
import Http
|
||||||
|
import Messages.Comp.OrgManage exposing (Texts)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.Http
|
import Util.Http
|
||||||
import Util.Maybe
|
import Util.Maybe
|
||||||
@ -205,50 +206,55 @@ update flags msg model =
|
|||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : UiSettings -> Model -> Html Msg
|
view2 : Texts -> UiSettings -> Model -> Html Msg
|
||||||
view2 settings model =
|
view2 texts settings model =
|
||||||
if model.viewMode == Table then
|
if model.viewMode == Table then
|
||||||
viewTable2 model
|
viewTable2 texts model
|
||||||
|
|
||||||
else
|
else
|
||||||
viewForm2 settings model
|
viewForm2 texts settings model
|
||||||
|
|
||||||
|
|
||||||
viewTable2 : Model -> Html Msg
|
viewTable2 : Texts -> Model -> Html Msg
|
||||||
viewTable2 model =
|
viewTable2 texts model =
|
||||||
div [ class "flex flex-col relative" ]
|
div [ class "flex flex-col relative" ]
|
||||||
[ MB.view
|
[ MB.view
|
||||||
{ start =
|
{ start =
|
||||||
[ MB.TextInput
|
[ MB.TextInput
|
||||||
{ tagger = SetQuery
|
{ tagger = SetQuery
|
||||||
, value = model.query
|
, value = model.query
|
||||||
, placeholder = "Search…"
|
, placeholder = texts.basics.searchPlaceholder
|
||||||
, icon = Just "fa fa-search"
|
, icon = Just "fa fa-search"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
, end =
|
, end =
|
||||||
[ MB.PrimaryButton
|
[ MB.PrimaryButton
|
||||||
{ tagger = InitNewOrg
|
{ tagger = InitNewOrg
|
||||||
, title = "Create a new organization"
|
, title = texts.createNewOrganization
|
||||||
, icon = Just "fa fa-plus"
|
, icon = Just "fa fa-plus"
|
||||||
, label = "New Organization"
|
, label = texts.newOrganization
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
, rootClasses = "mb-4"
|
, rootClasses = "mb-4"
|
||||||
}
|
}
|
||||||
, Html.map TableMsg (Comp.OrgTable.view2 model.tableModel)
|
, Html.map TableMsg (Comp.OrgTable.view2 texts.orgTable model.tableModel)
|
||||||
, B.loadingDimmer model.loading
|
, B.loadingDimmer
|
||||||
|
{ active = model.loading
|
||||||
|
, label = texts.basics.loading
|
||||||
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewForm2 : UiSettings -> Model -> Html Msg
|
viewForm2 : Texts -> UiSettings -> Model -> Html Msg
|
||||||
viewForm2 settings model =
|
viewForm2 texts settings model =
|
||||||
let
|
let
|
||||||
newOrg =
|
newOrg =
|
||||||
model.formModel.org.id == ""
|
model.formModel.org.id == ""
|
||||||
|
|
||||||
dimmerSettings2 =
|
dimmerSettings2 =
|
||||||
Comp.YesNoDimmer.defaultSettings2 "Really delete this organization?"
|
Comp.YesNoDimmer.defaultSettings texts.reallyDeleteOrg
|
||||||
|
texts.basics.yes
|
||||||
|
texts.basics.no
|
||||||
in
|
in
|
||||||
Html.form
|
Html.form
|
||||||
[ class "md:relative flex flex-col"
|
[ class "md:relative flex flex-col"
|
||||||
@ -262,14 +268,14 @@ viewForm2 settings model =
|
|||||||
)
|
)
|
||||||
, if newOrg then
|
, if newOrg then
|
||||||
h3 [ class S.header2 ]
|
h3 [ class S.header2 ]
|
||||||
[ text "Create new organization"
|
[ text texts.createNewOrganization
|
||||||
]
|
]
|
||||||
|
|
||||||
else
|
else
|
||||||
h3 [ class S.header2 ]
|
h3 [ class S.header2 ]
|
||||||
[ text model.formModel.org.name
|
[ text model.formModel.org.name
|
||||||
, div [ class "opacity-50 text-sm" ]
|
, div [ class "opacity-50 text-sm" ]
|
||||||
[ text "Id: "
|
[ text (texts.basics.id ++ ": ")
|
||||||
, text model.formModel.org.id
|
, text model.formModel.org.id
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -277,24 +283,24 @@ viewForm2 settings model =
|
|||||||
{ start =
|
{ start =
|
||||||
[ MB.PrimaryButton
|
[ MB.PrimaryButton
|
||||||
{ tagger = Submit
|
{ tagger = Submit
|
||||||
, title = "Submit this form"
|
, title = texts.basics.submitThisForm
|
||||||
, icon = Just "fa fa-save"
|
, icon = Just "fa fa-save"
|
||||||
, label = "Submit"
|
, label = texts.basics.submit
|
||||||
}
|
}
|
||||||
, MB.SecondaryButton
|
, MB.SecondaryButton
|
||||||
{ tagger = SetViewMode Table
|
{ tagger = SetViewMode Table
|
||||||
, title = "Back to list"
|
, title = texts.basics.backToList
|
||||||
, icon = Just "fa fa-arrow-left"
|
, icon = Just "fa fa-arrow-left"
|
||||||
, label = "Cancel"
|
, label = texts.basics.cancel
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
, end =
|
, end =
|
||||||
if not newOrg then
|
if not newOrg then
|
||||||
[ MB.DeleteButton
|
[ MB.DeleteButton
|
||||||
{ tagger = RequestDelete
|
{ tagger = RequestDelete
|
||||||
, title = "Delete this organization"
|
, title = texts.deleteThisOrg
|
||||||
, icon = Just "fa fa-trash"
|
, icon = Just "fa fa-trash"
|
||||||
, label = "Delete"
|
, label = texts.basics.delete
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -311,6 +317,15 @@ viewForm2 settings model =
|
|||||||
]
|
]
|
||||||
[ Maybe.withDefault "" model.formError |> text
|
[ Maybe.withDefault "" model.formError |> text
|
||||||
]
|
]
|
||||||
, Html.map FormMsg (Comp.OrgForm.view2 False settings model.formModel)
|
, Html.map FormMsg
|
||||||
, B.loadingDimmer model.loading
|
(Comp.OrgForm.view2
|
||||||
|
texts.orgForm
|
||||||
|
False
|
||||||
|
settings
|
||||||
|
model.formModel
|
||||||
|
)
|
||||||
|
, B.loadingDimmer
|
||||||
|
{ active = model.loading
|
||||||
|
, label = texts.basics.loading
|
||||||
|
}
|
||||||
]
|
]
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user