Externalized strings

This commit is contained in:
Eike Kettner 2021-03-28 18:23:43 +02:00
parent 2b81c72d96
commit ec237a2eaa
25 changed files with 709 additions and 271 deletions

View File

@ -7,7 +7,7 @@ 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 import Messages exposing (Messages)
import Messages.App exposing (Texts) import Messages.App exposing (Texts)
import Page exposing (Page(..)) import Page exposing (Page(..))
import Page.CollectiveSettings.View2 as CollectiveSettings import Page.CollectiveSettings.View2 as CollectiveSettings
@ -121,10 +121,10 @@ mainContent model =
viewHome model viewHome model
CollectiveSettingPage -> CollectiveSettingPage ->
viewCollectiveSettings model viewCollectiveSettings texts model
LoginPage _ -> LoginPage _ ->
viewLogin model viewLogin texts model
ManageDataPage -> ManageDataPage ->
viewManageData model viewManageData model
@ -404,28 +404,30 @@ viewHome model =
] ]
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)
] ]

View File

@ -1,6 +1,7 @@
module Comp.Basic exposing module Comp.Basic exposing
( editLinkLabel ( editLinkLabel
, editLinkTableCell , editLinkTableCell
, editLinkTableCell2
, genericButton , genericButton
, horizontalDivider , horizontalDivider
, inputRequired , inputRequired
@ -17,6 +18,7 @@ module Comp.Basic exposing
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
@ -192,9 +194,14 @@ loadingDimmer active =
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 +211,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
] ]

View File

@ -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.ClassifierSettingsFormComp exposing (Texts)
import Styles as S import Styles as S
import Util.Tag import Util.Tag
@ -59,7 +60,7 @@ 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
@ -183,8 +184,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 =
let let
catListTypeItem = catListTypeItem =
Comp.FixedDropdown.Item Comp.FixedDropdown.Item
@ -194,20 +195,10 @@ view2 settings model =
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.view2 (Just catListTypeItem) model.categoryListTypeModel)
] ]
@ -215,10 +206,10 @@ Use an empty whitelist to disable auto tagging.
[ 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
@ -228,16 +219,22 @@ Use an empty whitelist to disable auto tagging.
) )
] ]
, 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
""
(Data.Validated.value model.schedule)
model.scheduleModel
)
] ]
] ]

View File

@ -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.CollectiveSettingsFormComp exposing (Texts)
import Styles as S import Styles as S
import Util.Http import Util.Http
@ -200,8 +201,8 @@ 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 =
div div
[ classList [ classList
[ ( "ui form error success", True ) [ ( "ui form error success", True )
@ -215,10 +216,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,11 +229,11 @@ 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
@ -241,7 +242,7 @@ view2 flags settings model =
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 +253,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 +269,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 +284,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 +304,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 +321,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 "#" ]
} }

View File

@ -1,8 +1,10 @@
module Comp.IntField exposing module Comp.IntField exposing
( Model ( Model
, Msg , Msg
, ViewSettings
, init , init
, update , update
, view
, viewWithInfo2 , viewWithInfo2
) )
@ -98,20 +100,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 +130,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 +145,16 @@ viewWithInfo2 info nval classes model =
[ Maybe.withDefault "" model.error |> text [ Maybe.withDefault "" model.error |> text
] ]
] ]
viewWithInfo2 : String -> Maybe Int -> String -> Model -> Html Msg
viewWithInfo2 info nval classes model =
let
cfg =
{ label = model.label
, info = info
, number = nval
, classes = classes
}
in
view cfg model

View File

@ -28,6 +28,7 @@ import Html.Attributes exposing (..)
import Html.Events exposing (onCheck, onInput) import Html.Events exposing (onCheck, onInput)
import Http import Http
import Markdown import Markdown
import Messages.SourceFormComp exposing (Texts)
import Styles as S import Styles as S
import Util.Folder exposing (mkFolderOption) import Util.Folder exposing (mkFolderOption)
import Util.Maybe import Util.Maybe
@ -329,8 +330,8 @@ update flags msg model =
--- View2 --- View2
view2 : Flags -> UiSettings -> Model -> Html Msg view2 : Flags -> Texts -> UiSettings -> Model -> Html Msg
view2 _ settings model = view2 _ texts settings model =
let let
priorityItem = priorityItem =
Comp.FixedDropdown.Item Comp.FixedDropdown.Item
@ -344,14 +345,14 @@ view2 _ settings model =
[ for "source-abbrev" [ for "source-abbrev"
, class S.inputLabel , class S.inputLabel
] ]
[ text "Name" [ text texts.name
, B.inputRequired , B.inputRequired
] ]
, input , input
[ type_ "text" [ type_ "text"
, id "source-abbrev" , id "source-abbrev"
, onInput SetAbbrev , onInput SetAbbrev
, placeholder "Name" , placeholder texts.name
, value model.abbrev , value model.abbrev
, class S.textInput , class S.textInput
, classList [ ( S.inputErrorBorder, not (isValid model) ) ] , classList [ ( S.inputErrorBorder, not (isValid model) ) ]
@ -363,7 +364,7 @@ view2 _ settings model =
[ for "source-descr" [ for "source-descr"
, class S.inputLabel , class S.inputLabel
] ]
[ text "Description" [ text texts.description
] ]
, textarea , textarea
[ onInput SetDescr [ onInput SetDescr
@ -388,13 +389,13 @@ view2 _ settings model =
] ]
[] []
, span [ class "ml-2" ] , span [ class "ml-2" ]
[ text "Enabled" [ text texts.enabled
] ]
] ]
] ]
, div [ class "mb-4" ] , div [ class "mb-4" ]
[ label [ class S.inputLabel ] [ label [ class S.inputLabel ]
[ text "Priority" [ text texts.priority
] ]
, Html.map PrioDropdownMsg , Html.map PrioDropdownMsg
(Comp.FixedDropdown.view2 (Comp.FixedDropdown.view2
@ -402,26 +403,24 @@ view2 _ settings model =
model.priorityModel model.priorityModel
) )
, div [ class "opacity-50 text-sm" ] , div [ class "opacity-50 text-sm" ]
[ text "The priority used by the scheduler when processing uploaded files." [ text texts.priorityInfo
] ]
] ]
, div , div
[ class S.header2 [ class S.header2
, class "mt-6" , class "mt-6"
] ]
[ text "Metadata" [ text texts.metadata
] ]
, div , div
[ class S.message [ class S.message
, class "mb-4" , class "mb-4"
] ]
[ text "Metadata specified here is automatically attached to each item uploaded " [ text texts.metadataInfoText
, text "through this source, unless it is overriden in the upload request meta data. "
, text "Tags from the request are added to those defined here."
] ]
, div [ class "mb-4" ] , div [ class "mb-4" ]
[ label [ class S.inputLabel ] [ label [ class S.inputLabel ]
[ text "Folder" [ text texts.folder
] ]
, Html.map FolderDropdownMsg , Html.map FolderDropdownMsg
(Comp.Dropdown.view2 (Comp.Dropdown.view2
@ -430,7 +429,7 @@ view2 _ settings model =
model.folderModel model.folderModel
) )
, div [ class "opacity-50 text-sm" ] , div [ class "opacity-50 text-sm" ]
[ text "Choose a folder to automatically put items into." [ text texts.folderInfo
] ]
, div , div
[ classList [ classList
@ -438,17 +437,13 @@ view2 _ settings model =
] ]
, class S.message , class S.message
] ]
[ Markdown.toHtml [] """ [ Markdown.toHtml [] texts.folderForbiddenText
You are **not a member** of this folder. Items created through this
link will be **hidden** from any search results. Use a folder where
you are a member of to make items visible. This message will
disappear then.
"""
] ]
] ]
, div [ class "mb-4" ] , div [ class "mb-4" ]
[ label [ class S.inputLabel ] [ label [ class S.inputLabel ]
[ text "Tags" ] [ text texts.basics.tags
]
, Html.map TagDropdownMsg , Html.map TagDropdownMsg
(Comp.Dropdown.view2 (Comp.Dropdown.view2
DS.mainStyle DS.mainStyle
@ -456,18 +451,18 @@ disappear then.
model.tagModel model.tagModel
) )
, div [ class "opacity-50 text-sm" ] , div [ class "opacity-50 text-sm" ]
[ text "Choose tags that should be applied to items." [ text texts.tagsInfo
] ]
] ]
, div , div
[ class "mb-4" [ class "mb-4"
] ]
[ label [ class S.inputLabel ] [ label [ class S.inputLabel ]
[ text "File Filter" ] [ text texts.fileFilter ]
, input , input
[ type_ "text" [ type_ "text"
, onInput SetFileFilter , onInput SetFileFilter
, placeholder "File Filter" , placeholder texts.fileFilter
, model.fileFilter , model.fileFilter
|> Maybe.withDefault "" |> Maybe.withDefault ""
|> value |> value
@ -475,20 +470,12 @@ disappear then.
] ]
[] []
, div [ class "opacity-50 text-sm" ] , div [ class "opacity-50 text-sm" ]
[ text "Specify a file glob to filter files when uploading archives " [ Markdown.toHtml [] texts.fileFilterInfo
, text "(e.g. for email and zip). For example, to only extract pdf files: "
, code [ class "font-mono" ]
[ text "*.pdf"
]
, text ". Globs can be combined via OR, like this: "
, code [ class "font-mono" ]
[ text "*.pdf|mail.html"
]
] ]
] ]
, div [ class "mb-4" ] , div [ class "mb-4" ]
[ label [ class S.inputLabel ] [ label [ class S.inputLabel ]
[ text "Language:" [ text (texts.language ++ ":")
] ]
, Html.map LanguageMsg , Html.map LanguageMsg
(Comp.Dropdown.view2 (Comp.Dropdown.view2
@ -496,9 +483,8 @@ disappear then.
settings settings
model.languageModel model.languageModel
) )
, div [ class "text-gray-400 text-xs" ] , div [ class "opacity-50 text-sm" ]
[ text "Used for text extraction and analysis. The collective's " [ text texts.languageInfo
, text "default language is used if not specified here."
] ]
] ]
] ]

View File

@ -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.SourceManageComp exposing (Texts)
import Ports import Ports
import QRCode import QRCode
import Styles as S import Styles as S
@ -211,49 +212,49 @@ update flags msg model =
--- View2 --- View2
qrCodeView : String -> Html msg qrCodeView : Texts -> String -> Html msg
qrCodeView message = qrCodeView texts message =
QRCode.encode message QRCode.encode message
|> Result.map QRCode.toSvg |> Result.map QRCode.toSvg
|> Result.withDefault |> Result.withDefault
(Html.text "Error generating QR-Code") (Html.text texts.errorGeneratingQR)
view2 : Flags -> UiSettings -> Model -> Html Msg view2 : Texts -> Flags -> UiSettings -> Model -> Html Msg
view2 flags settings model = view2 texts flags settings model =
case model.viewMode of case model.viewMode of
None -> None ->
viewTable2 model viewTable2 texts model
Edit _ -> Edit _ ->
div [] (viewForm2 flags settings model) div [] (viewForm2 texts flags settings model)
Display source -> Display source ->
viewLinks2 flags settings source viewLinks2 texts flags settings source
viewTable2 : Model -> Html Msg viewTable2 : Texts -> Model -> Html Msg
viewTable2 model = viewTable2 texts model =
div [ class "relative flex flex-col" ] div [ class "relative flex flex-col" ]
[ MB.view [ MB.view
{ start = [] { start = []
, end = , end =
[ MB.PrimaryButton [ MB.PrimaryButton
{ tagger = InitNewSource { tagger = InitNewSource
, title = "Add a source url" , title = texts.addSourceUrl
, icon = Just "fa fa-plus" , icon = Just "fa fa-plus"
, label = "New source" , label = texts.newSource
} }
] ]
, rootClasses = "mb-4" , rootClasses = "mb-4"
} }
, Html.map TableMsg (Comp.SourceTable.view2 model.sources) , Html.map TableMsg (Comp.SourceTable.view2 texts.sourceTable model.sources)
, B.loadingDimmer model.loading , B.loadingDimmer model.loading
] ]
viewLinks2 : Flags -> UiSettings -> SourceAndTags -> Html Msg viewLinks2 : Texts -> Flags -> UiSettings -> SourceAndTags -> Html Msg
viewLinks2 flags _ source = viewLinks2 texts flags _ source =
let let
appUrl = appUrl =
flags.config.baseUrl ++ "/app/upload/" ++ source.source.id flags.config.baseUrl ++ "/app/upload/" ++ source.source.id
@ -270,7 +271,7 @@ viewLinks2 flags _ source =
div div
[] []
[ h2 [ class S.header2 ] [ h2 [ class S.header2 ]
[ text "Public Uploads: " [ text (texts.publicUploads ++ ": ")
, text source.source.abbrev , text source.source.abbrev
, div [ class "opacity-50 text-sm" ] , div [ class "opacity-50 text-sm" ]
[ text source.source.id [ text source.source.id
@ -279,37 +280,33 @@ viewLinks2 flags _ source =
, MB.view , MB.view
{ start = { start =
[ MB.SecondaryButton [ MB.SecondaryButton
{ label = "Back" { label = texts.basics.back
, icon = Just "fa fa-arrow-left" , icon = Just "fa fa-arrow-left"
, tagger = SetTableView , tagger = SetTableView
, title = "Back to list" , title = texts.basics.backToList
} }
] ]
, end = [] , end = []
, rootClasses = "mb-4" , rootClasses = "mb-4"
} }
, p [ class "text-lg pt-2 opacity-75" ] , p [ class "text-lg pt-2 opacity-75" ]
[ text "This source defines URLs that can be used by anyone to send files to " [ text texts.sourceInfoText
, text "you. There is a web page that you can share or the API url can be used "
, text "with other clients."
] ]
, p [ class "text-lg py-2 opacity-75" ] , p [ class "text-lg py-2 opacity-75" ]
[ text "There have been " [ text (texts.itemsCreatedInfo source.source.counter)
, String.fromInt source.source.counter |> text
, text " items created through this source."
] ]
, h3 , h3
[ class S.header3 [ class S.header3
, class "mt-2" , class "mt-2"
] ]
[ text "Public Upload Page" [ text texts.publicUploadPage
] ]
, div [ class "" ] , div [ class "" ]
[ div [ class "flex flex-row" ] [ div [ class "flex flex-row" ]
[ a [ a
[ class S.secondaryBasicButtonPlain [ class S.secondaryBasicButtonPlain
, class "rounded-l border text-sm px-4 py-2" , class "rounded-l border text-sm px-4 py-2"
, title "Copy to clipboard" , title texts.copyToClipboard
, href "#" , href "#"
, Tuple.second appClipboardData , Tuple.second appClipboardData
|> String.dropLeft 1 |> String.dropLeft 1
@ -323,7 +320,7 @@ viewLinks2 flags _ source =
, class "px-4 py-2 border-0 border-t border-b border-r text-sm" , class "px-4 py-2 border-0 border-t border-b border-r text-sm"
, href appUrl , href appUrl
, target "_blank" , target "_blank"
, title "Open in new tab/window" , title texts.openInNewTab
] ]
[ i [ class "fa fa-external-link-alt" ] [] [ i [ class "fa fa-external-link-alt" ] []
] ]
@ -340,21 +337,21 @@ viewLinks2 flags _ source =
[ class S.border [ class S.border
, class styleQr , class styleQr
] ]
[ qrCodeView appUrl [ qrCodeView texts appUrl
] ]
] ]
, h3 , h3
[ class S.header3 [ class S.header3
, class "mt-4" , class "mt-4"
] ]
[ text "Public API Upload URL" [ text texts.publicUploadUrl
] ]
, div [ class "" ] , div [ class "" ]
[ div [ class "flex flex-row" ] [ div [ class "flex flex-row" ]
[ a [ a
[ class S.secondaryBasicButtonPlain [ class S.secondaryBasicButtonPlain
, class "px-4 py-2 rounded-l border text-sm" , class "px-4 py-2 rounded-l border text-sm"
, title "Copy to clipboard" , title texts.copyToClipboard
, href "#" , href "#"
, Tuple.second apiClipboardData , Tuple.second apiClipboardData
|> String.dropLeft 1 |> String.dropLeft 1
@ -376,24 +373,24 @@ viewLinks2 flags _ source =
[ class S.border [ class S.border
, class styleQr , class styleQr
] ]
[ qrCodeView apiUrl [ qrCodeView texts apiUrl
] ]
] ]
] ]
viewForm2 : Flags -> UiSettings -> Model -> List (Html Msg) viewForm2 : Texts -> Flags -> UiSettings -> Model -> List (Html Msg)
viewForm2 flags settings model = viewForm2 texts flags settings model =
let let
newSource = newSource =
model.formModel.source.source.id == "" model.formModel.source.source.id == ""
dimmerSettings = dimmerSettings =
Comp.YesNoDimmer.defaultSettings2 "Really delete this source?" Comp.YesNoDimmer.defaultSettings2 texts.reallyDeleteSource
in in
[ if newSource then [ if newSource then
h3 [ class S.header2 ] h3 [ class S.header2 ]
[ text "Create new source" [ text texts.createNewSource
] ]
else else
@ -412,24 +409,24 @@ viewForm2 flags 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 = SetTableView { tagger = SetTableView
, 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 newSource then if not newSource then
[ MB.DeleteButton [ MB.DeleteButton
{ tagger = RequestDelete { tagger = RequestDelete
, title = "Delete this settings entry" , title = texts.deleteThisSource
, icon = Just "fa fa-trash" , icon = Just "fa fa-trash"
, label = "Delete" , label = texts.basics.delete
} }
] ]
@ -438,7 +435,7 @@ viewForm2 flags settings model =
, rootClasses = "mb-4" , rootClasses = "mb-4"
} }
, Html.map FormMsg , Html.map FormMsg
(Comp.SourceForm.view2 flags settings model.formModel) (Comp.SourceForm.view2 flags texts.sourceForm settings model.formModel)
, div , div
[ classList [ classList
[ ( S.errorMessage, True ) [ ( S.errorMessage, True )

View File

@ -12,6 +12,7 @@ import Data.Flags exposing (Flags)
import Data.Priority import Data.Priority
import Html exposing (..) import Html exposing (..)
import Html.Attributes exposing (..) import Html.Attributes exposing (..)
import Messages.SourceTableComp exposing (Texts)
import Styles as S import Styles as S
import Util.Html import Util.Html
@ -54,26 +55,26 @@ update _ msg =
--- View2 --- View2
view2 : List SourceAndTags -> Html Msg view2 : Texts -> List SourceAndTags -> Html Msg
view2 sources = view2 texts sources =
table [ class S.tableMain ] table [ class S.tableMain ]
[ thead [] [ thead []
[ tr [] [ tr []
[ th [ class "" ] [] [ th [ class "" ] []
, th [ class "text-left" ] [ text "Abbrev" ] , th [ class "text-left" ] [ text texts.abbrev ]
, th [ class "px-2 text-center" ] [ text "Enabled" ] , th [ class "px-2 text-center" ] [ text texts.enabled ]
, th [ class "hidden md:table-cell" ] [ text "Counter" ] , th [ class "hidden md:table-cell" ] [ text texts.counter ]
, th [ class "hidden md:table-cell" ] [ text "Priority" ] , th [ class "hidden md:table-cell" ] [ text texts.priority ]
, th [ class "hidden sm:table-cell" ] [ text "Id" ] , th [ class "hidden sm:table-cell" ] [ text texts.id ]
] ]
] ]
, tbody [] , tbody []
(List.map renderSourceLine2 sources) (List.map (renderSourceLine2 texts) sources)
] ]
renderSourceLine2 : SourceAndTags -> Html Msg renderSourceLine2 : Texts -> SourceAndTags -> Html Msg
renderSourceLine2 source = renderSourceLine2 texts source =
tr tr
[ class S.tableRow ] [ class S.tableRow ]
[ td [ class S.editLinkTableCellStyle ] [ td [ class S.editLinkTableCellStyle ]
@ -82,7 +83,7 @@ renderSourceLine2 source =
] ]
[ B.editLinkLabel (Select source) [ B.editLinkLabel (Select source)
, B.linkLabel , B.linkLabel
{ label = "Show" { label = texts.show
, icon = "fa fa-eye" , icon = "fa fa-eye"
, handler = Show source , handler = Show source
, disabled = not source.source.enabled , disabled = not source.source.enabled

View File

@ -19,6 +19,7 @@ import Data.UserState exposing (UserState)
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.UserFormComp exposing (Texts)
import Styles as S import Styles as S
import Util.Maybe import Util.Maybe
@ -166,19 +167,19 @@ update _ 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
[ class "mb-4" ] [ class "mb-4" ]
[ label [ class S.inputLabel ] [ label [ class S.inputLabel ]
[ text "Login" [ text texts.login
, B.inputRequired , B.inputRequired
] ]
, input , input
[ type_ "text" [ type_ "text"
, onInput SetLogin , onInput SetLogin
, placeholder "Login" , placeholder texts.login
, value model.login , value model.login
, class S.textInput , class S.textInput
, classList [ ( S.inputErrorBorder, model.login == "" ) ] , classList [ ( S.inputErrorBorder, model.login == "" ) ]
@ -187,20 +188,20 @@ view2 settings model =
] ]
, div [ class "mb-4" ] , div [ class "mb-4" ]
[ label [ class S.inputLabel ] [ label [ class S.inputLabel ]
[ text "E-Mail" [ text texts.email
] ]
, input , input
[ onInput SetEmail [ onInput SetEmail
, type_ "text" , type_ "text"
, model.email |> Maybe.withDefault "" |> value , model.email |> Maybe.withDefault "" |> value
, placeholder "E-Mail" , placeholder texts.email
, class S.textInput , class S.textInput
] ]
[] []
] ]
, div [ class "mb-4" ] , div [ class "mb-4" ]
[ label [ class S.inputLabel ] [ label [ class S.inputLabel ]
[ text "State" [ text texts.state
] ]
, Html.map StateMsg , Html.map StateMsg
(Comp.Dropdown.view2 (Comp.Dropdown.view2
@ -214,13 +215,13 @@ view2 settings model =
, classList [ ( "hidden", model.user.login /= "" ) ] , classList [ ( "hidden", model.user.login /= "" ) ]
] ]
[ label [ class S.inputLabel ] [ label [ class S.inputLabel ]
[ text "Password" [ text texts.password
, B.inputRequired , B.inputRequired
] ]
, input , input
[ type_ "text" [ type_ "text"
, onInput SetPassword , onInput SetPassword
, placeholder "Password" , placeholder texts.password
, Maybe.withDefault "" model.password |> value , Maybe.withDefault "" model.password |> value
, class S.textInput , class S.textInput
, classList [ ( S.inputErrorBorder, Util.Maybe.isEmpty model.password ) ] , classList [ ( S.inputErrorBorder, Util.Maybe.isEmpty model.password ) ]

View File

@ -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.UserManageComp exposing (Texts)
import Styles as S import Styles as S
import Util.Http import Util.Http
import Util.Maybe import Util.Maybe
@ -30,7 +31,7 @@ type alias Model =
{ tableModel : Comp.UserTable.Model { tableModel : Comp.UserTable.Model
, formModel : Comp.UserForm.Model , formModel : Comp.UserForm.Model
, viewMode : ViewMode , viewMode : ViewMode
, formError : Maybe String , formError : FormError
, loading : Bool , loading : Bool
, deleteConfirm : Comp.YesNoDimmer.Model , deleteConfirm : Comp.YesNoDimmer.Model
} }
@ -41,12 +42,18 @@ type ViewMode
| Form | Form
type FormError
= FormErrorNone
| FormErrorSubmit String
| FormErrorInvalid
emptyModel : Model emptyModel : Model
emptyModel = emptyModel =
{ tableModel = Comp.UserTable.emptyModel { tableModel = Comp.UserTable.emptyModel
, formModel = Comp.UserForm.emptyModel , formModel = Comp.UserForm.emptyModel
, viewMode = Table , viewMode = Table
, formError = Nothing , formError = FormErrorNone
, loading = False , loading = False
, deleteConfirm = Comp.YesNoDimmer.emptyModel , deleteConfirm = Comp.YesNoDimmer.emptyModel
} }
@ -79,7 +86,7 @@ update flags msg model =
, viewMode = Maybe.map (\_ -> Form) tm.selected |> Maybe.withDefault Table , viewMode = Maybe.map (\_ -> Form) tm.selected |> Maybe.withDefault Table
, formError = , formError =
if Util.Maybe.nonEmpty tm.selected then if Util.Maybe.nonEmpty tm.selected then
Nothing FormErrorNone
else else
model.formError model.formError
@ -132,7 +139,7 @@ update flags msg model =
InitNewUser -> InitNewUser ->
let let
nm = nm =
{ model | viewMode = Form, formError = Nothing } { model | viewMode = Form, formError = FormErrorNone }
user = user =
Api.Model.User.empty Api.Model.User.empty
@ -158,7 +165,7 @@ update flags msg model =
( { model | loading = True }, cmd ) ( { model | loading = True }, cmd )
else else
( { model | formError = Just "Please correct the errors in the form." }, Cmd.none ) ( { model | formError = FormErrorInvalid }, Cmd.none )
SubmitResp (Ok res) -> SubmitResp (Ok res) ->
if res.success then if res.success then
@ -172,10 +179,15 @@ update flags msg model =
( { m3 | loading = False }, Cmd.batch [ c2, c3 ] ) ( { m3 | loading = False }, Cmd.batch [ c2, c3 ] )
else else
( { model | formError = Just res.message, loading = False }, Cmd.none ) ( { model | formError = FormErrorSubmit res.message, loading = False }, Cmd.none )
SubmitResp (Err err) -> SubmitResp (Err err) ->
( { model | formError = Just (Util.Http.errorToString err), loading = False }, Cmd.none ) ( { model
| formError = FormErrorSubmit (Util.Http.errorToString err)
, loading = False
}
, Cmd.none
)
RequestDelete -> RequestDelete ->
update flags (YesNoMsg Comp.YesNoDimmer.activate) model update flags (YesNoMsg Comp.YesNoDimmer.activate) model
@ -202,44 +214,44 @@ 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" ] div [ class "flex flex-col" ]
[ MB.view [ MB.view
{ start = [] { start = []
, end = , end =
[ MB.PrimaryButton [ MB.PrimaryButton
{ tagger = InitNewUser { tagger = InitNewUser
, title = "Add a new user" , title = texts.addNewUser
, icon = Just "fa fa-plus" , icon = Just "fa fa-plus"
, label = "New user" , label = texts.newUser
} }
] ]
, rootClasses = "mb-4" , rootClasses = "mb-4"
} }
, Html.map TableMsg (Comp.UserTable.view2 model.tableModel) , Html.map TableMsg (Comp.UserTable.view2 texts.userTable model.tableModel)
, B.loadingDimmer model.loading , B.loadingDimmer model.loading
] ]
viewForm2 : UiSettings -> Model -> Html Msg viewForm2 : Texts -> UiSettings -> Model -> Html Msg
viewForm2 settings model = viewForm2 texts settings model =
let let
newUser = newUser =
Comp.UserForm.isNewUser model.formModel Comp.UserForm.isNewUser model.formModel
dimmerSettings : Comp.YesNoDimmer.Settings dimmerSettings : Comp.YesNoDimmer.Settings
dimmerSettings = dimmerSettings =
Comp.YesNoDimmer.defaultSettings2 "Really delete this user?" Comp.YesNoDimmer.defaultSettings2 texts.reallyDeleteUser
in in
Html.form Html.form
[ class "flex flex-col md:relative" [ class "flex flex-col md:relative"
@ -252,7 +264,7 @@ viewForm2 settings model =
) )
, if newUser then , if newUser then
h3 [ class S.header2 ] h3 [ class S.header2 ]
[ text "Create new user" [ text texts.createNewUser
] ]
else else
@ -263,24 +275,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 newUser then if not newUser then
[ MB.DeleteButton [ MB.DeleteButton
{ tagger = RequestDelete { tagger = RequestDelete
, title = "Delete this user" , title = texts.deleteThisUser
, icon = Just "fa fa-trash" , icon = Just "fa fa-trash"
, label = "Delete" , label = texts.basics.delete
} }
] ]
@ -288,14 +300,22 @@ viewForm2 settings model =
[] []
, rootClasses = "mb-4" , rootClasses = "mb-4"
} }
, Html.map FormMsg (Comp.UserForm.view2 settings model.formModel) , Html.map FormMsg (Comp.UserForm.view2 texts.userForm settings model.formModel)
, div , div
[ classList [ classList
[ ( "hidden", Util.Maybe.isEmpty model.formError ) [ ( "hidden", model.formError == FormErrorNone )
] ]
, class S.errorMessage , class S.errorMessage
] ]
[ Maybe.withDefault "" model.formError |> text [ case model.formError of
FormErrorNone ->
text ""
FormErrorSubmit err ->
text err
FormErrorInvalid ->
text texts.pleaseCorrectErrors
] ]
, B.loadingDimmer model.loading , B.loadingDimmer model.loading
] ]

View File

@ -11,6 +11,7 @@ import Comp.Basic as B
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 Messages.UserTableComp exposing (Texts)
import Styles as S import Styles as S
import Util.Time exposing (formatDateTime) import Util.Time exposing (formatDateTime)
@ -51,32 +52,34 @@ 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 "w-px whitespace-nowrap" ] [] [ th [ class "w-px whitespace-nowrap" ] []
, th [ class "text-left" ] [ text "Login" ] , th [ class "text-left" ] [ text texts.login ]
, th [ class "text-center" ] [ text "State" ] , th [ class "text-center" ] [ text texts.state ]
, th [ class "hidden md:table-cell text-left" ] [ text "Email" ] , th [ class "hidden md:table-cell text-left" ] [ text texts.email ]
, th [ class "hidden md:table-cell text-center" ] [ text "Logins" ] , th [ class "hidden md:table-cell text-center" ] [ text texts.login ]
, th [ class "hidden sm:table-cell text-center" ] [ text "Last Login" ] , th [ class "hidden sm:table-cell text-center" ] [ text texts.lastLogin ]
, th [ class "hidden md:table-cell text-center" ] [ text "Created" ] , th [ class "hidden md:table-cell text-center" ]
[ text texts.basics.created
]
] ]
] ]
, tbody [] , tbody []
(List.map (renderUserLine2 model) model.users) (List.map (renderUserLine2 texts model) model.users)
] ]
renderUserLine2 : Model -> User -> Html Msg renderUserLine2 : Texts -> Model -> User -> Html Msg
renderUserLine2 model user = renderUserLine2 texts model user =
tr tr
[ classList [ ( "active", model.selected == Just user ) ] [ classList [ ( "active", model.selected == Just user ) ]
, class S.tableRow , class S.tableRow
] ]
[ B.editLinkTableCell (Select user) [ B.editLinkTableCell2 texts.basics (Select user)
, td [ class "text-left" ] , td [ class "text-left" ]
[ text user.login [ text user.login
] ]

View File

@ -6,6 +6,7 @@ module Messages exposing
) )
import Messages.App import Messages.App
import Messages.CollectiveSettingsPage
import Messages.LoginPage import Messages.LoginPage
import UiLanguage exposing (UiLanguage(..)) import UiLanguage exposing (UiLanguage(..))
@ -18,6 +19,7 @@ type alias Messages =
, label : String , label : String
, flagIcon : String , flagIcon : String
, app : Messages.App.Texts , app : Messages.App.Texts
, collectiveSettings : Messages.CollectiveSettingsPage.Texts
, login : Messages.LoginPage.Texts , login : Messages.LoginPage.Texts
} }
@ -72,6 +74,7 @@ gb =
, label = "English" , label = "English"
, flagIcon = "flag-icon flag-icon-gb" , flagIcon = "flag-icon flag-icon-gb"
, app = Messages.App.gb , app = Messages.App.gb
, collectiveSettings = Messages.CollectiveSettingsPage.gb
, login = Messages.LoginPage.gb , login = Messages.LoginPage.gb
} }
@ -83,5 +86,6 @@ de =
, label = "Deutsch" , label = "Deutsch"
, flagIcon = "flag-icon flag-icon-de" , flagIcon = "flag-icon flag-icon-de"
, app = Messages.App.de , app = Messages.App.de
, collectiveSettings = Messages.CollectiveSettingsPage.de
, login = Messages.LoginPage.de , login = Messages.LoginPage.de
} }

View File

@ -0,0 +1,39 @@
module Messages.Basics exposing (..)
type alias Texts =
{ incoming : String
, outgoing : String
, tags : String
, items : String
, submit : String
, submitThisForm : String
, cancel : String
, delete : String
, created : String
, edit : String
, back : String
, backToList : String
}
gb : Texts
gb =
{ incoming = "Incoming"
, outgoing = "Outgoing"
, tags = "Tags"
, items = "Items"
, submit = "Submit"
, submitThisForm = "Submit this form"
, cancel = "Cancel"
, delete = "Delete"
, created = "Created"
, edit = "Edit"
, back = "Back"
, backToList = "Back to list"
}
de : Texts
de =
gb

View File

@ -0,0 +1,35 @@
module Messages.ClassifierSettingsFormComp exposing (..)
type alias Texts =
{ autoTaggingText : String
, blacklistOrWhitelist : String
, whitelistLabel : String
, blacklistLabel : String
, itemCount : String
, schedule : String
, itemCountHelp : String
}
gb : Texts
gb =
{ 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.
"""
, blacklistOrWhitelist = "Is the following a blacklist or whitelist?"
, whitelistLabel = "Include tag categories for learning"
, blacklistLabel = "Exclude tag categories from learning"
, itemCount = "Item Count"
, schedule = "Schedule"
, itemCountHelp = "The maximum number of items to learn from, order by date newest first. Use 0 to mean all."
}

View File

@ -0,0 +1,42 @@
module Messages.CollectiveSettingsFormComp exposing (..)
import Messages.ClassifierSettingsFormComp
type alias Texts =
{ classifierSettingsForm : Messages.ClassifierSettingsFormComp.Texts
, save : String
, saveSettings : String
, documentLanguage : String
, documentLanguageHelp : String
, integrationEndpoint : String
, integrationEndpointLabel : String
, integrationEndpointHelp : String
, fulltextSearch : String
, reindexAllData : String
, reindexAllDataHelp : String
, autoTagging : String
, startNow : String
}
gb : Texts
gb =
{ classifierSettingsForm = Messages.ClassifierSettingsFormComp.gb
, save = "Save"
, saveSettings = "Save Settings"
, documentLanguage = "Document Language"
, documentLanguageHelp = "The language of your documents. This helps text recognition (OCR) and text analysis."
, integrationEndpoint = "Integration Endpoint"
, integrationEndpointLabel = "Enable integration endpoint"
, integrationEndpointHelp =
"The integration endpoint allows (local) applications to submit files. "
++ "You can choose to disable it for your collective."
, fulltextSearch = "Full-Text Search"
, reindexAllData = "Re-Index All Data"
, reindexAllDataHelp =
"This starts a task that clears the full-text index and re-indexes all your data again."
++ "You must type OK before clicking the button to avoid accidental re-indexing."
, autoTagging = "Auto-Tagging"
, startNow = "Start now"
}

View File

@ -0,0 +1,44 @@
module Messages.CollectiveSettingsPage exposing (..)
import Messages.Basics
import Messages.CollectiveSettingsFormComp
import Messages.SourceManageComp
import Messages.UserManageComp
type alias Texts =
{ basics : Messages.Basics.Texts
, userManage : Messages.UserManageComp.Texts
, collectiveSettingsForm : Messages.CollectiveSettingsFormComp.Texts
, sourceManage : Messages.SourceManageComp.Texts
, collectiveSettings : String
, insights : String
, sources : String
, settings : String
, users : String
, user : String
, collective : String
, size : String
}
gb : Texts
gb =
{ basics = Messages.Basics.gb
, userManage = Messages.UserManageComp.gb
, collectiveSettingsForm = Messages.CollectiveSettingsFormComp.gb
, sourceManage = Messages.SourceManageComp.gb
, collectiveSettings = "Collective Settings"
, insights = "Insights"
, sources = "Sources"
, settings = "Settings"
, users = "Users"
, user = "User"
, collective = "Collective"
, size = "Size"
}
de : Texts
de =
gb

View File

@ -1,14 +1,16 @@
module Messages.LoginPage exposing module Messages.LoginPage exposing
( Texts ( Texts
, de , de
, fr
, gb , gb
) )
type alias Texts = type alias Texts =
{ username : String { loginToDocspell : String
, username : String
, collectiveSlashLogin : String
, password : String , password : String
, rememberMe : String
, loginPlaceholder : String , loginPlaceholder : String
, passwordPlaceholder : String , passwordPlaceholder : String
, loginButton : String , loginButton : String
@ -20,8 +22,11 @@ type alias Texts =
gb : Texts gb : Texts
gb = gb =
{ username = "Username" { loginToDocspell = "Login to Docspell"
, username = "Username"
, collectiveSlashLogin = "Collective / Login"
, password = "Password" , password = "Password"
, rememberMe = "Remember Me"
, loginPlaceholder = "Login" , loginPlaceholder = "Login"
, passwordPlaceholder = "Password" , passwordPlaceholder = "Password"
, loginButton = "Login" , loginButton = "Login"
@ -33,8 +38,11 @@ gb =
de : Texts de : Texts
de = de =
{ username = "Benutzer" { loginToDocspell = "Docspell Anmeldung"
, username = "Benutzer"
, collectiveSlashLogin = "Kollektiv / Benutzer"
, password = "Passwort" , password = "Passwort"
, rememberMe = "Anmeldung speichern"
, loginPlaceholder = "Benutzer" , loginPlaceholder = "Benutzer"
, passwordPlaceholder = "Passwort" , passwordPlaceholder = "Passwort"
, loginButton = "Anmelden" , loginButton = "Anmelden"
@ -42,16 +50,3 @@ de =
, noAccount = "Kein Konto?" , noAccount = "Kein Konto?"
, signupLink = "Hier registrieren!" , signupLink = "Hier registrieren!"
} }
fr : Texts
fr =
{ username = "Identifiant"
, password = "Mot de passe"
, loginPlaceholder = "Utilisateur"
, passwordPlaceholder = "Mot de passe"
, loginButton = "Connexion"
, loginSuccessful = "Identification réussie"
, noAccount = "Pas de compte ?"
, signupLink = "S'inscrire"
}

View File

@ -0,0 +1,61 @@
module Messages.SourceFormComp exposing (..)
import Messages.Basics
type alias Texts =
{ basics : Messages.Basics.Texts
, name : String
, description : String
, enabled : String
, priority : String
, priorityInfo : String
, metadata : String
, metadataInfoText : String
, folder : String
, folderInfo : String
, folderForbiddenText : String
, tagsInfo : String
, fileFilter : String
, fileFilterInfo : String
, language : String
, languageInfo : String
}
gb : Texts
gb =
{ basics = Messages.Basics.gb
, name = "Name"
, description = "Description"
, enabled = "Enabled"
, priority = "Priority"
, priorityInfo = "The priority used by the scheduler when processing uploaded files."
, metadata = "Metadata"
, metadataInfoText =
"Metadata specified here is automatically attached to each item uploaded "
++ "through this source, unless it is overriden in the upload request meta data. "
++ "Tags from the request are added to those defined here."
, folder = "Folder"
, folderInfo = "Choose a folder to automatically put items into."
, folderForbiddenText =
"""
You are **not a member** of this folder. Items created through this
link will be **hidden** from any search results. Use a folder where
you are a member of to make items visible. This message will
disappear then.
"""
, tagsInfo = "Choose tags that should be applied to items."
, fileFilter = "File Filter"
, fileFilterInfo = """
Specify a file glob to filter files when uploading archives
(e.g. for email and zip). For example, to only extract pdf files:
`*.pdf`. Globs can be combined via OR, like this: `*.pdf|mail.html`.
"""
, language = "Language"
, languageInfo =
"Used for text extraction and analysis. The collective's "
++ "default language is used if not specified here."
}

View File

@ -0,0 +1,53 @@
module Messages.SourceManageComp exposing (..)
import Messages.Basics
import Messages.SourceFormComp
import Messages.SourceTableComp
type alias Texts =
{ basics : Messages.Basics.Texts
, sourceTable : Messages.SourceTableComp.Texts
, sourceForm : Messages.SourceFormComp.Texts
, addSourceUrl : String
, newSource : String
, publicUploads : String
, sourceInfoText : String
, itemsCreatedInfo : Int -> String
, publicUploadPage : String
, copyToClipboard : String
, openInNewTab : String
, publicUploadUrl : String
, reallyDeleteSource : String
, createNewSource : String
, deleteThisSource : String
, errorGeneratingQR : String
}
gb : Texts
gb =
{ basics = Messages.Basics.gb
, sourceTable = Messages.SourceTableComp.gb
, sourceForm = Messages.SourceFormComp.gb
, addSourceUrl = "Add a source url"
, newSource = "New source"
, publicUploads = "Public Uploads"
, sourceInfoText =
"This source defines URLs that can be used by anyone to send files to "
++ "you. There is a web page that you can share or the API url can be used "
++ "with other clients."
, itemsCreatedInfo =
\n ->
"There have been "
++ String.fromInt n
++ " items created through this source."
, publicUploadPage = "Public Upload Page"
, copyToClipboard = "Copy to clipboard"
, openInNewTab = "Open in new tab/window"
, publicUploadUrl = "Public API Upload URL"
, reallyDeleteSource = "Really delete this source?"
, createNewSource = "Create new source"
, deleteThisSource = "Delete this source"
, errorGeneratingQR = "Error generating QR Code"
}

View File

@ -0,0 +1,22 @@
module Messages.SourceTableComp exposing (..)
type alias Texts =
{ abbrev : String
, enabled : String
, counter : String
, priority : String
, id : String
, show : String
}
gb : Texts
gb =
{ abbrev = "Abbrev"
, enabled = "Enabled"
, counter = "Counter"
, priority = "Priority"
, id = "Id"
, show = "Show"
}

View File

@ -0,0 +1,18 @@
module Messages.UserFormComp exposing (..)
type alias Texts =
{ login : String
, state : String
, email : String
, password : String
}
gb : Texts
gb =
{ login = "Login"
, state = "State"
, email = "E-Mail"
, password = "Password"
}

View File

@ -0,0 +1,39 @@
module Messages.UserManageComp exposing (..)
import Messages.Basics
import Messages.UserFormComp
import Messages.UserTableComp
type alias Texts =
{ userTable : Messages.UserTableComp.Texts
, userForm : Messages.UserFormComp.Texts
, users : String
, newUser : String
, addNewUser : String
, reallyDeleteUser : String
, createNewUser : String
, basics : Messages.Basics.Texts
, deleteThisUser : String
, pleaseCorrectErrors : String
}
gb : Texts
gb =
{ userTable = Messages.UserTableComp.gb
, userForm = Messages.UserFormComp.gb
, basics = Messages.Basics.gb
, users = "Users"
, newUser = "New user"
, addNewUser = "Add new user"
, reallyDeleteUser = "Really delete this user?"
, createNewUser = "Create new user"
, deleteThisUser = "Delete this user"
, pleaseCorrectErrors = "Please correct the errors in the form."
}
de : Texts
de =
gb

View File

@ -0,0 +1,26 @@
module Messages.UserTableComp exposing (..)
import Messages.Basics
type alias Texts =
{ basics : Messages.Basics.Texts
, login : String
, state : String
, email : String
, logins : String
, lastLogin : String
, created : String
}
gb : Texts
gb =
{ basics = Messages.Basics.gb
, login = "Login"
, state = "State"
, email = "E-Mail"
, logins = "Logins"
, lastLogin = "Last Login"
, created = "Created"
}

View File

@ -11,14 +11,15 @@ 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.CollectiveSettingsPage exposing (Texts)
import Page.CollectiveSettings.Data exposing (..) import Page.CollectiveSettings.Data exposing (..)
import Styles as S import Styles as S
import Util.Maybe import Util.Maybe
import Util.Size import Util.Size
viewSidebar : Bool -> Flags -> UiSettings -> Model -> Html Msg viewSidebar : Texts -> Bool -> Flags -> UiSettings -> Model -> Html Msg
viewSidebar visible _ _ model = viewSidebar texts visible _ _ model =
div div
[ id "sidebar" [ id "sidebar"
, class S.sidebar , class S.sidebar
@ -27,7 +28,7 @@ viewSidebar visible _ _ model =
] ]
[ div [ class "" ] [ div [ class "" ]
[ h1 [ class S.header1 ] [ h1 [ class S.header1 ]
[ text "Collective Settings" [ text texts.collectiveSettings
] ]
] ]
, div [ class "flex flex-col my-2" ] , div [ class "flex flex-col my-2" ]
@ -40,7 +41,7 @@ viewSidebar visible _ _ model =
[ i [ class "fa fa-chart-bar" ] [] [ i [ class "fa fa-chart-bar" ] []
, span , span
[ class "ml-3" ] [ class "ml-3" ]
[ text "Insights" ] [ text texts.insights ]
] ]
, a , a
[ href "#" [ href "#"
@ -51,7 +52,7 @@ viewSidebar visible _ _ model =
[ Icons.sourceIcon2 "" [ Icons.sourceIcon2 ""
, span , span
[ class "ml-3" ] [ class "ml-3" ]
[ text "Sources" ] [ text texts.sources ]
] ]
, a , a
[ href "#" [ href "#"
@ -62,7 +63,7 @@ viewSidebar visible _ _ model =
[ i [ class "fa fa-cog" ] [] [ i [ class "fa fa-cog" ] []
, span , span
[ class "ml-3" ] [ class "ml-3" ]
[ text "Settings" ] [ text texts.settings ]
] ]
, a , a
[ href "#" [ href "#"
@ -73,30 +74,30 @@ viewSidebar visible _ _ model =
[ i [ class "fa fa-user" ] [] [ i [ class "fa fa-user" ] []
, span , span
[ class "ml-3" ] [ class "ml-3" ]
[ text "Users" ] [ text texts.users ]
] ]
] ]
] ]
viewContent : Flags -> UiSettings -> Model -> Html Msg viewContent : Texts -> Flags -> UiSettings -> Model -> Html Msg
viewContent flags settings model = viewContent texts flags settings model =
div div
[ id "content" [ id "content"
, class S.content , class S.content
] ]
(case model.currentTab of (case model.currentTab of
Just UserTab -> Just UserTab ->
viewUsers settings model viewUsers texts settings model
Just SettingsTab -> Just SettingsTab ->
viewSettings flags settings model viewSettings texts flags settings model
Just InsightsTab -> Just InsightsTab ->
viewInsights flags model viewInsights texts flags model
Just SourceTab -> Just SourceTab ->
viewSources flags settings model viewSources texts flags settings model
Nothing -> Nothing ->
[] []
@ -116,8 +117,8 @@ menuEntryActive model tab =
class "" class ""
viewInsights : Flags -> Model -> List (Html Msg) viewInsights : Texts -> Flags -> Model -> List (Html Msg)
viewInsights flags model = viewInsights texts flags model =
let let
( coll, user ) = ( coll, user ) =
Maybe.map (\a -> ( a.collective, a.user )) flags.account Maybe.map (\a -> ( a.collective, a.user )) flags.account
@ -126,7 +127,7 @@ viewInsights flags model =
[ h1 [ class S.header1 ] [ h1 [ class S.header1 ]
[ i [ class "fa fa-chart-bar font-thin" ] [] [ i [ class "fa fa-chart-bar font-thin" ] []
, span [ class "ml-2" ] , span [ class "ml-2" ]
[ text "Insights" [ text texts.insights
] ]
] ]
, div [ class "mb-4" ] , div [ class "mb-4" ]
@ -136,7 +137,7 @@ viewInsights flags model =
[ div [ class "flex flex-row space-x-6" ] [ div [ class "flex flex-row space-x-6" ]
[ div [ div
[ class "" [ class ""
, title "Collective" , title texts.collective
] ]
[ i [ class "fa fa-users" ] [] [ i [ class "fa fa-users" ] []
, span [ class "ml-2" ] , span [ class "ml-2" ]
@ -145,7 +146,7 @@ viewInsights flags model =
] ]
, div , div
[ class "" [ class ""
, title "User" , title texts.user
] ]
[ i [ class "fa fa-user font-thin" ] [] [ i [ class "fa fa-user font-thin" ] []
, span [ class "ml-2" ] , span [ class "ml-2" ]
@ -161,26 +162,26 @@ viewInsights flags model =
[ text "Items" [ text "Items"
] ]
, div [ class "flex px-4 flex-wrap" ] , div [ class "flex px-4 flex-wrap" ]
[ stats (String.fromInt (model.insights.incomingCount + model.insights.outgoingCount)) "Items" [ stats (String.fromInt (model.insights.incomingCount + model.insights.outgoingCount)) texts.basics.items
, stats (String.fromInt model.insights.incomingCount) "Incoming" , stats (String.fromInt model.insights.incomingCount) texts.basics.incoming
, stats (String.fromInt model.insights.outgoingCount) "Outgoing" , stats (String.fromInt model.insights.outgoingCount) texts.basics.outgoing
] ]
] ]
, div , div
[ class "py-2" [ class "py-2"
] ]
[ h4 [ class S.header3 ] [ h4 [ class S.header3 ]
[ text "Size" [ text texts.size
] ]
, div [ class "flex px-4 flex-wrap" ] , div [ class "flex px-4 flex-wrap" ]
[ stats (toFloat model.insights.itemSize |> Util.Size.bytesReadable Util.Size.B) "Size" [ stats (toFloat model.insights.itemSize |> Util.Size.bytesReadable Util.Size.B) texts.size
] ]
] ]
, div , div
[ class "py-2" [ class "py-2"
] ]
[ h4 [ class S.header3 ] [ h4 [ class S.header3 ]
[ text "Tags" [ text texts.basics.tags
] ]
, div [ class "flex px-4 flex-wrap" ] , div [ class "flex px-4 flex-wrap" ]
(List.map makeTagStats (List.map makeTagStats
@ -207,54 +208,66 @@ makeTagStats nc =
stats (String.fromInt nc.count) nc.tag.name stats (String.fromInt nc.count) nc.tag.name
viewSources : Flags -> UiSettings -> Model -> List (Html Msg) viewSources : Texts -> Flags -> UiSettings -> Model -> List (Html Msg)
viewSources flags settings model = viewSources texts flags settings model =
[ h1 [ h1
[ class S.header1 [ class S.header1
, class "inline-flex items-center" , class "inline-flex items-center"
] ]
[ Icons.sourceIcon2 "" [ Icons.sourceIcon2 ""
, div [ class "ml-3" ] , div [ class "ml-3" ]
[ text "Sources" [ text texts.sources
] ]
] ]
, Html.map SourceMsg (Comp.SourceManage.view2 flags settings model.sourceModel) , Html.map SourceMsg (Comp.SourceManage.view2 texts.sourceManage flags settings model.sourceModel)
] ]
viewUsers : UiSettings -> Model -> List (Html Msg) viewUsers : Texts -> UiSettings -> Model -> List (Html Msg)
viewUsers settings model = viewUsers texts settings model =
[ h1 [ h1
[ class S.header1 [ class S.header1
, class "inline-flex items-center" , class "inline-flex items-center"
] ]
[ i [ class "fa fa-user" ] [] [ i [ class "fa fa-user" ] []
, div [ class "ml-3" ] , div [ class "ml-3" ]
[ text "Users" [ text texts.users
] ]
] ]
, Html.map UserMsg (Comp.UserManage.view2 settings model.userModel) , Html.map UserMsg (Comp.UserManage.view2 texts.userManage settings model.userModel)
] ]
viewSettings : Flags -> UiSettings -> Model -> List (Html Msg) viewSettings : Texts -> Flags -> UiSettings -> Model -> List (Html Msg)
viewSettings flags settings model = viewSettings texts flags settings model =
[ h2 [ h2
[ class S.header1 [ class S.header1
, class "inline-flex items-center" , class "inline-flex items-center"
] ]
[ i [ class "fa fa-cog" ] [] [ i [ class "fa fa-cog" ] []
, span [ class "ml-3" ] , span [ class "ml-3" ]
[ text "Collective Settings" [ text texts.collectiveSettings
] ]
] ]
, Html.map SettingsFormMsg , Html.map SettingsFormMsg
(Comp.CollectiveSettingsForm.view2 flags settings model.settingsModel) (Comp.CollectiveSettingsForm.view2
flags
texts.collectiveSettingsForm
settings
model.settingsModel
)
, div , div
[ classList [ classList
[ ( "hidden", Util.Maybe.isEmpty model.submitResult ) [ ( "hidden", Util.Maybe.isEmpty model.submitResult )
, ( S.successMessage, Maybe.map .success model.submitResult |> Maybe.withDefault False ) , ( S.successMessage
, ( S.errorMessage, Maybe.map .success model.submitResult |> Maybe.map not |> Maybe.withDefault False ) , Maybe.map .success model.submitResult
|> Maybe.withDefault False
)
, ( S.errorMessage
, Maybe.map .success model.submitResult
|> Maybe.map not
|> Maybe.withDefault False
)
] ]
, class "mt-2" , class "mt-2"
] ]

View File

@ -6,6 +6,7 @@ import Data.UiSettings exposing (UiSettings)
import Html exposing (..) import Html exposing (..)
import Html.Attributes exposing (..) import Html.Attributes exposing (..)
import Html.Events exposing (onCheck, onInput, onSubmit) import Html.Events exposing (onCheck, onInput, onSubmit)
import Messages.LoginPage exposing (Texts)
import Page exposing (Page(..)) import Page exposing (Page(..))
import Page.Login.Data exposing (..) import Page.Login.Data exposing (..)
import Styles as S import Styles as S
@ -20,8 +21,8 @@ viewSidebar _ _ _ _ =
[] []
viewContent : Flags -> VersionInfo -> UiSettings -> Model -> Html Msg viewContent : Texts -> Flags -> VersionInfo -> UiSettings -> Model -> Html Msg
viewContent flags versionInfo _ model = viewContent texts flags versionInfo _ model =
div div
[ id "content" [ id "content"
, class "h-full flex flex-col items-center justify-center w-full" , class "h-full flex flex-col items-center justify-center w-full"
@ -36,7 +37,7 @@ viewContent flags versionInfo _ model =
[] []
] ]
, div [ class "font-medium self-center text-xl sm:text-2xl" ] , div [ class "font-medium self-center text-xl sm:text-2xl" ]
[ text "Login to Docspell" [ text texts.loginToDocspell
] ]
, Html.form , Html.form
[ action "#" [ action "#"
@ -48,7 +49,7 @@ viewContent flags versionInfo _ model =
[ for "username" [ for "username"
, class S.inputLabel , class S.inputLabel
] ]
[ text "Username" [ text texts.username
] ]
, div [ class "relative" ] , div [ class "relative" ]
[ div [ class S.inputIcon ] [ div [ class S.inputIcon ]
@ -62,7 +63,7 @@ viewContent flags versionInfo _ model =
, value model.username , value model.username
, autofocus True , autofocus True
, class ("pl-10 pr-4 py-2 rounded-lg" ++ S.textInput) , class ("pl-10 pr-4 py-2 rounded-lg" ++ S.textInput)
, placeholder "Collective / Login" , placeholder texts.collectiveSlashLogin
] ]
[] []
] ]
@ -72,7 +73,7 @@ viewContent flags versionInfo _ model =
[ for "password" [ for "password"
, class S.inputLabel , class S.inputLabel
] ]
[ text "Password" [ text texts.password
] ]
, div [ class "relative" ] , div [ class "relative" ]
[ div [ class S.inputIcon ] [ div [ class S.inputIcon ]
@ -85,7 +86,7 @@ viewContent flags versionInfo _ model =
, onInput SetPassword , onInput SetPassword
, value model.password , value model.password
, class ("pl-10 pr-4 py-2 rounded-lg" ++ S.textInput) , class ("pl-10 pr-4 py-2 rounded-lg" ++ S.textInput)
, placeholder "Password" , placeholder texts.password
] ]
[] []
] ]
@ -107,7 +108,7 @@ viewContent flags versionInfo _ model =
, span , span
[ class "mb-1 ml-2 text-xs sm:text-sm tracking-wide my-1" [ class "mb-1 ml-2 text-xs sm:text-sm tracking-wide my-1"
] ]
[ text "Remember Me" [ text texts.rememberMe
] ]
] ]
] ]
@ -116,23 +117,23 @@ viewContent flags versionInfo _ model =
[ type_ "submit" [ type_ "submit"
, class S.primaryButton , class S.primaryButton
] ]
[ text "Login" [ text texts.loginButton
] ]
] ]
, resultMessage model , resultMessage texts model
, div , div
[ class "flex justify-end text-sm pt-4" [ class "flex justify-end text-sm pt-4"
, classList [ ( "hidden", flags.config.signupMode == "closed" ) ] , classList [ ( "hidden", flags.config.signupMode == "closed" ) ]
] ]
[ span [] [ span []
[ text "No account?" [ text texts.noAccount
] ]
, a , a
[ Page.href RegisterPage [ Page.href RegisterPage
, class ("ml-2" ++ S.link) , class ("ml-2" ++ S.link)
] ]
[ i [ class "fa fa-user-plus mr-1" ] [] [ i [ class "fa fa-user-plus mr-1" ] []
, text "Sign up" , text texts.signupLink
] ]
] ]
] ]
@ -155,13 +156,13 @@ viewContent flags versionInfo _ model =
] ]
resultMessage : Model -> Html Msg resultMessage : Texts -> Model -> Html Msg
resultMessage model = resultMessage texts model =
case model.result of case model.result of
Just r -> Just r ->
if r.success then if r.success then
div [ class ("my-2" ++ S.successMessage) ] div [ class ("my-2" ++ S.successMessage) ]
[ text "Login successful." [ text texts.loginSuccessful
] ]
else else