mirror of
				https://github.com/TheAnachronism/docspell.git
				synced 2025-10-30 21:40:12 +00:00 
			
		
		
		
	| @@ -4,7 +4,8 @@ | ||||
|  | ||||
| *Feb 19, 2021* | ||||
|  | ||||
| This release comes with a completely new ui, including a dark theme! | ||||
| This release comes with a completely new ui based on | ||||
| [tailwindcss](https://tailwindcss.com), including a dark theme! | ||||
| Additionally there are some other minor features and bug fixes. | ||||
|  | ||||
| - New Web-UI with light and dark theme (#293). | ||||
|   | ||||
| @@ -61,10 +61,7 @@ processes. | ||||
| The web frontend is written in [Elm](https://elm-lang.org), which is a | ||||
| nice functional language that compiles to javascript. The frontend is | ||||
| included in the http/restserver component. The CSS is provided by | ||||
| [Fomantic-UI](https://fomantic-ui.com/), where a [custom | ||||
| build](https://github.com/eikek/fomantic-slim-default) of it is used | ||||
| to avoid dependency to a google font and jquery (all javascript | ||||
| modules are removed). | ||||
| [TailwindCSS](https://tailwindcss.com/).. | ||||
|  | ||||
| The [development](https://docspell.org/docs/dev/building/) page | ||||
| contains some tips to get started. | ||||
|   | ||||
| @@ -18,12 +18,11 @@ case class Flags( | ||||
|     fullTextSearchEnabled: Boolean, | ||||
|     maxPageSize: Int, | ||||
|     maxNoteLength: Int, | ||||
|     showClassificationSettings: Boolean, | ||||
|     uiVersion: Int | ||||
|     showClassificationSettings: Boolean | ||||
| ) | ||||
|  | ||||
| object Flags { | ||||
|   def apply(cfg: Config, uiVersion: Int): Flags = | ||||
|   def apply(cfg: Config): Flags = | ||||
|     Flags( | ||||
|       cfg.appName, | ||||
|       getBaseUrl(cfg), | ||||
| @@ -33,8 +32,7 @@ object Flags { | ||||
|       cfg.fullTextSearch.enabled, | ||||
|       cfg.maxItemPageSize, | ||||
|       cfg.maxNoteLength, | ||||
|       cfg.showClassificationSettings, | ||||
|       uiVersion | ||||
|       cfg.showClassificationSettings | ||||
|     ) | ||||
|  | ||||
|   private def getBaseUrl(cfg: Config): String = | ||||
|   | ||||
| @@ -14,8 +14,6 @@ import org.http4s.HttpRoutes | ||||
| import org.http4s._ | ||||
| import org.http4s.dsl.Http4sDsl | ||||
| import org.http4s.headers._ | ||||
| import org.http4s.util.CaseInsensitiveString | ||||
| import org.http4s.util.Writer | ||||
| import org.log4s._ | ||||
| import yamusca.implicits._ | ||||
| import yamusca.imports._ | ||||
| @@ -26,32 +24,6 @@ object TemplateRoutes { | ||||
|   val `text/html`              = new MediaType("text", "html") | ||||
|   val `application/javascript` = new MediaType("application", "javascript") | ||||
|  | ||||
|   val ui2Header = CaseInsensitiveString("Docspell-Ui2") | ||||
|  | ||||
|   case class UiVersion(version: Int) extends Header.Parsed { | ||||
|     val key = UiVersion | ||||
|     def renderValue(writer: Writer): writer.type = | ||||
|       writer.append(version) | ||||
|   } | ||||
|   object UiVersion extends HeaderKey.Singleton { | ||||
|     val default = UiVersion(2) | ||||
|  | ||||
|     def get[F[_]](req: Request[F]): UiVersion = | ||||
|       req.headers.get(UiVersion).getOrElse(UiVersion.default) | ||||
|  | ||||
|     type HeaderT = UiVersion | ||||
|     val name = CaseInsensitiveString("Docspell-Ui") | ||||
|     override def parse(s: String): ParseResult[UiVersion] = | ||||
|       Either | ||||
|         .catchNonFatal(s.trim.toInt) | ||||
|         .leftMap(ex => ParseFailure("Invalid int header", ex.getMessage)) | ||||
|         .map(UiVersion.apply) | ||||
|  | ||||
|     override def matchHeader(h: Header): Option[UiVersion] = | ||||
|       if (h.name == name) parse(h.value).toOption | ||||
|       else None | ||||
|   } | ||||
|  | ||||
|   trait InnerRoutes[F[_]] { | ||||
|     def doc: HttpRoutes[F] | ||||
|     def app: HttpRoutes[F] | ||||
| @@ -81,24 +53,22 @@ object TemplateRoutes { | ||||
|           } yield resp | ||||
|         } | ||||
|       def app = | ||||
|         HttpRoutes.of[F] { case req @ GET -> _ => | ||||
|         HttpRoutes.of[F] { case GET -> _ => | ||||
|           for { | ||||
|             templ <- indexTemplate | ||||
|             uiv = UiVersion.get(req).version | ||||
|             resp <- Ok( | ||||
|               IndexData(cfg, uiv).render(templ), | ||||
|               IndexData(cfg).render(templ), | ||||
|               `Content-Type`(`text/html`, Charset.`UTF-8`) | ||||
|             ) | ||||
|           } yield resp | ||||
|         } | ||||
|  | ||||
|       def serviceWorker = | ||||
|         HttpRoutes.of[F] { case req @ GET -> _ => | ||||
|         HttpRoutes.of[F] { case GET -> _ => | ||||
|           for { | ||||
|             templ <- swTemplate | ||||
|             uiv = UiVersion.get(req).version | ||||
|             resp <- Ok( | ||||
|               IndexData(cfg, uiv).render(templ), | ||||
|               IndexData(cfg).render(templ), | ||||
|               `Content-Type`(`application/javascript`, Charset.`UTF-8`) | ||||
|             ) | ||||
|           } yield resp | ||||
| @@ -164,10 +134,10 @@ object TemplateRoutes { | ||||
|  | ||||
|   object IndexData { | ||||
|  | ||||
|     def apply(cfg: Config, uiVersion: Int): IndexData = | ||||
|     def apply(cfg: Config): IndexData = | ||||
|       IndexData( | ||||
|         Flags(cfg, uiVersion), | ||||
|         chooseUi(uiVersion), | ||||
|         Flags(cfg), | ||||
|         chooseUi, | ||||
|         Seq( | ||||
|           "/app/assets" + Webjars.clipboardjs + "/clipboard.min.js", | ||||
|           s"/app/assets/docspell-webapp/${BuildInfo.version}/docspell-app.js", | ||||
| @@ -175,17 +145,11 @@ object TemplateRoutes { | ||||
|         ), | ||||
|         s"/app/assets/docspell-webapp/${BuildInfo.version}/favicon", | ||||
|         s"/app/assets/docspell-webapp/${BuildInfo.version}/docspell.js", | ||||
|         Flags(cfg, uiVersion).asJson.spaces2 | ||||
|         Flags(cfg).asJson.spaces2 | ||||
|       ) | ||||
|  | ||||
|     private def chooseUi(uiVersion: Int): Seq[String] = | ||||
|       if (uiVersion == 2) | ||||
|         Seq(s"/app/assets/docspell-webapp/${BuildInfo.version}/css/styles.css") | ||||
|       else | ||||
|         Seq( | ||||
|           "/app/assets" + Webjars.fomanticslimdefault + "/semantic.min.css", | ||||
|           s"/app/assets/docspell-webapp/${BuildInfo.version}/docspell.css" | ||||
|         ) | ||||
|     private def chooseUi: Seq[String] = | ||||
|       Seq(s"/app/assets/docspell-webapp/${BuildInfo.version}/css/styles.css") | ||||
|  | ||||
|     implicit def yamuscaValueConverter: ValueConverter[IndexData] = | ||||
|       ValueConverter.deriveConverter[IndexData] | ||||
|   | ||||
| @@ -1,335 +0,0 @@ | ||||
| module App.View exposing (view) | ||||
|  | ||||
| import App.Data exposing (..) | ||||
| import Data.Flags | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onClick) | ||||
| import Page exposing (Page(..)) | ||||
| import Page.CollectiveSettings.View | ||||
| import Page.Home.Data | ||||
| import Page.Home.View | ||||
| import Page.ItemDetail.View | ||||
| import Page.Login.View | ||||
| import Page.ManageData.View | ||||
| import Page.NewInvite.View | ||||
| import Page.Queue.View | ||||
| import Page.Register.View | ||||
| import Page.Upload.View | ||||
| import Page.UserSettings.View | ||||
|  | ||||
|  | ||||
| view : Model -> Html Msg | ||||
| view model = | ||||
|     case model.page of | ||||
|         LoginPage _ -> | ||||
|             loginLayout model | ||||
|  | ||||
|         RegisterPage -> | ||||
|             registerLayout model | ||||
|  | ||||
|         _ -> | ||||
|             defaultLayout model | ||||
|  | ||||
|  | ||||
| registerLayout : Model -> Html Msg | ||||
| registerLayout model = | ||||
|     div [ class "register-layout" ] | ||||
|         [ viewRegister model | ||||
|         , footer model | ||||
|         ] | ||||
|  | ||||
|  | ||||
| loginLayout : Model -> Html Msg | ||||
| loginLayout model = | ||||
|     div [ class "login-layout" ] | ||||
|         [ viewLogin model | ||||
|         , footer model | ||||
|         ] | ||||
|  | ||||
|  | ||||
| defaultLayout : Model -> Html Msg | ||||
| defaultLayout model = | ||||
|     div [ class "default-layout" ] | ||||
|         [ div [ class "ui fixed top sticky attached large menu top-menu" ] | ||||
|             [ div [ class "ui fluid container" ] | ||||
|                 [ a | ||||
|                     [ class "header item narrow-item" | ||||
|                     , Page.href HomePage | ||||
|                     ] | ||||
|                     [ img | ||||
|                         [ class "image" | ||||
|                         , src (model.flags.config.docspellAssetPath ++ "/img/logo-96.png") | ||||
|                         ] | ||||
|                         [] | ||||
|                     , div [ class "content" ] | ||||
|                         [ text model.flags.config.appName | ||||
|                         ] | ||||
|                     ] | ||||
|                 , loginInfo model | ||||
|                 ] | ||||
|             ] | ||||
|         , div | ||||
|             [ class "main-content" | ||||
|             , id "main-content" | ||||
|             ] | ||||
|             [ case model.page of | ||||
|                 HomePage -> | ||||
|                     viewHome model | ||||
|  | ||||
|                 LoginPage _ -> | ||||
|                     viewLogin model | ||||
|  | ||||
|                 ManageDataPage -> | ||||
|                     viewManageData model | ||||
|  | ||||
|                 CollectiveSettingPage -> | ||||
|                     viewCollectiveSettings model | ||||
|  | ||||
|                 UserSettingPage -> | ||||
|                     viewUserSettings model | ||||
|  | ||||
|                 QueuePage -> | ||||
|                     viewQueue model | ||||
|  | ||||
|                 RegisterPage -> | ||||
|                     viewRegister model | ||||
|  | ||||
|                 UploadPage mid -> | ||||
|                     viewUpload mid model | ||||
|  | ||||
|                 NewInvitePage -> | ||||
|                     viewNewInvite model | ||||
|  | ||||
|                 ItemDetailPage id -> | ||||
|                     viewItemDetail id model | ||||
|             ] | ||||
|         , footer model | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewItemDetail : String -> Model -> Html Msg | ||||
| viewItemDetail id model = | ||||
|     let | ||||
|         inav = | ||||
|             Page.Home.Data.itemNav id model.homeModel | ||||
|     in | ||||
|     Html.map ItemDetailMsg (Page.ItemDetail.View.view inav model.uiSettings model.itemDetailModel) | ||||
|  | ||||
|  | ||||
| viewNewInvite : Model -> Html Msg | ||||
| viewNewInvite model = | ||||
|     Html.map NewInviteMsg (Page.NewInvite.View.view model.flags model.newInviteModel) | ||||
|  | ||||
|  | ||||
| viewUpload : Maybe String -> Model -> Html Msg | ||||
| viewUpload mid model = | ||||
|     Html.map UploadMsg (Page.Upload.View.view mid model.uploadModel) | ||||
|  | ||||
|  | ||||
| viewRegister : Model -> Html Msg | ||||
| viewRegister model = | ||||
|     Html.map RegisterMsg (Page.Register.View.view model.flags model.registerModel) | ||||
|  | ||||
|  | ||||
| viewQueue : Model -> Html Msg | ||||
| viewQueue model = | ||||
|     Html.map QueueMsg (Page.Queue.View.view model.queueModel) | ||||
|  | ||||
|  | ||||
| viewUserSettings : Model -> Html Msg | ||||
| viewUserSettings model = | ||||
|     Html.map UserSettingsMsg (Page.UserSettings.View.view model.flags model.uiSettings model.userSettingsModel) | ||||
|  | ||||
|  | ||||
| viewCollectiveSettings : Model -> Html Msg | ||||
| viewCollectiveSettings model = | ||||
|     Html.map CollSettingsMsg | ||||
|         (Page.CollectiveSettings.View.view model.flags | ||||
|             model.uiSettings | ||||
|             model.collSettingsModel | ||||
|         ) | ||||
|  | ||||
|  | ||||
| viewManageData : Model -> Html Msg | ||||
| viewManageData model = | ||||
|     Html.map ManageDataMsg | ||||
|         (Page.ManageData.View.view model.flags | ||||
|             model.uiSettings | ||||
|             model.manageDataModel | ||||
|         ) | ||||
|  | ||||
|  | ||||
| viewLogin : Model -> Html Msg | ||||
| viewLogin model = | ||||
|     Html.map LoginMsg (Page.Login.View.view model.flags model.loginModel) | ||||
|  | ||||
|  | ||||
| viewHome : Model -> Html Msg | ||||
| viewHome model = | ||||
|     Html.map HomeMsg (Page.Home.View.view model.flags model.uiSettings model.homeModel) | ||||
|  | ||||
|  | ||||
| menuEntry : Model -> Page -> List (Html Msg) -> Html Msg | ||||
| menuEntry model page children = | ||||
|     a | ||||
|         [ classList | ||||
|             [ ( "icon item", True ) | ||||
|             , ( "active", model.page == page ) | ||||
|             ] | ||||
|         , Page.href page | ||||
|         ] | ||||
|         children | ||||
|  | ||||
|  | ||||
| loginInfo : Model -> Html Msg | ||||
| loginInfo model = | ||||
|     div [ class "right menu" ] | ||||
|         (case model.flags.account of | ||||
|             Just acc -> | ||||
|                 [ div | ||||
|                     [ class "ui dropdown icon link item" | ||||
|                     , href "#" | ||||
|                     , onClick ToggleUserMenu | ||||
|                     , title ("Logged in as " ++ Data.Flags.accountString acc) | ||||
|                     ] | ||||
|                     [ i [ class "user alternate icon" ] [] | ||||
|                     , div | ||||
|                         [ classList | ||||
|                             [ ( "left menu", True ) | ||||
|                             , ( "transition visible", model.userMenuOpen ) | ||||
|                             , ( "transition hidden", not model.userMenuOpen ) | ||||
|                             ] | ||||
|                         ] | ||||
|                         [ div [ class "header" ] | ||||
|                             [ i [ class "user outline icon" ] [] | ||||
|                             , Data.Flags.accountString acc |> text | ||||
|                             ] | ||||
|                         , div [ class "ui divider" ] [] | ||||
|                         , menuEntry model | ||||
|                             CollectiveSettingPage | ||||
|                             [ i [ class "users circle icon" ] [] | ||||
|                             , text "Collective Profile" | ||||
|                             ] | ||||
|                         , menuEntry model | ||||
|                             UserSettingPage | ||||
|                             [ i [ class "user circle icon" ] [] | ||||
|                             , text "User Profile" | ||||
|                             ] | ||||
|                         , div [ class "divider" ] [] | ||||
|                         , a | ||||
|                             [ class "icon item" | ||||
|                             , href "#" | ||||
|                             , onClick Logout | ||||
|                             ] | ||||
|                             [ i [ class "sign out icon" ] [] | ||||
|                             , text "Logout" | ||||
|                             ] | ||||
|                         ] | ||||
|                     ] | ||||
|                 , div | ||||
|                     [ class "ui dropdown icon link item" | ||||
|                     , onClick ToggleNavMenu | ||||
|                     , href "#" | ||||
|                     ] | ||||
|                     [ i [ class "ui bars icon" ] [] | ||||
|                     , div | ||||
|                         [ classList | ||||
|                             [ ( "left menu", True ) | ||||
|                             , ( "transition visible", model.navMenuOpen ) | ||||
|                             , ( "transition hidden", not model.navMenuOpen ) | ||||
|                             ] | ||||
|                         ] | ||||
|                         [ menuEntry model | ||||
|                             HomePage | ||||
|                             [ img | ||||
|                                 [ class "image icon" | ||||
|                                 , src (model.flags.config.docspellAssetPath ++ "/img/logo-mc-96.png") | ||||
|                                 ] | ||||
|                                 [] | ||||
|                             , text "Items" | ||||
|                             ] | ||||
|                         , div [ class "divider" ] [] | ||||
|                         , menuEntry model | ||||
|                             ManageDataPage | ||||
|                             [ i [ class "cubes icon" ] [] | ||||
|                             , text "Manage Data" | ||||
|                             ] | ||||
|                         , div [ class "divider" ] [] | ||||
|                         , menuEntry model | ||||
|                             (UploadPage Nothing) | ||||
|                             [ i [ class "upload icon" ] [] | ||||
|                             , text "Upload files" | ||||
|                             ] | ||||
|                         , menuEntry model | ||||
|                             QueuePage | ||||
|                             [ i [ class "tachometer alternate icon" ] [] | ||||
|                             , text "Processing Queue" | ||||
|                             ] | ||||
|                         , div | ||||
|                             [ classList | ||||
|                                 [ ( "divider", True ) | ||||
|                                 , ( "invisible", model.flags.config.signupMode /= "invite" ) | ||||
|                                 ] | ||||
|                             ] | ||||
|                             [] | ||||
|                         , a | ||||
|                             [ classList | ||||
|                                 [ ( "icon item", True ) | ||||
|                                 , ( "invisible", model.flags.config.signupMode /= "invite" ) | ||||
|                                 ] | ||||
|                             , Page.href NewInvitePage | ||||
|                             ] | ||||
|                             [ i [ class "key icon" ] [] | ||||
|                             , text "New Invites" | ||||
|                             ] | ||||
|                         , div [ class "divider" ] [] | ||||
|                         , a | ||||
|                             [ class "item" | ||||
|                             , href "https://docspell.org/docs" | ||||
|                             , target "_new" | ||||
|                             , title "Opens https://docspell.org/docs" | ||||
|                             ] | ||||
|                             [ i [ class "help icon" ] [] | ||||
|                             , text "Help" | ||||
|                             , span [ class "ui right floated" ] | ||||
|                                 [ i [ class "external link icon" ] [] | ||||
|                                 ] | ||||
|                             ] | ||||
|                         ] | ||||
|                     ] | ||||
|                 ] | ||||
|  | ||||
|             Nothing -> | ||||
|                 [ a | ||||
|                     [ class "item" | ||||
|                     , Page.href (Page.loginPage model.page) | ||||
|                     ] | ||||
|                     [ text "Login" | ||||
|                     ] | ||||
|                 , a | ||||
|                     [ class "item" | ||||
|                     , Page.href RegisterPage | ||||
|                     ] | ||||
|                     [ text "Register" | ||||
|                     ] | ||||
|                 ] | ||||
|         ) | ||||
|  | ||||
|  | ||||
| footer : Model -> Html Msg | ||||
| footer model = | ||||
|     div [ class "ui footer" ] | ||||
|         [ div [ class "ui center aligned container" ] | ||||
|             [ a [ href "https://github.com/eikek/docspell" ] | ||||
|                 [ i [ class "ui github icon" ] [] | ||||
|                 ] | ||||
|             , span [] | ||||
|                 [ text "Docspell " | ||||
|                 , text model.version.version | ||||
|                 , text " (#" | ||||
|                 , String.left 8 model.version.gitCommit |> text | ||||
|                 , text ")" | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
| @@ -4,7 +4,6 @@ module Comp.AddressForm exposing | ||||
|     , emptyModel | ||||
|     , getAddress | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -109,52 +108,6 @@ update msg model = | ||||
|             ( { model | country = m1 }, Cmd.map CountryMsg c1 ) | ||||
|  | ||||
|  | ||||
| view : UiSettings -> Model -> Html Msg | ||||
| view settings model = | ||||
|     div [ class "ui form" ] | ||||
|         [ div | ||||
|             [ class "field" | ||||
|             ] | ||||
|             [ label [] [ text "Street" ] | ||||
|             , input | ||||
|                 [ type_ "text" | ||||
|                 , onInput SetStreet | ||||
|                 , placeholder "Street" | ||||
|                 , value model.street | ||||
|                 ] | ||||
|                 [] | ||||
|             ] | ||||
|         , div | ||||
|             [ class "field" | ||||
|             ] | ||||
|             [ label [] [ text "Zip Code" ] | ||||
|             , input | ||||
|                 [ type_ "text" | ||||
|                 , onInput SetZip | ||||
|                 , placeholder "Zip" | ||||
|                 , value model.zip | ||||
|                 ] | ||||
|                 [] | ||||
|             ] | ||||
|         , div | ||||
|             [ class "field" | ||||
|             ] | ||||
|             [ label [] [ text "City" ] | ||||
|             , input | ||||
|                 [ type_ "text" | ||||
|                 , onInput SetCity | ||||
|                 , placeholder "City" | ||||
|                 , value model.city | ||||
|                 ] | ||||
|                 [] | ||||
|             ] | ||||
|         , div [ class "field" ] | ||||
|             [ label [] [ text "Country" ] | ||||
|             , Html.map CountryMsg (Comp.Dropdown.view settings model.country) | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|   | ||||
| @@ -3,7 +3,6 @@ module Comp.AttachmentMeta exposing | ||||
|     , Msg | ||||
|     , init | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -62,161 +61,6 @@ update msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : Model -> Html Msg | ||||
| view model = | ||||
|     div [] | ||||
|         [ h3 [ class "ui header" ] | ||||
|             [ text "Extracted Meta Data" | ||||
|             ] | ||||
|         , case model.meta of | ||||
|             NotAvailable -> | ||||
|                 div [ class "ui active dimmer" ] | ||||
|                     [ div [ class "ui loader" ] | ||||
|                         [] | ||||
|                     ] | ||||
|  | ||||
|             Failure msg -> | ||||
|                 div [ class "ui error message" ] | ||||
|                     [ text msg | ||||
|                     ] | ||||
|  | ||||
|             Success data -> | ||||
|                 viewData data | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewData : AttachmentMeta -> Html Msg | ||||
| viewData meta = | ||||
|     div [] | ||||
|         [ div [ class "ui dividing header" ] | ||||
|             [ text "Content" | ||||
|             ] | ||||
|         , div [ class "extracted-text" ] | ||||
|             [ text meta.content | ||||
|             ] | ||||
|         , div [ class "ui dividing header" ] | ||||
|             [ text "Labels" | ||||
|             ] | ||||
|         , div [] | ||||
|             [ div [ class "ui horizontal list" ] | ||||
|                 (List.map renderLabelItem meta.labels) | ||||
|             ] | ||||
|         , div [ class "ui dividing header" ] | ||||
|             [ text "Proposals" | ||||
|             ] | ||||
|         , viewProposals meta.proposals | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewProposals : ItemProposals -> Html Msg | ||||
| viewProposals props = | ||||
|     let | ||||
|         mkItem n lbl = | ||||
|             div [ class "item" ] | ||||
|                 [ div [ class "ui label" ] | ||||
|                     [ text lbl.name | ||||
|                     , div [ class "detail" ] | ||||
|                         [ (String.fromInt (n + 1) ++ ".") | ||||
|                             |> text | ||||
|                         ] | ||||
|                     ] | ||||
|                 ] | ||||
|  | ||||
|         mkTimeItem ms = | ||||
|             div [ class "item" ] | ||||
|                 [ div [ class "ui label" ] | ||||
|                     [ Util.Time.formatDateShort ms |> text | ||||
|                     ] | ||||
|                 ] | ||||
|     in | ||||
|     div [] | ||||
|         [ div [ class "ui small header" ] | ||||
|             [ text "Correspondent Organization" | ||||
|             ] | ||||
|         , div [ class "ui horizontal list" ] | ||||
|             (List.indexedMap mkItem props.corrOrg) | ||||
|         , div [ class "ui small header" ] | ||||
|             [ text "Correspondent Person" | ||||
|             ] | ||||
|         , div [ class "ui horizontal list" ] | ||||
|             (List.indexedMap mkItem props.corrPerson) | ||||
|         , div [ class "ui small header" ] | ||||
|             [ text "Concerning Person" | ||||
|             ] | ||||
|         , div [ class "ui horizontal list" ] | ||||
|             (List.indexedMap mkItem props.concPerson) | ||||
|         , div [ class "ui small header" ] | ||||
|             [ text "Concerning Equipment" | ||||
|             ] | ||||
|         , div [ class "ui horizontal list" ] | ||||
|             (List.indexedMap mkItem props.concEquipment) | ||||
|         , div [ class "ui small header" ] | ||||
|             [ text "Item Date" | ||||
|             ] | ||||
|         , div [ class "ui horizontal list" ] | ||||
|             (List.map mkTimeItem props.itemDate) | ||||
|         , div [ class "ui small header" ] | ||||
|             [ text "Item Due Date" | ||||
|             ] | ||||
|         , div [ class "ui horizontal list" ] | ||||
|             (List.map mkTimeItem props.dueDate) | ||||
|         ] | ||||
|  | ||||
|  | ||||
| renderLabelItem : Label -> Html Msg | ||||
| renderLabelItem label = | ||||
|     div [ class "item" ] | ||||
|         [ renderLabel label | ||||
|         ] | ||||
|  | ||||
|  | ||||
| renderLabel : Label -> Html Msg | ||||
| renderLabel label = | ||||
|     let | ||||
|         icon = | ||||
|             case label.labelType of | ||||
|                 "organization" -> | ||||
|                     "factory icon" | ||||
|  | ||||
|                 "person" -> | ||||
|                     "user icon" | ||||
|  | ||||
|                 "location" -> | ||||
|                     "map marker icon" | ||||
|  | ||||
|                 "date" -> | ||||
|                     "calendar alternate icon" | ||||
|  | ||||
|                 "misc" -> | ||||
|                     "help icon" | ||||
|  | ||||
|                 "email" -> | ||||
|                     "at icon" | ||||
|  | ||||
|                 "website" -> | ||||
|                     "external alternate icon" | ||||
|  | ||||
|                 _ -> | ||||
|                     "tag icon" | ||||
|     in | ||||
|     div | ||||
|         [ class "ui basic label" | ||||
|         , title label.labelType | ||||
|         ] | ||||
|         [ i [ class icon ] [] | ||||
|         , text label.label | ||||
|         , div [ class "detail" ] | ||||
|             [ String.fromInt label.beginPos |> text | ||||
|             , text "-" | ||||
|             , String.fromInt label.endPos |> text | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| module Comp.BasicSizeField exposing | ||||
|     ( Msg | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -24,33 +23,6 @@ update msg = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : String -> BasicSize -> Html Msg | ||||
| view labelTxt current = | ||||
|     div [ class "grouped fields" ] | ||||
|         (label [] [ text labelTxt ] | ||||
|             :: List.map (makeField current) Data.BasicSize.all | ||||
|         ) | ||||
|  | ||||
|  | ||||
| makeField : BasicSize -> BasicSize -> Html Msg | ||||
| makeField current element = | ||||
|     div [ class "field" ] | ||||
|         [ div [ class "ui radio checkbox" ] | ||||
|             [ input | ||||
|                 [ type_ "radio" | ||||
|                 , checked (current == element) | ||||
|                 , onCheck (\_ -> Toggle element) | ||||
|                 ] | ||||
|                 [] | ||||
|             , label [] [ text (Data.BasicSize.label element) ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -4,7 +4,6 @@ module Comp.CalEventInput exposing | ||||
|     , init | ||||
|     , initDefault | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -127,153 +126,6 @@ update flags ev msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : String -> CalEvent -> Model -> Html Msg | ||||
| view extraClasses ev model = | ||||
|     let | ||||
|         yearLen = | ||||
|             Basics.max 4 (String.length ev.year) | ||||
|  | ||||
|         otherLen str = | ||||
|             Basics.max 2 (String.length str) | ||||
|     in | ||||
|     div | ||||
|         [ classList | ||||
|             [ ( extraClasses, True ) | ||||
|             ] | ||||
|         ] | ||||
|         [ div [ class "calevent-input" ] | ||||
|             [ div [] | ||||
|                 [ label [] [ text "Weekday" ] | ||||
|                 , input | ||||
|                     [ type_ "text" | ||||
|                     , class "time-input" | ||||
|                     , size | ||||
|                         (Maybe.map otherLen ev.weekday | ||||
|                             |> Maybe.withDefault 4 | ||||
|                         ) | ||||
|                     , Maybe.withDefault "" ev.weekday | ||||
|                         |> value | ||||
|                     , onInput SetWeekday | ||||
|                     ] | ||||
|                     [] | ||||
|                 ] | ||||
|             , div [] | ||||
|                 [ label [] [ text "Year" ] | ||||
|                 , input | ||||
|                     [ type_ "text" | ||||
|                     , class "time-input" | ||||
|                     , size yearLen | ||||
|                     , value ev.year | ||||
|                     , onInput SetYear | ||||
|                     ] | ||||
|                     [] | ||||
|                 ] | ||||
|             , div [ class "date separator" ] | ||||
|                 [ text "–" | ||||
|                 ] | ||||
|             , div [] | ||||
|                 [ label [] [ text "Month" ] | ||||
|                 , input | ||||
|                     [ type_ "text" | ||||
|                     , class "time-input" | ||||
|                     , size (otherLen ev.month) | ||||
|                     , value ev.month | ||||
|                     , onInput SetMonth | ||||
|                     ] | ||||
|                     [] | ||||
|                 ] | ||||
|             , div [ class "date separator" ] | ||||
|                 [ text "–" | ||||
|                 ] | ||||
|             , div [] | ||||
|                 [ label [] [ text "Day" ] | ||||
|                 , input | ||||
|                     [ type_ "text" | ||||
|                     , class "time-input" | ||||
|                     , size (otherLen ev.day) | ||||
|                     , value ev.day | ||||
|                     , onInput SetDay | ||||
|                     ] | ||||
|                     [] | ||||
|                 ] | ||||
|             , div [ class "datetime separator" ] | ||||
|                 [ text "  " | ||||
|                 ] | ||||
|             , div [] | ||||
|                 [ label [] [ text "Hour" ] | ||||
|                 , input | ||||
|                     [ type_ "text" | ||||
|                     , class "time-input" | ||||
|                     , size (otherLen ev.hour) | ||||
|                     , value ev.hour | ||||
|                     , onInput SetHour | ||||
|                     ] | ||||
|                     [] | ||||
|                 ] | ||||
|             , div [ class "time separator" ] | ||||
|                 [ text ":" | ||||
|                 ] | ||||
|             , div [] | ||||
|                 [ label [] [ text "Minute" ] | ||||
|                 , input | ||||
|                     [ type_ "text" | ||||
|                     , class "time-input" | ||||
|                     , size (otherLen ev.minute) | ||||
|                     , value ev.minute | ||||
|                     , onInput SetMinute | ||||
|                     ] | ||||
|                     [] | ||||
|                 ] | ||||
|             ] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui basic red pointing label", True ) | ||||
|                 , ( "hidden invisible", not (isCheckError model) ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ text "Error: " | ||||
|             , Maybe.map .message model.checkResult | ||||
|                 |> Maybe.withDefault "" | ||||
|                 |> text | ||||
|             ] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui  message", True ) | ||||
|                 , ( "hidden invisible" | ||||
|                   , model.checkResult == Nothing || isCheckError model | ||||
|                   ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ dl [] | ||||
|                 [ dt [] | ||||
|                     [ text "Schedule: " | ||||
|                     ] | ||||
|                 , dd [] | ||||
|                     [ code [] | ||||
|                         [ Maybe.andThen .event model.checkResult | ||||
|                             |> Maybe.withDefault "" | ||||
|                             |> text | ||||
|                         ] | ||||
|                     ] | ||||
|                 , dt [] | ||||
|                     [ text "Next: " | ||||
|                     ] | ||||
|                 , dd [] | ||||
|                     (Maybe.map .next model.checkResult | ||||
|                         |> Maybe.withDefault [] | ||||
|                         |> List.map Util.Time.formatDateTime | ||||
|                         |> List.map text | ||||
|                         |> List.intersperse (br [] []) | ||||
|                     ) | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -3,7 +3,6 @@ module Comp.ChangePasswordForm exposing | ||||
|     , Msg(..) | ||||
|     , emptyModel | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -177,74 +176,6 @@ update flags msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : Model -> Html Msg | ||||
| view model = | ||||
|     div | ||||
|         [ classList | ||||
|             [ ( "ui form", True ) | ||||
|             , ( "error", List.isEmpty model.errors |> not ) | ||||
|             , ( "success", model.successMsg /= "" ) | ||||
|             ] | ||||
|         ] | ||||
|         [ div | ||||
|             [ classList | ||||
|                 [ ( "required field", True ) | ||||
|                 , ( "error", model.current == Nothing ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ label [] [ text "Current Password" ] | ||||
|             , Html.map SetCurrent (Comp.PasswordInput.view model.current model.currentModel) | ||||
|             ] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "required field", True ) | ||||
|                 , ( "error", model.newPass1 == Nothing ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ label [] [ text "New Password" ] | ||||
|             , Html.map SetNew1 (Comp.PasswordInput.view model.newPass1 model.pass1Model) | ||||
|             ] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "required field", True ) | ||||
|                 , ( "error", model.newPass2 == Nothing ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ label [] [ text "New Password (repeat)" ] | ||||
|             , Html.map SetNew2 (Comp.PasswordInput.view model.newPass2 model.pass2Model) | ||||
|             ] | ||||
|         , div [ class "ui horizontal divider" ] [] | ||||
|         , div [ class "ui success message" ] | ||||
|             [ text model.successMsg | ||||
|             ] | ||||
|         , div [ class "ui error message" ] | ||||
|             [ case model.errors of | ||||
|                 a :: [] -> | ||||
|                     text a | ||||
|  | ||||
|                 _ -> | ||||
|                     ul [ class "ui list" ] | ||||
|                         (List.map (\em -> li [] [ text em ]) model.errors) | ||||
|             ] | ||||
|         , div [ class "ui horizontal divider" ] [] | ||||
|         , button [ class "ui primary button", onClick Submit ] | ||||
|             [ text "Submit" | ||||
|             ] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui dimmer", True ) | ||||
|                 , ( "active", model.loading ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ div [ class "ui loader" ] [] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -4,7 +4,6 @@ module Comp.ClassifierSettingsForm exposing | ||||
|     , getSettings | ||||
|     , init | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -181,63 +180,6 @@ update flags msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : UiSettings -> Model -> Html Msg | ||||
| view settings model = | ||||
|     let | ||||
|         catListTypeItem = | ||||
|             Comp.FixedDropdown.Item | ||||
|                 model.categoryListType | ||||
|                 (Data.ListType.label model.categoryListType) | ||||
|     in | ||||
|     div [] | ||||
|         [ Markdown.toHtml [ class "ui basic segment" ] | ||||
|             """ | ||||
|  | ||||
| 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 "field" ] | ||||
|             [ label [] [ text "Is the following a blacklist or whitelist?" ] | ||||
|             , Html.map CategoryListTypeMsg | ||||
|                 (Comp.FixedDropdown.view (Just catListTypeItem) model.categoryListTypeModel) | ||||
|             ] | ||||
|         , div [ class "field" ] | ||||
|             [ label [] | ||||
|                 [ case model.categoryListType of | ||||
|                     Data.ListType.Whitelist -> | ||||
|                         text "Include tag categories for learning" | ||||
|  | ||||
|                     Data.ListType.Blacklist -> | ||||
|                         text "Exclude tag categories from learning" | ||||
|                 ] | ||||
|             , Html.map CategoryListMsg | ||||
|                 (Comp.Dropdown.view settings model.categoryListModel) | ||||
|             ] | ||||
|         , Html.map ItemCountMsg | ||||
|             (Comp.IntField.viewWithInfo | ||||
|                 "The maximum number of items to learn from, order by date newest first. Use 0 to mean all." | ||||
|                 model.itemCount | ||||
|                 "field" | ||||
|                 model.itemCountModel | ||||
|             ) | ||||
|         , div [ class "field" ] | ||||
|             [ label [] [ text "Schedule" ] | ||||
|             , Html.map ScheduleMsg | ||||
|                 (Comp.CalEventInput.view "" (Data.Validated.value model.schedule) model.scheduleModel) | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -4,7 +4,6 @@ module Comp.CollectiveSettingsForm exposing | ||||
|     , getSettings | ||||
|     , init | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -198,148 +197,6 @@ update flags msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : Flags -> UiSettings -> Model -> Html Msg | ||||
| view flags settings model = | ||||
|     div | ||||
|         [ classList | ||||
|             [ ( "ui form error success", True ) | ||||
|             , ( "error", Maybe.map .success model.fullTextReIndexResult == Just False ) | ||||
|             , ( "success", Maybe.map .success model.fullTextReIndexResult == Just True ) | ||||
|             ] | ||||
|         ] | ||||
|         [ h3 [ class "ui dividing header" ] | ||||
|             [ text "Document Language" | ||||
|             ] | ||||
|         , div [ class "field" ] | ||||
|             [ label [] [ text "Document Language" ] | ||||
|             , Html.map LangDropdownMsg (Comp.Dropdown.view settings model.langModel) | ||||
|             , span [ class "small-info" ] | ||||
|                 [ text "The language of your documents. This helps text recognition (OCR) and text analysis." | ||||
|                 ] | ||||
|             ] | ||||
|         , h3 | ||||
|             [ classList | ||||
|                 [ ( "ui dividing header", True ) | ||||
|                 , ( "invisible hidden", not flags.config.integrationEnabled ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ text "Integration Endpoint" | ||||
|             ] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "field", True ) | ||||
|                 , ( "invisible hidden", not flags.config.integrationEnabled ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ div [ class "ui checkbox" ] | ||||
|                 [ input | ||||
|                     [ type_ "checkbox" | ||||
|                     , onCheck (\_ -> ToggleIntegrationEndpoint) | ||||
|                     , checked model.intEnabled | ||||
|                     ] | ||||
|                     [] | ||||
|                 , label [] [ text "Enable integration endpoint" ] | ||||
|                 , span [ class "small-info" ] | ||||
|                     [ text "The integration endpoint allows (local) applications to submit files. " | ||||
|                     , text "You can choose to disable it for your collective." | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         , h3 | ||||
|             [ classList | ||||
|                 [ ( "ui dividing header", True ) | ||||
|                 , ( "invisible hidden", not flags.config.fullTextSearchEnabled ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ text "Full-Text Search" | ||||
|             ] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "inline field", True ) | ||||
|                 , ( "invisible hidden", not flags.config.fullTextSearchEnabled ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ div [ class "ui action input" ] | ||||
|                 [ input | ||||
|                     [ type_ "text" | ||||
|                     , value model.fullTextConfirmText | ||||
|                     , onInput SetFullTextConfirm | ||||
|                     ] | ||||
|                     [] | ||||
|                 , button | ||||
|                     [ class "ui primary right labeled icon button" | ||||
|                     , onClick TriggerReIndex | ||||
|                     ] | ||||
|                     [ i [ class "refresh icon" ] [] | ||||
|                     , text "Re-Index All Data" | ||||
|                     ] | ||||
|                 ] | ||||
|             , div [ class "small-info" ] | ||||
|                 [ text "This starts a task that clears the full-text index and re-indexes all your data again." | ||||
|                 , text "You must type OK before clicking the button to avoid accidental re-indexing." | ||||
|                 ] | ||||
|             , renderResultMessage model.fullTextReIndexResult | ||||
|             ] | ||||
|         , h3 | ||||
|             [ classList | ||||
|                 [ ( "ui dividing header", True ) | ||||
|                 , ( "invisible hidden", not flags.config.showClassificationSettings ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ text "Auto-Tagging" | ||||
|             ] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "field", True ) | ||||
|                 , ( "invisible hidden", not flags.config.showClassificationSettings ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ Html.map ClassifierSettingMsg | ||||
|                 (Comp.ClassifierSettingsForm.view settings model.classifierModel) | ||||
|             , div [ class "ui vertical segment" ] | ||||
|                 [ button | ||||
|                     [ class "ui small secondary basic button" | ||||
|                     , title "Starts a task to train a classifier" | ||||
|                     , onClick StartClassifierTask | ||||
|                     ] | ||||
|                     [ text "Start now" | ||||
|                     ] | ||||
|                 , renderResultMessage model.startClassifierResult | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "ui divider" ] [] | ||||
|         , button | ||||
|             [ classList | ||||
|                 [ ( "ui primary button", True ) | ||||
|                 , ( "disabled", getSettings model |> Data.Validated.isInvalid ) | ||||
|                 ] | ||||
|             , onClick SaveSettings | ||||
|             ] | ||||
|             [ text "Save" | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| renderResultMessage : Maybe BasicResult -> Html msg | ||||
| renderResultMessage result = | ||||
|     div | ||||
|         [ classList | ||||
|             [ ( "ui message", True ) | ||||
|             , ( "error", Maybe.map .success result == Just False ) | ||||
|             , ( "success", Maybe.map .success result == Just True ) | ||||
|             , ( "hidden invisible", result == Nothing ) | ||||
|             ] | ||||
|         ] | ||||
|         [ Maybe.map .message result | ||||
|             |> Maybe.withDefault "" | ||||
|             |> text | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -4,7 +4,6 @@ module Comp.ColorTagger exposing | ||||
|     , ViewOpts | ||||
|     , init | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -85,7 +84,7 @@ update msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
| type alias ViewOpts = | ||||
| @@ -95,88 +94,6 @@ type alias ViewOpts = | ||||
|     } | ||||
|  | ||||
|  | ||||
| view : FormData -> ViewOpts -> Model -> Html Msg | ||||
| view data opts model = | ||||
|     div [ class "field" ] | ||||
|         [ label [] [ text opts.label ] | ||||
|         , div [ class "inline field" ] | ||||
|             [ Html.map LeftMsg | ||||
|                 (Comp.FixedDropdown.viewString | ||||
|                     model.leftSelect | ||||
|                     model.leftDropdown | ||||
|                 ) | ||||
|             ] | ||||
|         , div [ class "field" ] | ||||
|             [ chooseColor | ||||
|                 (AddPair data) | ||||
|                 Data.Color.all | ||||
|                 Nothing | ||||
|             ] | ||||
|         , renderFormData opts data | ||||
|         , span | ||||
|             [ classList | ||||
|                 [ ( "small-info", True ) | ||||
|                 , ( "invisible hidden", opts.description == Nothing ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ Maybe.withDefault "" opts.description | ||||
|                 |> text | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| renderFormData : ViewOpts -> FormData -> Html Msg | ||||
| renderFormData opts data = | ||||
|     let | ||||
|         values = | ||||
|             Dict.toList data | ||||
|  | ||||
|         renderItem ( k, v ) = | ||||
|             div [ class "item" ] | ||||
|                 [ a | ||||
|                     [ class "link icon" | ||||
|                     , href "#" | ||||
|                     , onClick (DeleteItem data k) | ||||
|                     ] | ||||
|                     [ i [ class "trash icon" ] [] | ||||
|                     ] | ||||
|                 , a | ||||
|                     [ class "link icon" | ||||
|                     , href "#" | ||||
|                     , onClick (EditItem k v) | ||||
|                     ] | ||||
|                     [ i [ class "edit icon" ] [] | ||||
|                     ] | ||||
|                 , opts.renderItem ( k, v ) | ||||
|                 ] | ||||
|     in | ||||
|     div [ class "ui list" ] | ||||
|         (List.map renderItem values) | ||||
|  | ||||
|  | ||||
| chooseColor : (Color -> msg) -> List Color -> Maybe String -> Html msg | ||||
| chooseColor tagger colors mtext = | ||||
|     let | ||||
|         renderLabel color = | ||||
|             a | ||||
|                 [ class ("ui large label " ++ Data.Color.toString color) | ||||
|                 , href "#" | ||||
|                 , onClick (tagger color) | ||||
|                 ] | ||||
|                 [ Maybe.withDefault | ||||
|                     (Data.Color.toString color) | ||||
|                     mtext | ||||
|                     |> text | ||||
|                 ] | ||||
|     in | ||||
|     div [ class "ui labels" ] <| | ||||
|         List.map renderLabel colors | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
| view2 : FormData -> ViewOpts -> Model -> Html Msg | ||||
| view2 data opts model = | ||||
|     div [ class "flex flex-col" ] | ||||
|   | ||||
| @@ -4,8 +4,6 @@ module Comp.ContactField exposing | ||||
|     , emptyModel | ||||
|     , getContacts | ||||
|     , update | ||||
|     , view | ||||
|     , view1 | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -119,69 +117,6 @@ update msg model = | ||||
|             ) | ||||
|  | ||||
|  | ||||
| view : UiSettings -> Model -> Html Msg | ||||
| view settings model = | ||||
|     view1 settings False model | ||||
|  | ||||
|  | ||||
| view1 : UiSettings -> Bool -> Model -> Html Msg | ||||
| view1 _ compact model = | ||||
|     div [] | ||||
|         [ div [ classList [ ( "fields", not compact ) ] ] | ||||
|             [ div | ||||
|                 [ classList | ||||
|                     [ ( "field", True ) | ||||
|                     , ( "four wide", not compact ) | ||||
|                     ] | ||||
|                 ] | ||||
|                 [ Html.map TypeMsg | ||||
|                     (Comp.FixedDropdown.view | ||||
|                         (Maybe.map makeDropdownItem model.selectedKind) | ||||
|                         model.kind | ||||
|                     ) | ||||
|                 ] | ||||
|             , div | ||||
|                 [ classList | ||||
|                     [ ( "twelve wide", not compact ) | ||||
|                     , ( "field", True ) | ||||
|                     ] | ||||
|                 ] | ||||
|                 [ div [ class "ui action input" ] | ||||
|                     [ input | ||||
|                         [ type_ "text" | ||||
|                         , onInput SetValue | ||||
|                         , value model.value | ||||
|                         ] | ||||
|                         [] | ||||
|                     , a [ class "ui button", onClick AddContact, href "#" ] | ||||
|                         [ text "Add" | ||||
|                         ] | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "field", True ) | ||||
|                 , ( "invisible", List.isEmpty model.items ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ div [ class "ui vertical secondary fluid menu" ] | ||||
|                 (List.map renderItem model.items) | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| renderItem : Contact -> Html Msg | ||||
| renderItem contact = | ||||
|     div [ class "link item", onClick (Select contact) ] | ||||
|         [ i [ class "delete icon" ] [] | ||||
|         , div [ class "ui blue label" ] | ||||
|             [ text contact.kind | ||||
|             ] | ||||
|         , text contact.value | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|   | ||||
| @@ -2,12 +2,10 @@ module Comp.CustomFieldForm exposing | ||||
|     ( Model | ||||
|     , Msg | ||||
|     , ViewSettings | ||||
|     , fullViewSettings | ||||
|     , init | ||||
|     , initEmpty | ||||
|     , makeField | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -195,122 +193,6 @@ type alias ViewSettings = | ||||
|     } | ||||
|  | ||||
|  | ||||
| fullViewSettings : ViewSettings | ||||
| fullViewSettings = | ||||
|     { classes = "ui error form segment" | ||||
|     , showControls = True | ||||
|     } | ||||
|  | ||||
|  | ||||
| view : ViewSettings -> Model -> Html Msg | ||||
| view viewSettings model = | ||||
|     let | ||||
|         mkItem cft = | ||||
|             Comp.FixedDropdown.Item cft (Data.CustomFieldType.label cft) | ||||
|     in | ||||
|     div [ class viewSettings.classes ] | ||||
|         ([ Html.map DeleteMsg (Comp.YesNoDimmer.view model.deleteDimmer) | ||||
|          , if model.field.id == "" then | ||||
|             div [] | ||||
|                 [ text "Create a new custom field." | ||||
|                 ] | ||||
|  | ||||
|            else | ||||
|             div [] | ||||
|                 [ text "Modify this custom field. Note that changing the format may " | ||||
|                 , text "result in invisible values in the ui, if they don't comply to the new format!" | ||||
|                 ] | ||||
|          , div | ||||
|             [ classList | ||||
|                 [ ( "ui message", True ) | ||||
|                 , ( "invisible hidden", model.result == Nothing ) | ||||
|                 , ( "error", Maybe.map .success model.result == Just False ) | ||||
|                 , ( "success", Maybe.map .success model.result == Just True ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ Maybe.map .message model.result | ||||
|                 |> Maybe.withDefault "" | ||||
|                 |> text | ||||
|             ] | ||||
|          , div [ class "required field" ] | ||||
|             [ label [] [ text "Name" ] | ||||
|             , input | ||||
|                 [ type_ "text" | ||||
|                 , onInput SetName | ||||
|                 , model.name | ||||
|                     |> Maybe.withDefault "" | ||||
|                     |> value | ||||
|                 ] | ||||
|                 [] | ||||
|             , div [ class "small-info" ] | ||||
|                 [ text "The name uniquely identifies this field. It must be a valid " | ||||
|                 , text "identifier, not contain spaces or weird characters." | ||||
|                 ] | ||||
|             ] | ||||
|          , div [ class "required field" ] | ||||
|             [ label [] [ text "Field Format" ] | ||||
|             , Html.map FTypeMsg | ||||
|                 (Comp.FixedDropdown.view | ||||
|                     (Maybe.map mkItem model.ftype) | ||||
|                     model.ftypeModel | ||||
|                 ) | ||||
|             , div [ class "small-info" ] | ||||
|                 [ text "A field must have a format. Values are validated " | ||||
|                 , text "according to this format." | ||||
|                 ] | ||||
|             ] | ||||
|          , div [ class "field" ] | ||||
|             [ label [] [ text "Label" ] | ||||
|             , input | ||||
|                 [ type_ "text" | ||||
|                 , onInput SetLabel | ||||
|                 , model.label | ||||
|                     |> Maybe.withDefault "" | ||||
|                     |> value | ||||
|                 ] | ||||
|                 [] | ||||
|             , div [ class "small-info" ] | ||||
|                 [ text "The user defined label for this field. This is used to represent " | ||||
|                 , text "this field in the ui. If not present, the name is used." | ||||
|                 ] | ||||
|             ] | ||||
|          ] | ||||
|             ++ (if viewSettings.showControls then | ||||
|                     viewButtons model | ||||
|  | ||||
|                 else | ||||
|                     [] | ||||
|                ) | ||||
|         ) | ||||
|  | ||||
|  | ||||
| viewButtons : Model -> List (Html Msg) | ||||
| viewButtons model = | ||||
|     [ div [ class "ui divider" ] [] | ||||
|     , button | ||||
|         [ class "ui primary button" | ||||
|         , onClick SubmitForm | ||||
|         ] | ||||
|         [ text "Submit" | ||||
|         ] | ||||
|     , button | ||||
|         [ class "ui button" | ||||
|         , onClick GoBack | ||||
|         ] | ||||
|         [ text "Back" | ||||
|         ] | ||||
|     , button | ||||
|         [ classList | ||||
|             [ ( "ui red button", True ) | ||||
|             , ( "invisible hidden", model.field.id == "" ) | ||||
|             ] | ||||
|         , onClick RequestDelete | ||||
|         ] | ||||
|         [ text "Delete" | ||||
|         ] | ||||
|     ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|   | ||||
| @@ -7,7 +7,6 @@ module Comp.CustomFieldInput exposing | ||||
|     , initWith | ||||
|     , update | ||||
|     , updateSearch | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -329,118 +328,6 @@ hasWildCards msg = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| removeButton : String -> Html Msg | ||||
| removeButton classes = | ||||
|     a | ||||
|         [ class "ui icon button" | ||||
|         , class classes | ||||
|         , href "#" | ||||
|         , title "Remove this value" | ||||
|         , onClick Remove | ||||
|         ] | ||||
|         [ i [ class "trash alternate outline icon" ] [] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| view : String -> Maybe String -> Model -> Html Msg | ||||
| view classes icon model = | ||||
|     let | ||||
|         error = | ||||
|             errorMsg model | ||||
|     in | ||||
|     div | ||||
|         [ class classes | ||||
|         , classList | ||||
|             [ ( "error", error /= Nothing ) | ||||
|             ] | ||||
|         ] | ||||
|         [ label [] | ||||
|             [ mkLabel model |> text | ||||
|             ] | ||||
|         , makeInput icon model | ||||
|         , div | ||||
|             [ class "ui red pointing basic label" | ||||
|             , classList | ||||
|                 [ ( "invisible hidden", error == Nothing ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ Maybe.withDefault "" error |> text | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| makeInput : Maybe String -> Model -> Html Msg | ||||
| makeInput icon model = | ||||
|     let | ||||
|         iconOr c = | ||||
|             Maybe.withDefault c icon | ||||
|     in | ||||
|     case model.fieldModel of | ||||
|         TextField v -> | ||||
|             div [ class "ui action left icon input" ] | ||||
|                 [ input | ||||
|                     [ type_ "text" | ||||
|                     , Maybe.withDefault "" v |> value | ||||
|                     , onInput SetText | ||||
|                     ] | ||||
|                     [] | ||||
|                 , removeButton "" | ||||
|                 , i [ class (iconOr <| Icons.customFieldType Data.CustomFieldType.Text) ] [] | ||||
|                 ] | ||||
|  | ||||
|         NumberField nm -> | ||||
|             div [ class "ui action left icon input" ] | ||||
|                 [ input | ||||
|                     [ type_ "text" | ||||
|                     , value nm.input | ||||
|                     , onInput NumberMsg | ||||
|                     ] | ||||
|                     [] | ||||
|                 , removeButton "" | ||||
|                 , i [ class (iconOr <| Icons.customFieldType Data.CustomFieldType.Numeric) ] [] | ||||
|                 ] | ||||
|  | ||||
|         MoneyField nm -> | ||||
|             div [ class "ui action left icon input" ] | ||||
|                 [ input | ||||
|                     [ type_ "text" | ||||
|                     , value nm.input | ||||
|                     , onInput MoneyMsg | ||||
|                     ] | ||||
|                     [] | ||||
|                 , removeButton "" | ||||
|                 , i [ class (iconOr <| Icons.customFieldType Data.CustomFieldType.Money) ] [] | ||||
|                 ] | ||||
|  | ||||
|         BoolField b -> | ||||
|             div [ class "ui container" ] | ||||
|                 [ div [ class "ui checkbox" ] | ||||
|                     [ input | ||||
|                         [ type_ "checkbox" | ||||
|                         , onCheck (\_ -> ToggleBool) | ||||
|                         , checked b | ||||
|                         ] | ||||
|                         [] | ||||
|                     , label [] | ||||
|                         [ text (mkLabel model) | ||||
|                         ] | ||||
|                     ] | ||||
|                 , removeButton "right floated" | ||||
|                 ] | ||||
|  | ||||
|         DateField v dp -> | ||||
|             div [ class "ui action left icon input" ] | ||||
|                 [ Html.map DateMsg | ||||
|                     (Comp.DatePicker.view v Comp.DatePicker.defaultSettings dp) | ||||
|                 , removeButton "" | ||||
|                 , i [ class (iconOr <| Icons.customFieldType Data.CustomFieldType.Date) ] [] | ||||
|                 ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -4,7 +4,6 @@ module Comp.CustomFieldManage exposing | ||||
|     , empty | ||||
|     , init | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -133,73 +132,6 @@ update flags msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : Flags -> Model -> Html Msg | ||||
| view flags model = | ||||
|     case model.detailModel of | ||||
|         Just dm -> | ||||
|             viewDetail flags dm | ||||
|  | ||||
|         Nothing -> | ||||
|             viewTable model | ||||
|  | ||||
|  | ||||
| viewDetail : Flags -> Comp.CustomFieldForm.Model -> Html Msg | ||||
| viewDetail flags detailModel = | ||||
|     let | ||||
|         viewSettings = | ||||
|             Comp.CustomFieldForm.fullViewSettings | ||||
|     in | ||||
|     div [] | ||||
|         [ Html.map DetailMsg (Comp.CustomFieldForm.view viewSettings detailModel) | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewTable : Model -> Html Msg | ||||
| viewTable model = | ||||
|     div [] | ||||
|         [ div [ class "ui secondary menu" ] | ||||
|             [ div [ class "horizontally fitted item" ] | ||||
|                 [ div [ class "ui icon input" ] | ||||
|                     [ input | ||||
|                         [ type_ "text" | ||||
|                         , onInput SetQuery | ||||
|                         , value model.query | ||||
|                         , placeholder "Search…" | ||||
|                         ] | ||||
|                         [] | ||||
|                     , i [ class "ui search icon" ] | ||||
|                         [] | ||||
|                     ] | ||||
|                 ] | ||||
|             , div [ class "right menu" ] | ||||
|                 [ div [ class "item" ] | ||||
|                     [ a | ||||
|                         [ class "ui primary button" | ||||
|                         , href "#" | ||||
|                         , onClick InitNewCustomField | ||||
|                         ] | ||||
|                         [ i [ class "plus icon" ] [] | ||||
|                         , text "New CustomField" | ||||
|                         ] | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         , Html.map TableMsg (Comp.CustomFieldTable.view model.tableModel model.fields) | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui dimmer", True ) | ||||
|                 , ( "active", model.loading ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ div [ class "ui loader" ] [] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
| @@ -217,15 +149,17 @@ viewDetail2 : Flags -> Comp.CustomFieldForm.Model -> Html Msg | ||||
| viewDetail2 _ detailModel = | ||||
|     let | ||||
|         viewSettings = | ||||
|             Comp.CustomFieldForm.fullViewSettings | ||||
|             { showControls = True | ||||
|             , classes = "" | ||||
|             } | ||||
|     in | ||||
|     div [] | ||||
|         ([ if detailModel.field.id == "" then | ||||
|         ((if detailModel.field.id == "" then | ||||
|             h3 [ class S.header2 ] | ||||
|                 [ text "Create new custom field" | ||||
|                 ] | ||||
|  | ||||
|            else | ||||
|           else | ||||
|             h3 [ class S.header2 ] | ||||
|                 [ Util.CustomField.nameOrLabel detailModel.field |> text | ||||
|                 , div [ class "opacity-50 text-sm" ] | ||||
| @@ -233,8 +167,8 @@ viewDetail2 _ detailModel = | ||||
|                     , text detailModel.field.id | ||||
|                     ] | ||||
|                 ] | ||||
|          ] | ||||
|             ++ List.map (Html.map DetailMsg) (Comp.CustomFieldForm.view2 viewSettings detailModel) | ||||
|          ) | ||||
|             :: List.map (Html.map DetailMsg) (Comp.CustomFieldForm.view2 viewSettings detailModel) | ||||
|         ) | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -12,7 +12,6 @@ module Comp.CustomFieldMultiInput exposing | ||||
|     , setValues | ||||
|     , update | ||||
|     , updateSearch | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -214,18 +213,9 @@ update1 forSearch flags msg model = | ||||
|                 fSelect = | ||||
|                     mkFieldSelect (currentOptions model.allFields visible) | ||||
|  | ||||
|                 -- have to re-state the open menu when this is invoked | ||||
|                 -- from a click in the dropdown | ||||
|                 -- this hack is only required for the semantic-ui version | ||||
|                 fSelectDropdown = | ||||
|                     fSelect.dropdown | ||||
|  | ||||
|                 dropdownOpen = | ||||
|                     { fSelectDropdown | menuOpen = flags.config.uiVersion /= 2 } | ||||
|  | ||||
|                 model_ = | ||||
|                     { model | ||||
|                         | fieldSelect = { fSelect | dropdown = dropdownOpen } | ||||
|                         | fieldSelect = fSelect | ||||
|                         , visibleFields = visible | ||||
|                     } | ||||
|  | ||||
| @@ -321,7 +311,7 @@ update1 forSearch flags msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
| type alias ViewSettings = | ||||
| @@ -331,76 +321,6 @@ type alias ViewSettings = | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : ViewSettings -> Model -> Html Msg | ||||
| view viewSettings model = | ||||
|     div [ class viewSettings.classes ] | ||||
|         (viewMenuBar viewSettings model | ||||
|             :: List.map (viewCustomField viewSettings model) (visibleFields model) | ||||
|         ) | ||||
|  | ||||
|  | ||||
| viewMenuBar : ViewSettings -> Model -> Html Msg | ||||
| viewMenuBar viewSettings model = | ||||
|     let | ||||
|         { dropdown, selected } = | ||||
|             model.fieldSelect | ||||
|     in | ||||
|     div | ||||
|         [ classList | ||||
|             [ ( "field", True ) | ||||
|             , ( "ui action input", viewSettings.showAddButton ) | ||||
|             ] | ||||
|         ] | ||||
|         (Html.map FieldSelectMsg | ||||
|             (Comp.FixedDropdown.viewStyled "fluid" (Maybe.map mkItem selected) dropdown) | ||||
|             :: (if viewSettings.showAddButton then | ||||
|                     [ addFieldLink "" model | ||||
|                     ] | ||||
|  | ||||
|                 else | ||||
|                     [] | ||||
|                ) | ||||
|         ) | ||||
|  | ||||
|  | ||||
| viewCustomField : ViewSettings -> Model -> CustomField -> Html Msg | ||||
| viewCustomField viewSettings model field = | ||||
|     let | ||||
|         visibleField = | ||||
|             Dict.get field.name model.visibleFields | ||||
|     in | ||||
|     case visibleField of | ||||
|         Just vf -> | ||||
|             Html.map (CustomFieldInputMsg field) | ||||
|                 (Comp.CustomFieldInput.view "field" | ||||
|                     (viewSettings.fieldIcon vf.field) | ||||
|                     vf.inputModel | ||||
|                 ) | ||||
|  | ||||
|         Nothing -> | ||||
|             span [] [] | ||||
|  | ||||
|  | ||||
| addFieldLink : String -> Model -> Html Msg | ||||
| addFieldLink classes _ = | ||||
|     a | ||||
|         [ class ("ui icon button " ++ classes) | ||||
|         , href "#" | ||||
|         , onClick CreateNewField | ||||
|         , title "Create a new custom field" | ||||
|         ] | ||||
|         [ i [ class "plus link icon" ] [] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
| view2 : DS.DropdownStyle -> ViewSettings -> Model -> Html Msg | ||||
| view2 ddstyle viewSettings model = | ||||
|     div [ class viewSettings.classes ] | ||||
|   | ||||
| @@ -4,7 +4,6 @@ module Comp.CustomFieldTable exposing | ||||
|     , Msg | ||||
|     , init | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -43,59 +42,6 @@ update msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : Model -> List CustomField -> Html Msg | ||||
| view _ items = | ||||
|     div [] | ||||
|         [ table [ class "ui very basic aligned table" ] | ||||
|             [ thead [] | ||||
|                 [ tr [] | ||||
|                     [ th [ class "collapsing" ] [] | ||||
|                     , th [] [ text "Name/Label" ] | ||||
|                     , th [] [ text "Format" ] | ||||
|                     , th [] [ text "#Usage" ] | ||||
|                     , th [] [ text "Created" ] | ||||
|                     ] | ||||
|                 ] | ||||
|             , tbody [] | ||||
|                 (List.map viewItem items) | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewItem : CustomField -> Html Msg | ||||
| viewItem item = | ||||
|     tr [] | ||||
|         [ td [ class "collapsing" ] | ||||
|             [ a | ||||
|                 [ href "#" | ||||
|                 , class "ui basic small blue label" | ||||
|                 , onClick (EditItem item) | ||||
|                 ] | ||||
|                 [ i [ class "edit icon" ] [] | ||||
|                 , text "Edit" | ||||
|                 ] | ||||
|             ] | ||||
|         , td [] | ||||
|             [ text <| Maybe.withDefault item.name item.label | ||||
|             ] | ||||
|         , td [] | ||||
|             [ text item.ftype | ||||
|             ] | ||||
|         , td [] | ||||
|             [ String.fromInt item.usages | ||||
|                 |> text | ||||
|             ] | ||||
|         , td [] | ||||
|             [ Util.Time.formatDateShort item.created | ||||
|                 |> text | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -1,4 +0,0 @@ | ||||
| module Comp.DateInput exposing (..) | ||||
|  | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| @@ -14,9 +14,7 @@ module Comp.DetailEdit exposing | ||||
|     , initTag | ||||
|     , initTagByName | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     , viewModal | ||||
|     , viewModal2 | ||||
|     ) | ||||
|  | ||||
| @@ -638,151 +636,6 @@ update flags msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| customFieldFormSettings : Comp.CustomFieldForm.ViewSettings | ||||
| customFieldFormSettings = | ||||
|     { classes = "ui error form" | ||||
|     , showControls = False | ||||
|     } | ||||
|  | ||||
|  | ||||
| viewButtons : Model -> List (Html Msg) | ||||
| viewButtons model = | ||||
|     [ button | ||||
|         [ class "ui primary button" | ||||
|         , href "#" | ||||
|         , onClick Submit | ||||
|         , disabled (model.submitting || model.loading) | ||||
|         ] | ||||
|         [ if model.submitting || model.loading then | ||||
|             i [ class "ui spinner loading icon" ] [] | ||||
|  | ||||
|           else | ||||
|             text "Submit" | ||||
|         ] | ||||
|     , button | ||||
|         [ class "ui button" | ||||
|         , href "#" | ||||
|         , onClick Cancel | ||||
|         ] | ||||
|         [ text "Cancel" | ||||
|         ] | ||||
|     ] | ||||
|  | ||||
|  | ||||
| viewIntern : UiSettings -> Bool -> Model -> List (Html Msg) | ||||
| viewIntern settings withButtons model = | ||||
|     [ div | ||||
|         [ classList | ||||
|             [ ( "ui message", True ) | ||||
|             , ( "error", Maybe.map .success model.result == Just False ) | ||||
|             , ( "success", Maybe.map .success model.result == Just True ) | ||||
|             , ( "invisible hidden", model.result == Nothing ) | ||||
|             ] | ||||
|         ] | ||||
|         [ Maybe.map .message model.result | ||||
|             |> Maybe.withDefault "" | ||||
|             |> text | ||||
|         ] | ||||
|     , case model.form of | ||||
|         TM tm -> | ||||
|             Html.map TagMsg (Comp.TagForm.view tm) | ||||
|  | ||||
|         PMR pm -> | ||||
|             Html.map PersonMsg (Comp.PersonForm.view1 settings True pm) | ||||
|  | ||||
|         PMC pm -> | ||||
|             Html.map PersonMsg (Comp.PersonForm.view1 settings True pm) | ||||
|  | ||||
|         OM om -> | ||||
|             Html.map OrgMsg (Comp.OrgForm.view1 settings True om) | ||||
|  | ||||
|         EM em -> | ||||
|             Html.map EquipMsg (Comp.EquipmentForm.view em) | ||||
|  | ||||
|         CFM fm -> | ||||
|             Html.map CustomFieldMsg (Comp.CustomFieldForm.view customFieldFormSettings fm) | ||||
|     ] | ||||
|         ++ (if withButtons then | ||||
|                 div [ class "ui divider" ] [] :: viewButtons model | ||||
|  | ||||
|             else | ||||
|                 [] | ||||
|            ) | ||||
|  | ||||
|  | ||||
| view : UiSettings -> Model -> Html Msg | ||||
| view settings model = | ||||
|     div [] | ||||
|         (viewIntern settings True model) | ||||
|  | ||||
|  | ||||
| viewModal : UiSettings -> Maybe Model -> Html Msg | ||||
| viewModal settings mm = | ||||
|     let | ||||
|         hidden = | ||||
|             mm == Nothing | ||||
|  | ||||
|         heading = | ||||
|             fold (\_ -> "Add Tag") | ||||
|                 (\_ -> "Add Person") | ||||
|                 (\_ -> "Add Organization") | ||||
|                 (\_ -> "Add Equipment") | ||||
|                 (\_ -> "Add Custom Field") | ||||
|  | ||||
|         headIcon = | ||||
|             fold (\_ -> Icons.tagIcon "") | ||||
|                 (\_ -> Icons.personIcon "") | ||||
|                 (\_ -> Icons.organizationIcon "") | ||||
|                 (\_ -> Icons.equipmentIcon "") | ||||
|                 (\_ -> Icons.customFieldIcon "") | ||||
|     in | ||||
|     div | ||||
|         [ classList | ||||
|             [ ( "ui inverted dimmer keep-small", True ) | ||||
|             , ( "invisibe hidden", hidden ) | ||||
|             , ( "active", not hidden ) | ||||
|             ] | ||||
|         , style "display" "flex !important" | ||||
|         ] | ||||
|         [ div | ||||
|             [ classList | ||||
|                 [ ( "ui modal keep-small", True ) | ||||
|                 , ( "active", not hidden ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ div [ class "header" ] | ||||
|                 [ Maybe.map .form mm | ||||
|                     |> Maybe.map headIcon | ||||
|                     |> Maybe.withDefault (i [] []) | ||||
|                 , Maybe.map .form mm | ||||
|                     |> Maybe.map heading | ||||
|                     |> Maybe.withDefault "" | ||||
|                     |> text | ||||
|                 ] | ||||
|             , div [ class "scrolling content" ] | ||||
|                 (case mm of | ||||
|                     Just model -> | ||||
|                         viewIntern settings False model | ||||
|  | ||||
|                     Nothing -> | ||||
|                         [] | ||||
|                 ) | ||||
|             , div [ class "actions" ] | ||||
|                 (case mm of | ||||
|                     Just model -> | ||||
|                         viewButtons model | ||||
|  | ||||
|                     Nothing -> | ||||
|                         [] | ||||
|                 ) | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
| @@ -900,10 +753,6 @@ viewButtons2 model = | ||||
|  | ||||
| viewIntern2 : UiSettings -> Bool -> Model -> List (Html Msg) | ||||
| viewIntern2 settings withButtons model = | ||||
|     let | ||||
|         viewSettings = | ||||
|             Comp.CustomFieldForm.fullViewSettings | ||||
|     in | ||||
|     [ div | ||||
|         [ classList | ||||
|             [ ( S.errorMessage, Maybe.map .success model.result == Just False ) | ||||
| @@ -935,7 +784,9 @@ viewIntern2 settings withButtons model = | ||||
|             div [] | ||||
|                 (List.map (Html.map CustomFieldMsg) | ||||
|                     (Comp.CustomFieldForm.view2 | ||||
|                         customFieldFormSettings | ||||
|                         { classes = "" | ||||
|                         , showControls = False | ||||
|                         } | ||||
|                         fm | ||||
|                     ) | ||||
|                 ) | ||||
|   | ||||
| @@ -13,9 +13,7 @@ module Comp.Dropdown exposing | ||||
|     , orgDropdown | ||||
|     , setMkOption | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     , viewSingle | ||||
|     , viewSingle2 | ||||
|     ) | ||||
|  | ||||
| @@ -462,178 +460,6 @@ update msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| -- View | ||||
|  | ||||
|  | ||||
| view : UiSettings -> Model a -> Html (Msg a) | ||||
| view settings model = | ||||
|     if model.multiple then | ||||
|         viewMultiple settings model | ||||
|  | ||||
|     else | ||||
|         viewSingle model | ||||
|  | ||||
|  | ||||
| viewSingle : Model a -> Html (Msg a) | ||||
| viewSingle model = | ||||
|     let | ||||
|         renderClosed item = | ||||
|             div | ||||
|                 [ class "message" | ||||
|                 , style "display" "inline-block !important" | ||||
|                 ] | ||||
|                 [ i | ||||
|                     [ class "delete icon" | ||||
|                     , onClick (RemoveItem item) | ||||
|                     ] | ||||
|                     [] | ||||
|                 , text item.option.text | ||||
|                 ] | ||||
|  | ||||
|         renderDefault = | ||||
|             [ List.head model.selected | ||||
|                 |> Maybe.map renderClosed | ||||
|                 |> Maybe.withDefault (renderPlaceholder model) | ||||
|             , renderMenu model | ||||
|             ] | ||||
|  | ||||
|         openSearch = | ||||
|             [ input | ||||
|                 [ class "search" | ||||
|                 , placeholder "Search…" | ||||
|                 , onInput Filter | ||||
|                 , value model.filterString | ||||
|                 ] | ||||
|                 [] | ||||
|             , renderMenu model | ||||
|             ] | ||||
|     in | ||||
|     div | ||||
|         (classList | ||||
|             [ ( "ui search dropdown selection", True ) | ||||
|             , ( "open", model.menuOpen ) | ||||
|             ] | ||||
|             :: (if model.menuOpen then | ||||
|                     [ tabindex 0 | ||||
|                     , onKeyUp KeyPress | ||||
|                     ] | ||||
|  | ||||
|                 else | ||||
|                     [ onClick ToggleMenu | ||||
|                     , tabindex 0 | ||||
|                     , onKeyUp KeyPress | ||||
|                     ] | ||||
|                ) | ||||
|         ) | ||||
|         (List.append | ||||
|             [ i | ||||
|                 (class "dropdown icon" | ||||
|                     :: (if model.menuOpen then | ||||
|                             [ onClick ToggleMenu ] | ||||
|  | ||||
|                         else | ||||
|                             [] | ||||
|                        ) | ||||
|                 ) | ||||
|                 [] | ||||
|             ] | ||||
|          <| | ||||
|             if model.menuOpen && isSearchable model then | ||||
|                 openSearch | ||||
|  | ||||
|             else | ||||
|                 renderDefault | ||||
|         ) | ||||
|  | ||||
|  | ||||
| viewMultiple : UiSettings -> Model a -> Html (Msg a) | ||||
| viewMultiple settings model = | ||||
|     let | ||||
|         renderSelectMultiple : Item a -> Html (Msg a) | ||||
|         renderSelectMultiple item = | ||||
|             div | ||||
|                 [ classList | ||||
|                     [ ( "ui label", True ) | ||||
|                     , ( model.labelColor item.value settings, True ) | ||||
|                     ] | ||||
|                 , style "display" "inline-block !important" | ||||
|                 , onClick (RemoveItem item) | ||||
|                 ] | ||||
|                 [ text item.option.text | ||||
|                 , i [ class "delete icon" ] [] | ||||
|                 ] | ||||
|     in | ||||
|     div | ||||
|         [ classList | ||||
|             [ ( "ui search dropdown multiple selection", True ) | ||||
|             , ( "open", model.menuOpen ) | ||||
|             ] | ||||
|         , tabindex 0 | ||||
|         , onKeyUp KeyPress | ||||
|         ] | ||||
|         (List.concat | ||||
|             [ [ i [ class "dropdown icon", onClick ToggleMenu ] [] | ||||
|               ] | ||||
|             , List.map renderSelectMultiple model.selected | ||||
|             , if isSearchable model then | ||||
|                 [ input | ||||
|                     [ class "search" | ||||
|                     , placeholder "Search…" | ||||
|                     , onInput Filter | ||||
|                     , value model.filterString | ||||
|                     ] | ||||
|                     [] | ||||
|                 ] | ||||
|  | ||||
|               else | ||||
|                 [] | ||||
|             , [ renderMenu model | ||||
|               ] | ||||
|             ] | ||||
|         ) | ||||
|  | ||||
|  | ||||
| renderMenu : Model a -> Html (Msg a) | ||||
| renderMenu model = | ||||
|     div | ||||
|         [ classList | ||||
|             [ ( "menu", True ) | ||||
|             , ( "transition visible", model.menuOpen ) | ||||
|             ] | ||||
|         ] | ||||
|         (getOptions model |> List.map renderOption) | ||||
|  | ||||
|  | ||||
| renderPlaceholder : Model a -> Html (Msg a) | ||||
| renderPlaceholder model = | ||||
|     div | ||||
|         [ classList | ||||
|             [ ( "placeholder-message", True ) | ||||
|             , ( "text", model.multiple ) | ||||
|             ] | ||||
|         , style "display" "inline-block !important" | ||||
|         ] | ||||
|         [ text model.placeholder | ||||
|         ] | ||||
|  | ||||
|  | ||||
| renderOption : Item a -> Html (Msg a) | ||||
| renderOption item = | ||||
|     div | ||||
|         [ classList | ||||
|             [ ( "item", True ) | ||||
|             , ( "active", item.active || item.selected ) | ||||
|             ] | ||||
|         , onClick (AddItem item) | ||||
|         ] | ||||
|         [ text item.option.text | ||||
|         , span [ class "small-info right-float" ] | ||||
|             [ text item.option.additional | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| -- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -9,7 +9,6 @@ module Comp.Dropzone exposing | ||||
|     , init | ||||
|     , setActive | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -108,42 +107,6 @@ update msg model = | ||||
|             ( { model | state = ns }, Cmd.none, newFiles ) | ||||
|  | ||||
|  | ||||
| view : Settings -> Model -> Html Msg | ||||
| view settings model = | ||||
|     div | ||||
|         [ classList (settings.classList model.state) | ||||
|         , onDragEnter DragEnter | ||||
|         , onDragOver DragEnter | ||||
|         , onDragLeave DragLeave | ||||
|         , onDropFiles GotFiles | ||||
|         ] | ||||
|         [ div [ class "ui icon header" ] | ||||
|             [ i [ class "mouse pointer icon" ] [] | ||||
|             , text "Drop files here" | ||||
|             ] | ||||
|         , div [ class "ui horizontal divider" ] | ||||
|             [ text "Or" | ||||
|             ] | ||||
|         , a | ||||
|             [ classList | ||||
|                 [ ( "ui basic primary button", True ) | ||||
|                 , ( "disabled", not model.state.active ) | ||||
|                 ] | ||||
|             , onClick PickFiles | ||||
|             , href "#" | ||||
|             ] | ||||
|             [ i [ class "folder open icon" ] [] | ||||
|             , text "Select ..." | ||||
|             ] | ||||
|         , div [ class "ui center aligned text container" ] | ||||
|             [ span [ class "small-info" ] | ||||
|                 [ text "Choose document files (pdf, docx, txt, html, …). " | ||||
|                 , text "Archives (zip and eml) are extracted." | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| filterMime : Model -> List File -> List File | ||||
| filterMime model files = | ||||
|     let | ||||
| @@ -157,6 +120,10 @@ filterMime model files = | ||||
|         List.filter pred files | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
| view2 : Model -> Html Msg | ||||
| view2 model = | ||||
|     div | ||||
|   | ||||
| @@ -3,13 +3,11 @@ module Comp.EmailInput exposing | ||||
|     , Msg | ||||
|     , init | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| import Api | ||||
| import Api.Model.ContactList exposing (ContactList) | ||||
| import Comp.Dropdown | ||||
| import Data.ContactType | ||||
| import Data.DropdownStyle as DS | ||||
| import Data.Flags exposing (Flags) | ||||
| @@ -136,69 +134,6 @@ update flags current msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : List String -> Model -> Html Msg | ||||
| view values model = | ||||
|     div | ||||
|         [ classList | ||||
|             [ ( "ui search dropdown multiple selection", True ) | ||||
|             , ( "open", model.menuOpen ) | ||||
|             ] | ||||
|         ] | ||||
|         (List.map renderValue values | ||||
|             ++ [ input | ||||
|                     [ type_ "text" | ||||
|                     , class "search long-search" | ||||
|                     , placeholder "Recipients…" | ||||
|                     , onKeyUp KeyPress | ||||
|                     , onInput SetInput | ||||
|                     , value model.input | ||||
|                     ] | ||||
|                     [] | ||||
|                , renderMenu model | ||||
|                ] | ||||
|         ) | ||||
|  | ||||
|  | ||||
| renderValue : String -> Html Msg | ||||
| renderValue str = | ||||
|     a | ||||
|         [ class "ui label" | ||||
|         , href "#" | ||||
|         , onClick (RemoveEmail str) | ||||
|         ] | ||||
|         [ text str | ||||
|         , i [ class "delete icon" ] [] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| renderMenu : Model -> Html Msg | ||||
| renderMenu model = | ||||
|     let | ||||
|         mkItem v = | ||||
|             a | ||||
|                 [ classList | ||||
|                     [ ( "item", True ) | ||||
|                     , ( "active", model.active == Just v ) | ||||
|                     ] | ||||
|                 , href "#" | ||||
|                 , onClick (AddEmail v) | ||||
|                 ] | ||||
|                 [ text v | ||||
|                 ] | ||||
|     in | ||||
|     div | ||||
|         [ classList | ||||
|             [ ( "menu", True ) | ||||
|             , ( "transition visible", model.menuOpen ) | ||||
|             ] | ||||
|         ] | ||||
|         (List.map mkItem model.candidates) | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -6,7 +6,6 @@ module Comp.EmailSettingsForm exposing | ||||
|     , init | ||||
|     , isValid | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -21,7 +20,7 @@ import Data.SSLType exposing (SSLType) | ||||
| import Data.UiSettings exposing (UiSettings) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onCheck, onInput) | ||||
| import Html.Events exposing (onInput) | ||||
| import Styles as S | ||||
| import Util.Maybe | ||||
|  | ||||
| @@ -182,109 +181,6 @@ update msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : UiSettings -> Model -> Html Msg | ||||
| view settings model = | ||||
|     div | ||||
|         [ classList | ||||
|             [ ( "ui form", True ) | ||||
|             , ( "error", not (isValid model) ) | ||||
|             , ( "success", isValid model ) | ||||
|             ] | ||||
|         ] | ||||
|         [ div [ class "required field" ] | ||||
|             [ label [] [ text "Name" ] | ||||
|             , input | ||||
|                 [ type_ "text" | ||||
|                 , value model.name | ||||
|                 , onInput SetName | ||||
|                 , placeholder "Connection name, e.g. 'gmail.com'" | ||||
|                 ] | ||||
|                 [] | ||||
|             , div [ class "ui info message" ] | ||||
|                 [ text "The connection name must not contain whitespace or special characters." | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "fields" ] | ||||
|             [ div [ class "thirteen wide required field" ] | ||||
|                 [ label [] [ text "SMTP Host" ] | ||||
|                 , input | ||||
|                     [ type_ "text" | ||||
|                     , placeholder "SMTP host name, e.g. 'mail.gmail.com'" | ||||
|                     , value model.host | ||||
|                     , onInput SetHost | ||||
|                     ] | ||||
|                     [] | ||||
|                 ] | ||||
|             , Html.map PortMsg | ||||
|                 (Comp.IntField.view model.portNum | ||||
|                     "three wide field" | ||||
|                     model.portField | ||||
|                 ) | ||||
|             ] | ||||
|         , div [ class "two fields" ] | ||||
|             [ div [ class "field" ] | ||||
|                 [ label [] [ text "SMTP User" ] | ||||
|                 , input | ||||
|                     [ type_ "text" | ||||
|                     , placeholder "SMTP Username, e.g. 'your.name@gmail.com'" | ||||
|                     , Maybe.withDefault "" model.user |> value | ||||
|                     , onInput SetUser | ||||
|                     ] | ||||
|                     [] | ||||
|                 ] | ||||
|             , div [ class "field" ] | ||||
|                 [ label [] [ text "SMTP Password" ] | ||||
|                 , Html.map PassMsg (Comp.PasswordInput.view model.password model.passField) | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "two fields" ] | ||||
|             [ div [ class "required field" ] | ||||
|                 [ label [] [ text "From Address" ] | ||||
|                 , input | ||||
|                     [ type_ "text" | ||||
|                     , placeholder "Sender E-Mail address" | ||||
|                     , value model.from | ||||
|                     , onInput SetFrom | ||||
|                     ] | ||||
|                     [] | ||||
|                 ] | ||||
|             , div [ class "field" ] | ||||
|                 [ label [] [ text "Reply-To" ] | ||||
|                 , input | ||||
|                     [ type_ "text" | ||||
|                     , placeholder "Optional reply-to E-Mail address" | ||||
|                     , Maybe.withDefault "" model.replyTo |> value | ||||
|                     , onInput SetReplyTo | ||||
|                     ] | ||||
|                     [] | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "two fields" ] | ||||
|             [ div [ class "inline field" ] | ||||
|                 [ div [ class "ui checkbox" ] | ||||
|                     [ input | ||||
|                         [ type_ "checkbox" | ||||
|                         , checked model.ignoreCertificates | ||||
|                         , onCheck (\_ -> ToggleCheckCert) | ||||
|                         ] | ||||
|                         [] | ||||
|                     , label [] [ text "Ignore certificate check" ] | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "two fields" ] | ||||
|             [ div [ class "field" ] | ||||
|                 [ label [] [ text "SSL" ] | ||||
|                 , Html.map SSLTypeMsg (Comp.Dropdown.view settings model.sslType) | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -4,7 +4,6 @@ module Comp.EmailSettingsManage exposing | ||||
|     , emptyModel | ||||
|     , init | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -21,7 +20,6 @@ import Data.Flags exposing (Flags) | ||||
| import Data.UiSettings exposing (UiSettings) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onClick, onInput) | ||||
| import Http | ||||
| import Styles as S | ||||
| import Util.Http | ||||
| @@ -205,99 +203,6 @@ update flags msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : UiSettings -> Model -> Html Msg | ||||
| view settings model = | ||||
|     case model.viewMode of | ||||
|         Table -> | ||||
|             viewTable model | ||||
|  | ||||
|         Form -> | ||||
|             viewForm settings model | ||||
|  | ||||
|  | ||||
| viewTable : Model -> Html Msg | ||||
| viewTable model = | ||||
|     div [] | ||||
|         [ div [ class "ui secondary menu" ] | ||||
|             [ div [ class "horizontally fitted item" ] | ||||
|                 [ div [ class "ui icon input" ] | ||||
|                     [ input | ||||
|                         [ type_ "text" | ||||
|                         , onInput SetQuery | ||||
|                         , value model.query | ||||
|                         , placeholder "Search…" | ||||
|                         ] | ||||
|                         [] | ||||
|                     , i [ class "ui search icon" ] | ||||
|                         [] | ||||
|                     ] | ||||
|                 ] | ||||
|             , div [ class "right menu" ] | ||||
|                 [ div [ class "item" ] | ||||
|                     [ a | ||||
|                         [ class "ui primary button" | ||||
|                         , href "#" | ||||
|                         , onClick InitNew | ||||
|                         ] | ||||
|                         [ i [ class "plus icon" ] [] | ||||
|                         , text "New Settings" | ||||
|                         ] | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         , Html.map TableMsg (Comp.EmailSettingsTable.view model.tableModel) | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewForm : UiSettings -> Model -> Html Msg | ||||
| viewForm settings model = | ||||
|     div [ class "ui segment" ] | ||||
|         [ Html.map YesNoMsg (Comp.YesNoDimmer.view model.deleteConfirm) | ||||
|         , Html.map FormMsg (Comp.EmailSettingsForm.view settings model.formModel) | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui error message", True ) | ||||
|                 , ( "invisible", model.formError == Nothing ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ Maybe.withDefault "" model.formError |> text | ||||
|             ] | ||||
|         , div [ class "ui divider" ] [] | ||||
|         , button | ||||
|             [ class "ui primary button" | ||||
|             , onClick Submit | ||||
|             , href "#" | ||||
|             ] | ||||
|             [ text "Submit" | ||||
|             ] | ||||
|         , a | ||||
|             [ class "ui secondary button" | ||||
|             , onClick (SetViewMode Table) | ||||
|             , href "#" | ||||
|             ] | ||||
|             [ text "Cancel" | ||||
|             ] | ||||
|         , if model.formModel.settings.name /= "" then | ||||
|             a [ class "ui right floated red button", href "#", onClick RequestDelete ] | ||||
|                 [ text "Delete" ] | ||||
|  | ||||
|           else | ||||
|             span [] [] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui dimmer", True ) | ||||
|                 , ( "active", model.loading ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ div [ class "ui loader" ] [] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -4,7 +4,6 @@ module Comp.EmailSettingsTable exposing | ||||
|     , emptyModel | ||||
|     , init | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -12,7 +11,6 @@ import Api.Model.EmailSettings exposing (EmailSettings) | ||||
| import Comp.Basic as B | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onClick) | ||||
| import Styles as S | ||||
|  | ||||
|  | ||||
| @@ -46,46 +44,6 @@ update msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : Model -> Html Msg | ||||
| view model = | ||||
|     table [ class "ui selectable pointer table" ] | ||||
|         [ thead [] | ||||
|             [ tr [] | ||||
|                 [ th [ class "collapsible" ] [ text "Name" ] | ||||
|                 , th [] [ text "Host/Port" ] | ||||
|                 , th [] [ text "From" ] | ||||
|                 ] | ||||
|             ] | ||||
|         , tbody [] | ||||
|             (List.map (renderLine model) model.emailSettings) | ||||
|         ] | ||||
|  | ||||
|  | ||||
| renderLine : Model -> EmailSettings -> Html Msg | ||||
| renderLine model ems = | ||||
|     let | ||||
|         hostport = | ||||
|             case ems.smtpPort of | ||||
|                 Just p -> | ||||
|                     ems.smtpHost ++ ":" ++ String.fromInt p | ||||
|  | ||||
|                 Nothing -> | ||||
|                     ems.smtpHost | ||||
|     in | ||||
|     tr | ||||
|         [ classList [ ( "active", model.selected == Just ems ) ] | ||||
|         , onClick (Select ems) | ||||
|         ] | ||||
|         [ td [ class "collapsible" ] [ text ems.name ] | ||||
|         , td [] [ text hostport ] | ||||
|         , td [] [ text ems.from ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -5,7 +5,6 @@ module Comp.EquipmentForm exposing | ||||
|     , getEquipment | ||||
|     , isValid | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -73,27 +72,6 @@ update _ msg model = | ||||
|             ( { model | notes = Util.Maybe.fromString str }, Cmd.none ) | ||||
|  | ||||
|  | ||||
| view : Model -> Html Msg | ||||
| view model = | ||||
|     div [ class "ui form" ] | ||||
|         [ div | ||||
|             [ classList | ||||
|                 [ ( "field", True ) | ||||
|                 , ( "error", not (isValid model) ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ label [] [ text "Name*" ] | ||||
|             , input | ||||
|                 [ type_ "text" | ||||
|                 , onInput SetName | ||||
|                 , placeholder "Name" | ||||
|                 , value model.name | ||||
|                 ] | ||||
|                 [] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|   | ||||
| @@ -3,7 +3,6 @@ module Comp.EquipmentManage exposing | ||||
|     , Msg(..) | ||||
|     , emptyModel | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -19,7 +18,7 @@ import Comp.YesNoDimmer | ||||
| import Data.Flags exposing (Flags) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onClick, onInput, onSubmit) | ||||
| import Html.Events exposing (onSubmit) | ||||
| import Http | ||||
| import Styles as S | ||||
| import Util.Http | ||||
| @@ -201,111 +200,6 @@ update flags msg model = | ||||
|             ( m, Api.getEquipments flags str EquipmentResp ) | ||||
|  | ||||
|  | ||||
| view : Model -> Html Msg | ||||
| view model = | ||||
|     if model.viewMode == Table then | ||||
|         viewTable model | ||||
|  | ||||
|     else | ||||
|         viewForm model | ||||
|  | ||||
|  | ||||
| viewTable : Model -> Html Msg | ||||
| viewTable model = | ||||
|     div [] | ||||
|         [ div [ class "ui secondary menu" ] | ||||
|             [ div [ class "horizontally fitted item" ] | ||||
|                 [ div [ class "ui icon input" ] | ||||
|                     [ input | ||||
|                         [ type_ "text" | ||||
|                         , onInput SetQuery | ||||
|                         , value model.query | ||||
|                         , placeholder "Search…" | ||||
|                         ] | ||||
|                         [] | ||||
|                     , i [ class "ui search icon" ] | ||||
|                         [] | ||||
|                     ] | ||||
|                 ] | ||||
|             , div [ class "right menu" ] | ||||
|                 [ div [ class "item" ] | ||||
|                     [ a | ||||
|                         [ class "ui primary button" | ||||
|                         , href "#" | ||||
|                         , onClick InitNewEquipment | ||||
|                         ] | ||||
|                         [ i [ class "plus icon" ] [] | ||||
|                         , text "New Equipment" | ||||
|                         ] | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         , Html.map TableMsg (Comp.EquipmentTable.view model.tableModel) | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui dimmer", True ) | ||||
|                 , ( "active", model.loading ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ div [ class "ui loader" ] [] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewForm : Model -> Html Msg | ||||
| viewForm model = | ||||
|     let | ||||
|         newEquipment = | ||||
|             model.formModel.equipment.id == "" | ||||
|     in | ||||
|     Html.form [ class "ui segment", onSubmit Submit ] | ||||
|         [ Html.map YesNoMsg (Comp.YesNoDimmer.view model.deleteConfirm) | ||||
|         , if newEquipment then | ||||
|             h3 [ class "ui dividing header" ] | ||||
|                 [ text "Create new equipment" | ||||
|                 ] | ||||
|  | ||||
|           else | ||||
|             h3 [ class "ui dividing header" ] | ||||
|                 [ text ("Edit equipment: " ++ model.formModel.equipment.name) | ||||
|                 , div [ class "sub header" ] | ||||
|                     [ text "Id: " | ||||
|                     , text model.formModel.equipment.id | ||||
|                     ] | ||||
|                 ] | ||||
|         , Html.map FormMsg (Comp.EquipmentForm.view model.formModel) | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui error message", True ) | ||||
|                 , ( "invisible", Util.Maybe.isEmpty model.formError ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ Maybe.withDefault "" model.formError |> text | ||||
|             ] | ||||
|         , div [ class "ui horizontal divider" ] [] | ||||
|         , button [ class "ui primary button", type_ "submit" ] | ||||
|             [ text "Submit" | ||||
|             ] | ||||
|         , a [ class "ui secondary button", onClick (SetViewMode Table), href "#" ] | ||||
|             [ text "Cancel" | ||||
|             ] | ||||
|         , if not newEquipment then | ||||
|             a [ class "ui right floated red button", href "#", onClick RequestDelete ] | ||||
|                 [ text "Delete" ] | ||||
|  | ||||
|           else | ||||
|             span [] [] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui dimmer", True ) | ||||
|                 , ( "active", model.loading ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ div [ class "ui loader" ] [] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|   | ||||
| @@ -3,7 +3,6 @@ module Comp.EquipmentTable exposing | ||||
|     , Msg(..) | ||||
|     , emptyModel | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -48,41 +47,6 @@ update _ msg model = | ||||
|             ( { model | selected = Nothing }, Cmd.none ) | ||||
|  | ||||
|  | ||||
| view : Model -> Html Msg | ||||
| view model = | ||||
|     table [ class "ui very basic aligned table" ] | ||||
|         [ thead [] | ||||
|             [ tr [] | ||||
|                 [ th [ class "collapsing" ] [] | ||||
|                 , th [] [ text "Name" ] | ||||
|                 ] | ||||
|             ] | ||||
|         , tbody [] | ||||
|             (List.map (renderEquipmentLine model) model.equips) | ||||
|         ] | ||||
|  | ||||
|  | ||||
| renderEquipmentLine : Model -> Equipment -> Html Msg | ||||
| renderEquipmentLine model equip = | ||||
|     tr | ||||
|         [ classList [ ( "active", model.selected == Just equip ) ] | ||||
|         ] | ||||
|         [ td [ class "collapsing" ] | ||||
|             [ a | ||||
|                 [ href "#" | ||||
|                 , class "ui basic small blue label" | ||||
|                 , onClick (Select equip) | ||||
|                 ] | ||||
|                 [ i [ class "edit icon" ] [] | ||||
|                 , text "Edit" | ||||
|                 ] | ||||
|             ] | ||||
|         , td [] | ||||
|             [ text equip.name | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|   | ||||
| @@ -2,7 +2,6 @@ module Comp.FieldListSelect exposing | ||||
|     ( Model | ||||
|     , Msg | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -10,7 +9,6 @@ import Comp.MenuBar as MB | ||||
| import Data.Fields exposing (Field) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onCheck) | ||||
|  | ||||
|  | ||||
| type alias Model = | ||||
| @@ -48,35 +46,6 @@ addField selected field = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : Model -> Html Msg | ||||
| view selected = | ||||
|     div [ class "grouped fields" ] | ||||
|         (List.map (fieldCheckbox selected) Data.Fields.all) | ||||
|  | ||||
|  | ||||
| fieldCheckbox : Model -> Field -> Html Msg | ||||
| fieldCheckbox selected field = | ||||
|     let | ||||
|         isChecked = | ||||
|             List.member field selected | ||||
|     in | ||||
|     div [ class "field" ] | ||||
|         [ div [ class "ui checkbox" ] | ||||
|             [ input | ||||
|                 [ type_ "checkbox" | ||||
|                 , checked isChecked | ||||
|                 , onCheck (\_ -> Toggle field) | ||||
|                 ] | ||||
|                 [] | ||||
|             , label [] [ text (Data.Fields.label field) ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -7,10 +7,7 @@ module Comp.FixedDropdown exposing | ||||
|     , initString | ||||
|     , initTuple | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     , viewString | ||||
|     , viewStyled | ||||
|     , viewStyled2 | ||||
|     ) | ||||
|  | ||||
| @@ -37,8 +34,7 @@ type alias Model a = | ||||
|  | ||||
|  | ||||
| type Msg a | ||||
|     = SelectItem (Item a) | ||||
|     | SelectItem2 (Item a) | ||||
|     = SelectItem2 (Item a) | ||||
|     | ToggleMenu | ||||
|     | KeyPress (Maybe KeyCode) | ||||
|  | ||||
| @@ -124,9 +120,6 @@ update msg model = | ||||
|         ToggleMenu -> | ||||
|             ( { model | menuOpen = not model.menuOpen }, Nothing ) | ||||
|  | ||||
|         SelectItem item -> | ||||
|             ( model, Just item.id ) | ||||
|  | ||||
|         SelectItem2 item -> | ||||
|             ( { model | menuOpen = False }, Just item.id ) | ||||
|  | ||||
| @@ -170,65 +163,6 @@ update msg model = | ||||
|             ( model, Nothing ) | ||||
|  | ||||
|  | ||||
| viewStyled : String -> Maybe (Item a) -> Model a -> Html (Msg a) | ||||
| viewStyled classes selected model = | ||||
|     div | ||||
|         [ classList | ||||
|             [ ( "ui selection dropdown", True ) | ||||
|             , ( classes, True ) | ||||
|             , ( "open", model.menuOpen ) | ||||
|             ] | ||||
|         , tabindex 0 | ||||
|         , onClick ToggleMenu | ||||
|         , onKeyUpCode KeyPress | ||||
|         ] | ||||
|         [ input [ type_ "hidden" ] [] | ||||
|         , i [ class "dropdown icon" ] [] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "default", selected == Nothing ) | ||||
|                 , ( "text", True ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ Maybe.map .display selected | ||||
|                 |> Maybe.withDefault "Select…" | ||||
|                 |> text | ||||
|             ] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "menu transition", True ) | ||||
|                 , ( "hidden", not model.menuOpen ) | ||||
|                 , ( "visible", model.menuOpen ) | ||||
|                 ] | ||||
|             ] | ||||
|           <| | ||||
|             List.map (renderItems model) model.options | ||||
|         ] | ||||
|  | ||||
|  | ||||
| view : Maybe (Item a) -> Model a -> Html (Msg a) | ||||
| view selected model = | ||||
|     viewStyled "" selected model | ||||
|  | ||||
|  | ||||
| viewString : Maybe String -> Model String -> Html (Msg String) | ||||
| viewString selected model = | ||||
|     view (Maybe.map (\s -> Item s s) selected) model | ||||
|  | ||||
|  | ||||
| renderItems : Model a -> Item a -> Html (Msg a) | ||||
| renderItems model item = | ||||
|     div | ||||
|         [ classList | ||||
|             [ ( "item", True ) | ||||
|             , ( "selected", isSelected model item ) | ||||
|             ] | ||||
|         , onClick (SelectItem item) | ||||
|         ] | ||||
|         [ text item.display | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|   | ||||
| @@ -4,7 +4,6 @@ module Comp.FolderDetail exposing | ||||
|     , init | ||||
|     , initEmpty | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -273,128 +272,7 @@ update flags msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : Flags -> Model -> Html Msg | ||||
| view flags model = | ||||
|     let | ||||
|         isOwner = | ||||
|             Maybe.map .user flags.account | ||||
|                 |> Maybe.map ((==) model.folder.owner.name) | ||||
|                 |> Maybe.withDefault False | ||||
|     in | ||||
|     div [] | ||||
|         ([ Html.map DeleteMsg (Comp.YesNoDimmer.view model.deleteDimmer) | ||||
|          , if model.folder.id == "" then | ||||
|             div [] | ||||
|                 [ text "Create a new folder. You are automatically set as owner of this new folder." | ||||
|                 ] | ||||
|  | ||||
|            else | ||||
|             div [] | ||||
|                 [ text "Modify this folder by changing the name or add/remove members." | ||||
|                 ] | ||||
|          , if model.folder.id /= "" && not isOwner then | ||||
|             div [ class "ui info message" ] | ||||
|                 [ text "You are not the owner of this folder and therefore are not allowed to edit it." | ||||
|                 ] | ||||
|  | ||||
|            else | ||||
|             div [] [] | ||||
|          , div | ||||
|             [ classList | ||||
|                 [ ( "ui message", True ) | ||||
|                 , ( "invisible hidden", model.result == Nothing ) | ||||
|                 , ( "error", Maybe.map .success model.result == Just False ) | ||||
|                 , ( "success", Maybe.map .success model.result == Just True ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ Maybe.map .message model.result | ||||
|                 |> Maybe.withDefault "" | ||||
|                 |> text | ||||
|             ] | ||||
|          , div [ class "ui header" ] | ||||
|             [ text "Owner" | ||||
|             ] | ||||
|          , div [ class "" ] | ||||
|             [ text model.folder.owner.name | ||||
|             ] | ||||
|          , div [ class "ui header" ] | ||||
|             [ text "Name" | ||||
|             ] | ||||
|          , div [ class "ui action input" ] | ||||
|             [ input | ||||
|                 [ type_ "text" | ||||
|                 , onInput SetName | ||||
|                 , Maybe.withDefault "" model.name | ||||
|                     |> value | ||||
|                 ] | ||||
|                 [] | ||||
|             , button | ||||
|                 [ class "ui icon button" | ||||
|                 , onClick SaveName | ||||
|                 ] | ||||
|                 [ i [ class "save icon" ] [] | ||||
|                 ] | ||||
|             ] | ||||
|          ] | ||||
|             ++ viewMembers model | ||||
|             ++ viewButtons model | ||||
|         ) | ||||
|  | ||||
|  | ||||
| viewButtons : Model -> List (Html Msg) | ||||
| viewButtons model = | ||||
|     [ div [ class "ui divider" ] [] | ||||
|     , button | ||||
|         [ class "ui button" | ||||
|         , onClick GoBack | ||||
|         ] | ||||
|         [ text "Back" | ||||
|         ] | ||||
|     , button | ||||
|         [ classList | ||||
|             [ ( "ui red button", True ) | ||||
|             , ( "invisible hidden", model.folder.id == "" ) | ||||
|             ] | ||||
|         , onClick RequestDelete | ||||
|         ] | ||||
|         [ text "Delete" | ||||
|         ] | ||||
|     ] | ||||
|  | ||||
|  | ||||
| viewMembers : Model -> List (Html Msg) | ||||
| viewMembers model = | ||||
|     if model.folder.id == "" then | ||||
|         [] | ||||
|  | ||||
|     else | ||||
|         [ div [ class "ui header" ] | ||||
|             [ text "Members" | ||||
|             ] | ||||
|         , div [ class "ui form" ] | ||||
|             [ div [ class "inline field" ] | ||||
|                 [ Html.map MemberDropdownMsg | ||||
|                     (Comp.FixedDropdown.view | ||||
|                         (Maybe.map makeItem model.selectedMember) | ||||
|                         model.memberDropdown | ||||
|                     ) | ||||
|                 , button | ||||
|                     [ class "ui primary button" | ||||
|                     , title "Add a new member" | ||||
|                     , onClick AddMember | ||||
|                     ] | ||||
|                     [ text "Add" | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         , div | ||||
|             [ class "ui list" | ||||
|             ] | ||||
|             (List.map viewMember model.members) | ||||
|         ] | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
| makeItem : IdName -> Comp.FixedDropdown.Item IdName | ||||
| @@ -402,29 +280,6 @@ makeItem idn = | ||||
|     Comp.FixedDropdown.Item idn idn.name | ||||
|  | ||||
|  | ||||
| viewMember : IdName -> Html Msg | ||||
| viewMember member = | ||||
|     div | ||||
|         [ class "item" | ||||
|         ] | ||||
|         [ a | ||||
|             [ class "link icon" | ||||
|             , href "#" | ||||
|             , title "Remove this member" | ||||
|             , onClick (RemoveMember member) | ||||
|             ] | ||||
|             [ i [ class "red trash icon" ] [] | ||||
|             ] | ||||
|         , span [] | ||||
|             [ text member.name | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
| view2 : Flags -> Model -> Html Msg | ||||
| view2 flags model = | ||||
|     let | ||||
|   | ||||
| @@ -4,7 +4,6 @@ module Comp.FolderManage exposing | ||||
|     , empty | ||||
|     , init | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -20,7 +19,6 @@ import Comp.MenuBar as MB | ||||
| import Data.Flags exposing (Flags) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onCheck, onClick, onInput) | ||||
| import Http | ||||
| import Styles as S | ||||
|  | ||||
| @@ -139,13 +137,13 @@ update flags msg model = | ||||
|         UserListResp (Ok ul) -> | ||||
|             ( { model | users = ul.items }, Cmd.none ) | ||||
|  | ||||
|         UserListResp (Err err) -> | ||||
|         UserListResp (Err _) -> | ||||
|             ( model, Cmd.none ) | ||||
|  | ||||
|         FolderListResp (Ok sl) -> | ||||
|             ( { model | folders = sl.items }, Cmd.none ) | ||||
|  | ||||
|         FolderListResp (Err err) -> | ||||
|         FolderListResp (Err _) -> | ||||
|             ( model, Cmd.none ) | ||||
|  | ||||
|         FolderDetailResp (Ok sd) -> | ||||
| @@ -153,7 +151,7 @@ update flags msg model = | ||||
|             , Cmd.none | ||||
|             ) | ||||
|  | ||||
|         FolderDetailResp (Err err) -> | ||||
|         FolderDetailResp (Err _) -> | ||||
|             ( model, Cmd.none ) | ||||
|  | ||||
|         InitNewFolder -> | ||||
| @@ -167,80 +165,6 @@ update flags msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : Flags -> Model -> Html Msg | ||||
| view flags model = | ||||
|     case model.detailModel of | ||||
|         Just dm -> | ||||
|             viewDetail flags dm | ||||
|  | ||||
|         Nothing -> | ||||
|             viewTable model | ||||
|  | ||||
|  | ||||
| viewDetail : Flags -> Comp.FolderDetail.Model -> Html Msg | ||||
| viewDetail flags detailModel = | ||||
|     div [] | ||||
|         [ Html.map DetailMsg (Comp.FolderDetail.view flags detailModel) | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewTable : Model -> Html Msg | ||||
| viewTable model = | ||||
|     div [] | ||||
|         [ div [ class "ui secondary menu" ] | ||||
|             [ div [ class "horizontally fitted item" ] | ||||
|                 [ div [ class "ui icon input" ] | ||||
|                     [ input | ||||
|                         [ type_ "text" | ||||
|                         , onInput SetQuery | ||||
|                         , value model.query | ||||
|                         , placeholder "Search…" | ||||
|                         ] | ||||
|                         [] | ||||
|                     , i [ class "ui search icon" ] | ||||
|                         [] | ||||
|                     ] | ||||
|                 ] | ||||
|             , div [ class "item" ] | ||||
|                 [ div [ class "ui checkbox" ] | ||||
|                     [ input | ||||
|                         [ type_ "checkbox" | ||||
|                         , onCheck (\_ -> ToggleOwningOnly) | ||||
|                         , checked model.owningOnly | ||||
|                         ] | ||||
|                         [] | ||||
|                     , label [] [ text "Show owning folders only" ] | ||||
|                     ] | ||||
|                 ] | ||||
|             , div [ class "right menu" ] | ||||
|                 [ div [ class "item" ] | ||||
|                     [ a | ||||
|                         [ class "ui primary button" | ||||
|                         , href "#" | ||||
|                         , onClick InitNewFolder | ||||
|                         ] | ||||
|                         [ i [ class "plus icon" ] [] | ||||
|                         , text "New Folder" | ||||
|                         ] | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         , Html.map TableMsg (Comp.FolderTable.view model.tableModel model.folders) | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui dimmer", True ) | ||||
|                 , ( "active", model.loading ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ div [ class "ui loader" ] [] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -7,8 +7,6 @@ module Comp.FolderSelect exposing | ||||
|     , setSelected | ||||
|     , update | ||||
|     , updateDrop | ||||
|     , view | ||||
|     , viewDrop | ||||
|     , viewDrop2 | ||||
|     ) | ||||
|  | ||||
| @@ -133,50 +131,7 @@ selectedFolder model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : Int -> Model -> Html Msg | ||||
| view = | ||||
|     viewDrop DD.init | ||||
|  | ||||
|  | ||||
| viewDrop : DD.Model -> Int -> Model -> Html Msg | ||||
| viewDrop dropModel constr model = | ||||
|     let | ||||
|         highlightDrop = | ||||
|             DD.getDropId dropModel == Just DD.FolderRemove | ||||
|     in | ||||
|     div [ class "ui list" ] | ||||
|         [ div [ class "item" ] | ||||
|             [ i [ class "folder open icon" ] [] | ||||
|             , div [ class "content" ] | ||||
|                 [ div | ||||
|                     (classList | ||||
|                         [ ( "header", True ) | ||||
|                         , ( "current-drop-target", highlightDrop ) | ||||
|                         ] | ||||
|                         :: DD.droppable FolderDDMsg DD.FolderRemove | ||||
|                     ) | ||||
|                     [ text "Folders" | ||||
|                     ] | ||||
|                 , div [ class "ui relaxed list" ] | ||||
|                     (renderItems dropModel constr model) | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| renderItems : DD.Model -> Int -> Model -> List (Html Msg) | ||||
| renderItems dropModel constr model = | ||||
|     if constr <= 0 then | ||||
|         List.map (viewItem dropModel model) model.all | ||||
|  | ||||
|     else if model.expanded then | ||||
|         List.map (viewItem dropModel model) model.all ++ collapseToggle constr model | ||||
|  | ||||
|     else | ||||
|         List.map (viewItem dropModel model) (List.take constr model.all) ++ expandToggle constr model | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
| expandToggle : Int -> Model -> List (Html Msg) | ||||
| @@ -195,49 +150,6 @@ collapseToggle max model = | ||||
|         ToggleExpand | ||||
|  | ||||
|  | ||||
| viewItem : DD.Model -> Model -> FolderStats -> Html Msg | ||||
| viewItem dropModel model item = | ||||
|     let | ||||
|         selected = | ||||
|             Just item.id == model.selected | ||||
|  | ||||
|         icon = | ||||
|             if selected then | ||||
|                 "folder outline open icon" | ||||
|  | ||||
|             else | ||||
|                 "folder outline icon" | ||||
|  | ||||
|         highlightDrop = | ||||
|             DD.getDropId dropModel == Just (DD.Folder item.id) | ||||
|     in | ||||
|     a | ||||
|         ([ classList | ||||
|             [ ( "item", True ) | ||||
|             , ( "active", selected ) | ||||
|             , ( "current-drop-target", highlightDrop ) | ||||
|             ] | ||||
|          , href "#" | ||||
|          , onClick (Toggle item) | ||||
|          ] | ||||
|             ++ DD.droppable FolderDDMsg (DD.Folder item.id) | ||||
|         ) | ||||
|         [ i [ class icon ] [] | ||||
|         , div [ class "content" ] | ||||
|             [ div [ class "description" ] | ||||
|                 [ text item.name | ||||
|                 , div [ class "ui right floated circular label" ] | ||||
|                     [ text (String.fromInt item.count) | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
| viewDrop2 : DD.Model -> Int -> Model -> Html Msg | ||||
| viewDrop2 dropModel constr model = | ||||
|     let | ||||
|   | ||||
| @@ -4,7 +4,6 @@ module Comp.FolderTable exposing | ||||
|     , Msg | ||||
|     , init | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -12,9 +11,7 @@ import Api.Model.FolderItem exposing (FolderItem) | ||||
| import Comp.Basic as B | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onClick) | ||||
| import Styles as S | ||||
| import Util.Html | ||||
| import Util.Time | ||||
|  | ||||
|  | ||||
| @@ -44,63 +41,6 @@ update msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : Model -> List FolderItem -> Html Msg | ||||
| view _ items = | ||||
|     div [] | ||||
|         [ table [ class "ui very basic aligned table" ] | ||||
|             [ thead [] | ||||
|                 [ tr [] | ||||
|                     [ th [ class "collapsing" ] [] | ||||
|                     , th [] [ text "Name" ] | ||||
|                     , th [] [ text "Owner" ] | ||||
|                     , th [ class "collapsing" ] [ text "Owner or Member" ] | ||||
|                     , th [ class "collapsing" ] [ text "#Member" ] | ||||
|                     , th [ class "collapsing" ] [ text "Created" ] | ||||
|                     ] | ||||
|                 ] | ||||
|             , tbody [] | ||||
|                 (List.map viewItem items) | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewItem : FolderItem -> Html Msg | ||||
| viewItem item = | ||||
|     tr [] | ||||
|         [ td [ class "collapsing" ] | ||||
|             [ a | ||||
|                 [ href "#" | ||||
|                 , class "ui basic small blue label" | ||||
|                 , onClick (EditItem item) | ||||
|                 ] | ||||
|                 [ i [ class "edit icon" ] [] | ||||
|                 , text "Edit" | ||||
|                 ] | ||||
|             ] | ||||
|         , td [] | ||||
|             [ text item.name | ||||
|             ] | ||||
|         , td [] | ||||
|             [ text item.owner.name | ||||
|             ] | ||||
|         , td [ class "center aligned" ] | ||||
|             [ Util.Html.checkbox item.isMember | ||||
|             ] | ||||
|         , td [ class "center aligned" ] | ||||
|             [ String.fromInt item.memberCount | ||||
|                 |> text | ||||
|             ] | ||||
|         , td [ class "center aligned" ] | ||||
|             [ Util.Time.formatDateShort item.created | ||||
|                 |> text | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -6,7 +6,6 @@ module Comp.ImapSettingsForm exposing | ||||
|     , init | ||||
|     , isValid | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -21,7 +20,7 @@ import Data.SSLType exposing (SSLType) | ||||
| import Data.UiSettings exposing (UiSettings) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onCheck, onInput) | ||||
| import Html.Events exposing (onInput) | ||||
| import Styles as S | ||||
| import Util.Maybe | ||||
|  | ||||
| @@ -174,98 +173,6 @@ update msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : UiSettings -> Model -> Html Msg | ||||
| view settings model = | ||||
|     div | ||||
|         [ classList | ||||
|             [ ( "ui form", True ) | ||||
|             , ( "info error", not (isValid model) ) | ||||
|             , ( "info success", isValid model ) | ||||
|             ] | ||||
|         ] | ||||
|         [ div [ class "required field" ] | ||||
|             [ label [] [ text "Name" ] | ||||
|             , input | ||||
|                 [ type_ "text" | ||||
|                 , value model.name | ||||
|                 , onInput SetName | ||||
|                 , placeholder "Connection name, e.g. 'gmail.com'" | ||||
|                 ] | ||||
|                 [] | ||||
|             , div [ class "ui info message" ] | ||||
|                 [ text "The connection name must not contain whitespace or special characters." | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "fields" ] | ||||
|             [ div [ class "thirteen wide required field" ] | ||||
|                 [ label [] [ text "IMAP Host" ] | ||||
|                 , input | ||||
|                     [ type_ "text" | ||||
|                     , placeholder "IMAP host name, e.g. 'mail.gmail.com'" | ||||
|                     , value model.host | ||||
|                     , onInput SetHost | ||||
|                     ] | ||||
|                     [] | ||||
|                 ] | ||||
|             , Html.map PortMsg | ||||
|                 (Comp.IntField.view model.portNum | ||||
|                     "three wide field" | ||||
|                     model.portField | ||||
|                 ) | ||||
|             ] | ||||
|         , div [ class "two fields" ] | ||||
|             [ div [ class "field" ] | ||||
|                 [ label [] [ text "IMAP User" ] | ||||
|                 , input | ||||
|                     [ type_ "text" | ||||
|                     , placeholder "IMAP Username, e.g. 'your.name@gmail.com'" | ||||
|                     , Maybe.withDefault "" model.user |> value | ||||
|                     , onInput SetUser | ||||
|                     ] | ||||
|                     [] | ||||
|                 ] | ||||
|             , div [ class "field" ] | ||||
|                 [ label [] [ text "IMAP Password" ] | ||||
|                 , Html.map PassMsg (Comp.PasswordInput.view model.password model.passField) | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "two fields" ] | ||||
|             [ div [ class "inline field" ] | ||||
|                 [ div [ class "ui checkbox" ] | ||||
|                     [ input | ||||
|                         [ type_ "checkbox" | ||||
|                         , checked model.ignoreCertificates | ||||
|                         , onCheck (\_ -> ToggleCheckCert) | ||||
|                         ] | ||||
|                         [] | ||||
|                     , label [] [ text "Ignore certificate check" ] | ||||
|                     ] | ||||
|                 ] | ||||
|             , div [ class "inline field" ] | ||||
|                 [ div [ class "ui checkbox" ] | ||||
|                     [ input | ||||
|                         [ type_ "checkbox" | ||||
|                         , checked model.useOAuthToken | ||||
|                         , onCheck (\_ -> ToggleUseOAuth) | ||||
|                         ] | ||||
|                         [] | ||||
|                     , label [] [ text "Enable OAuth2 authentication using the password as access token" ] | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "two fields" ] | ||||
|             [ div [ class "field" ] | ||||
|                 [ label [] [ text "SSL" ] | ||||
|                 , Html.map SSLTypeMsg (Comp.Dropdown.view settings model.sslType) | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -4,7 +4,6 @@ module Comp.ImapSettingsManage exposing | ||||
|     , emptyModel | ||||
|     , init | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -21,7 +20,6 @@ import Data.Flags exposing (Flags) | ||||
| import Data.UiSettings exposing (UiSettings) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onClick, onInput) | ||||
| import Http | ||||
| import Styles as S | ||||
| import Util.Http | ||||
| @@ -205,99 +203,6 @@ update flags msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : UiSettings -> Model -> Html Msg | ||||
| view settings model = | ||||
|     case model.viewMode of | ||||
|         Table -> | ||||
|             viewTable model | ||||
|  | ||||
|         Form -> | ||||
|             viewForm settings model | ||||
|  | ||||
|  | ||||
| viewTable : Model -> Html Msg | ||||
| viewTable model = | ||||
|     div [] | ||||
|         [ div [ class "ui secondary menu" ] | ||||
|             [ div [ class "horizontally fitted item" ] | ||||
|                 [ div [ class "ui icon input" ] | ||||
|                     [ input | ||||
|                         [ type_ "text" | ||||
|                         , onInput SetQuery | ||||
|                         , value model.query | ||||
|                         , placeholder "Search…" | ||||
|                         ] | ||||
|                         [] | ||||
|                     , i [ class "ui search icon" ] | ||||
|                         [] | ||||
|                     ] | ||||
|                 ] | ||||
|             , div [ class "right menu" ] | ||||
|                 [ div [ class "item" ] | ||||
|                     [ a | ||||
|                         [ class "ui primary button" | ||||
|                         , href "#" | ||||
|                         , onClick InitNew | ||||
|                         ] | ||||
|                         [ i [ class "plus icon" ] [] | ||||
|                         , text "New Settings" | ||||
|                         ] | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         , Html.map TableMsg (Comp.ImapSettingsTable.view model.tableModel) | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewForm : UiSettings -> Model -> Html Msg | ||||
| viewForm settings model = | ||||
|     div [ class "ui segment" ] | ||||
|         [ Html.map YesNoMsg (Comp.YesNoDimmer.view model.deleteConfirm) | ||||
|         , Html.map FormMsg (Comp.ImapSettingsForm.view settings model.formModel) | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui error message", True ) | ||||
|                 , ( "invisible", model.formError == Nothing ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ Maybe.withDefault "" model.formError |> text | ||||
|             ] | ||||
|         , div [ class "ui divider" ] [] | ||||
|         , button | ||||
|             [ class "ui primary button" | ||||
|             , onClick Submit | ||||
|             , href "#" | ||||
|             ] | ||||
|             [ text "Submit" | ||||
|             ] | ||||
|         , a | ||||
|             [ class "ui secondary button" | ||||
|             , onClick (SetViewMode Table) | ||||
|             , href "#" | ||||
|             ] | ||||
|             [ text "Cancel" | ||||
|             ] | ||||
|         , if model.formModel.settings.name /= "" then | ||||
|             a [ class "ui right floated red button", href "#", onClick RequestDelete ] | ||||
|                 [ text "Delete" ] | ||||
|  | ||||
|           else | ||||
|             span [] [] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui dimmer", True ) | ||||
|                 , ( "active", model.loading ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ div [ class "ui loader" ] [] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -4,7 +4,6 @@ module Comp.ImapSettingsTable exposing | ||||
|     , emptyModel | ||||
|     , init | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -12,7 +11,6 @@ import Api.Model.ImapSettings exposing (ImapSettings) | ||||
| import Comp.Basic as B | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onClick) | ||||
| import Styles as S | ||||
|  | ||||
|  | ||||
| @@ -46,44 +44,6 @@ update msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : Model -> Html Msg | ||||
| view model = | ||||
|     table [ class "ui selectable pointer table" ] | ||||
|         [ thead [] | ||||
|             [ tr [] | ||||
|                 [ th [ class "collapsible" ] [ text "Name" ] | ||||
|                 , th [] [ text "Host/Port" ] | ||||
|                 ] | ||||
|             ] | ||||
|         , tbody [] | ||||
|             (List.map (renderLine model) model.emailSettings) | ||||
|         ] | ||||
|  | ||||
|  | ||||
| renderLine : Model -> ImapSettings -> Html Msg | ||||
| renderLine model ems = | ||||
|     let | ||||
|         hostport = | ||||
|             case ems.imapPort of | ||||
|                 Just p -> | ||||
|                     ems.imapHost ++ ":" ++ String.fromInt p | ||||
|  | ||||
|                 Nothing -> | ||||
|                     ems.imapHost | ||||
|     in | ||||
|     tr | ||||
|         [ classList [ ( "active", model.selected == Just ems ) ] | ||||
|         , onClick (Select ems) | ||||
|         ] | ||||
|         [ td [ class "collapsible" ] [ text ems.name ] | ||||
|         , td [] [ text hostport ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -3,8 +3,6 @@ module Comp.IntField exposing | ||||
|     , Msg | ||||
|     , init | ||||
|     , update | ||||
|     , view | ||||
|     , viewWithInfo | ||||
|     , viewWithInfo2 | ||||
|     ) | ||||
|  | ||||
| @@ -96,47 +94,6 @@ update msg model = | ||||
|                         ) | ||||
|  | ||||
|  | ||||
| view : Maybe Int -> String -> Model -> Html Msg | ||||
| view = | ||||
|     viewWithInfo "" | ||||
|  | ||||
|  | ||||
| viewWithInfo : String -> Maybe Int -> String -> Model -> Html Msg | ||||
| viewWithInfo info nval classes model = | ||||
|     div | ||||
|         [ classList | ||||
|             [ ( classes, True ) | ||||
|             , ( "error", model.error /= Nothing ) | ||||
|             ] | ||||
|         ] | ||||
|         [ label [] [ text model.label ] | ||||
|         , input | ||||
|             [ type_ "text" | ||||
|             , Maybe.map String.fromInt nval | ||||
|                 |> Maybe.withDefault model.lastInput | ||||
|                 |> value | ||||
|             , onInput SetValue | ||||
|             ] | ||||
|             [] | ||||
|         , span | ||||
|             [ classList | ||||
|                 [ ( "small-info", True ) | ||||
|                 , ( "hidden invisible", info == "" ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ Markdown.toHtml [] info | ||||
|             ] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui pointing red basic label", True ) | ||||
|                 , ( "hidden", model.error == Nothing ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ Maybe.withDefault "" model.error |> text | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|   | ||||
| @@ -5,7 +5,6 @@ module Comp.ItemCard exposing | ||||
|     , ViewConfig | ||||
|     , init | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -137,425 +136,6 @@ update ddm msg model = | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : ViewConfig -> UiSettings -> Model -> ItemLight -> Html Msg | ||||
| view cfg settings model item = | ||||
|     let | ||||
|         isConfirmed = | ||||
|             item.state /= "created" | ||||
|  | ||||
|         cardColor = | ||||
|             if not isConfirmed then | ||||
|                 "blue" | ||||
|  | ||||
|             else | ||||
|                 "" | ||||
|  | ||||
|         fieldHidden f = | ||||
|             Data.UiSettings.fieldHidden settings f | ||||
|  | ||||
|         cardAction = | ||||
|             case cfg.selection of | ||||
|                 Data.ItemSelection.Inactive -> | ||||
|                     [ Page.href (ItemDetailPage item.id) | ||||
|                     ] | ||||
|  | ||||
|                 Data.ItemSelection.Active ids -> | ||||
|                     [ onClick (ToggleSelectItem ids item.id) | ||||
|                     , href "#" | ||||
|                     ] | ||||
|  | ||||
|         selectedDimmer = | ||||
|             div | ||||
|                 [ classList | ||||
|                     [ ( "ui light dimmer", True ) | ||||
|                     , ( "active", isSelected cfg item.id ) | ||||
|                     ] | ||||
|                 ] | ||||
|                 [ div [ class "content" ] | ||||
|                     [ a | ||||
|                         cardAction | ||||
|                         [ i [ class "huge icons purple" ] | ||||
|                             [ i [ class "big circle outline icon" ] [] | ||||
|                             , i [ class "check icon" ] [] | ||||
|                             ] | ||||
|                         ] | ||||
|                     ] | ||||
|                 ] | ||||
|     in | ||||
|     div | ||||
|         ([ classList | ||||
|             [ ( "ui fluid card", True ) | ||||
|             , ( cardColor, True ) | ||||
|             , ( cfg.extraClasses, True ) | ||||
|             ] | ||||
|          , id item.id | ||||
|          ] | ||||
|             ++ DD.draggable ItemDDMsg item.id | ||||
|         ) | ||||
|         ((if fieldHidden Data.Fields.PreviewImage then | ||||
|             [] | ||||
|  | ||||
|           else | ||||
|             [ selectedDimmer | ||||
|             , previewMenu settings model item (currentAttachment model item) | ||||
|             , previewImage settings cardAction model item | ||||
|             ] | ||||
|          ) | ||||
|             ++ [ mainContent cardAction cardColor isConfirmed settings cfg item | ||||
|                , notesContent settings item | ||||
|                , metaDataContent settings item | ||||
|                , fulltextResultsContent item | ||||
|                ] | ||||
|         ) | ||||
|  | ||||
|  | ||||
| fulltextResultsContent : ItemLight -> Html Msg | ||||
| fulltextResultsContent item = | ||||
|     div | ||||
|         [ classList | ||||
|             [ ( "content search-highlight", True ) | ||||
|             , ( "invisible hidden", item.highlighting == [] ) | ||||
|             ] | ||||
|         ] | ||||
|         [ div [ class "ui list" ] | ||||
|             (List.map renderHighlightEntry item.highlighting) | ||||
|         ] | ||||
|  | ||||
|  | ||||
| metaDataContent : UiSettings -> ItemLight -> Html Msg | ||||
| metaDataContent settings item = | ||||
|     let | ||||
|         fieldHidden f = | ||||
|             Data.UiSettings.fieldHidden settings f | ||||
|  | ||||
|         dueDate = | ||||
|             IT.render IT.dueDateShort item | ||||
|     in | ||||
|     div [ class "content" ] | ||||
|         [ div [ class "ui horizontal link list" ] | ||||
|             [ div | ||||
|                 [ classList | ||||
|                     [ ( "link item", True ) | ||||
|                     , ( "invisible hidden" | ||||
|                       , fieldHidden Data.Fields.CorrOrg | ||||
|                             && fieldHidden Data.Fields.CorrPerson | ||||
|                       ) | ||||
|                     ] | ||||
|                 , title "Correspondent" | ||||
|                 ] | ||||
|                 (Icons.correspondentIcon "" | ||||
|                     :: Comp.LinkTarget.makeCorrLink item [] SetLinkTarget | ||||
|                 ) | ||||
|             , div | ||||
|                 [ classList | ||||
|                     [ ( "item", True ) | ||||
|                     , ( "invisible hidden" | ||||
|                       , fieldHidden Data.Fields.ConcPerson | ||||
|                             && fieldHidden Data.Fields.ConcEquip | ||||
|                       ) | ||||
|                     ] | ||||
|                 , title "Concerning" | ||||
|                 ] | ||||
|                 (Icons.concernedIcon | ||||
|                     :: Comp.LinkTarget.makeConcLink item [] SetLinkTarget | ||||
|                 ) | ||||
|             , div | ||||
|                 [ classList | ||||
|                     [ ( "item", True ) | ||||
|                     , ( "invisible hidden", fieldHidden Data.Fields.Folder ) | ||||
|                     ] | ||||
|                 , title "Folder" | ||||
|                 ] | ||||
|                 [ Icons.folderIcon "" | ||||
|                 , Comp.LinkTarget.makeFolderLink item [] SetLinkTarget | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "right floated meta" ] | ||||
|             [ div [ class "ui horizontal link list" ] | ||||
|                 [ Comp.LinkTarget.makeSourceLink | ||||
|                     [ ( "item", True ) ] | ||||
|                     SetLinkTarget | ||||
|                     (IT.render IT.source item) | ||||
|                 , div | ||||
|                     [ classList | ||||
|                         [ ( "item", True ) | ||||
|                         , ( "invisible hidden" | ||||
|                           , item.dueDate | ||||
|                                 == Nothing | ||||
|                                 || fieldHidden Data.Fields.DueDate | ||||
|                           ) | ||||
|                         ] | ||||
|                     , title ("Due on " ++ dueDate) | ||||
|                     ] | ||||
|                     [ div | ||||
|                         [ class "ui basic grey label" | ||||
|                         ] | ||||
|                         [ Icons.dueDateIcon "" | ||||
|                         , text (" " ++ dueDate) | ||||
|                         ] | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| notesContent : UiSettings -> ItemLight -> Html Msg | ||||
| notesContent settings item = | ||||
|     div | ||||
|         [ classList | ||||
|             [ ( "content", True ) | ||||
|             , ( "invisible hidden" | ||||
|               , settings.itemSearchNoteLength | ||||
|                     <= 0 | ||||
|                     || Util.String.isNothingOrBlank item.notes | ||||
|               ) | ||||
|             ] | ||||
|         ] | ||||
|         [ span [ class "small-info" ] | ||||
|             [ Maybe.withDefault "" item.notes | ||||
|                 |> Util.String.ellipsis settings.itemSearchNoteLength | ||||
|                 |> text | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| mainContent : List (Attribute Msg) -> String -> Bool -> UiSettings -> ViewConfig -> ItemLight -> Html Msg | ||||
| mainContent cardAction cardColor isConfirmed settings _ item = | ||||
|     let | ||||
|         dirIcon = | ||||
|             i [ class (Data.Direction.iconFromMaybe item.direction) ] [] | ||||
|  | ||||
|         fieldHidden f = | ||||
|             Data.UiSettings.fieldHidden settings f | ||||
|  | ||||
|         titlePattern = | ||||
|             settings.cardTitleTemplate.template | ||||
|  | ||||
|         subtitlePattern = | ||||
|             settings.cardSubtitleTemplate.template | ||||
|     in | ||||
|     a | ||||
|         (class "content" :: cardAction) | ||||
|         [ if fieldHidden Data.Fields.Direction then | ||||
|             div [ class "header" ] | ||||
|                 [ IT.render titlePattern item |> text | ||||
|                 ] | ||||
|  | ||||
|           else | ||||
|             div | ||||
|                 [ class "header" | ||||
|                 , IT.render IT.direction item |> title | ||||
|                 ] | ||||
|                 [ dirIcon | ||||
|                 , IT.render titlePattern item |> text | ||||
|                 ] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui right corner label", True ) | ||||
|                 , ( cardColor, True ) | ||||
|                 , ( "invisible", isConfirmed ) | ||||
|                 ] | ||||
|             , title "New" | ||||
|             ] | ||||
|             [ i [ class "exclamation icon" ] [] | ||||
|             ] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "meta", True ) | ||||
|                 , ( "invisible hidden", fieldHidden Data.Fields.Date ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ IT.render subtitlePattern item |> text | ||||
|             ] | ||||
|         , div [ class "meta description" ] | ||||
|             [ mainTagsAndFields settings item | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| mainTagsAndFields : UiSettings -> ItemLight -> Html Msg | ||||
| mainTagsAndFields settings item = | ||||
|     let | ||||
|         fieldHidden f = | ||||
|             Data.UiSettings.fieldHidden settings f | ||||
|  | ||||
|         hideTags = | ||||
|             item.tags == [] || fieldHidden Data.Fields.Tag | ||||
|  | ||||
|         hideFields = | ||||
|             item.customfields == [] || fieldHidden Data.Fields.CustomFields | ||||
|  | ||||
|         showTag tag = | ||||
|             div | ||||
|                 [ classList | ||||
|                     [ ( "ui basic label", True ) | ||||
|                     , ( Data.UiSettings.tagColorString tag settings, True ) | ||||
|                     ] | ||||
|                 ] | ||||
|                 [ i [ class "tag icon" ] [] | ||||
|                 , div [ class "detail" ] | ||||
|                     [ text tag.name | ||||
|                     ] | ||||
|                 ] | ||||
|  | ||||
|         showField fv = | ||||
|             Util.CustomField.renderValue "ui basic label" fv | ||||
|  | ||||
|         renderFields = | ||||
|             if hideFields then | ||||
|                 [] | ||||
|  | ||||
|             else | ||||
|                 List.sortBy Util.CustomField.nameOrLabel item.customfields | ||||
|                     |> List.map showField | ||||
|  | ||||
|         renderTags = | ||||
|             if hideTags then | ||||
|                 [] | ||||
|  | ||||
|             else | ||||
|                 List.map showTag item.tags | ||||
|     in | ||||
|     div | ||||
|         [ classList | ||||
|             [ ( "ui right floated tiny labels", True ) | ||||
|             , ( "invisible hidden", hideTags && hideFields ) | ||||
|             ] | ||||
|         ] | ||||
|         (renderFields ++ renderTags) | ||||
|  | ||||
|  | ||||
| previewImage : UiSettings -> List (Attribute Msg) -> Model -> ItemLight -> Html Msg | ||||
| previewImage settings cardAction model item = | ||||
|     let | ||||
|         mainAttach = | ||||
|             currentAttachment model item | ||||
|  | ||||
|         previewUrl = | ||||
|             Maybe.map .id mainAttach | ||||
|                 |> Maybe.map Api.attachmentPreviewURL | ||||
|                 |> Maybe.withDefault (Api.itemBasePreviewURL item.id) | ||||
|     in | ||||
|     a | ||||
|         ([ class "image ds-card-image" | ||||
|          , Data.UiSettings.cardPreviewSize settings | ||||
|          ] | ||||
|             ++ cardAction | ||||
|         ) | ||||
|         [ img | ||||
|             [ class "preview-image" | ||||
|             , src previewUrl | ||||
|             , Data.UiSettings.cardPreviewSize settings | ||||
|             ] | ||||
|             [] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| previewMenu : UiSettings -> Model -> ItemLight -> Maybe AttachmentLight -> Html Msg | ||||
| previewMenu settings model item mainAttach = | ||||
|     let | ||||
|         pageCount = | ||||
|             Maybe.andThen .pageCount mainAttach | ||||
|                 |> Maybe.withDefault 0 | ||||
|  | ||||
|         mkAttachUrl id = | ||||
|             if settings.nativePdfPreview then | ||||
|                 Api.fileURL id | ||||
|  | ||||
|             else | ||||
|                 Api.fileURL id ++ "/view" | ||||
|  | ||||
|         attachUrl = | ||||
|             Maybe.map .id mainAttach | ||||
|                 |> Maybe.map mkAttachUrl | ||||
|                 |> Maybe.withDefault "/api/v1/sec/attachment/none" | ||||
|  | ||||
|         gotoFileBtn = | ||||
|             a | ||||
|                 [ class "ui compact basic icon button" | ||||
|                 , href attachUrl | ||||
|                 , target "_self" | ||||
|                 , title "Open attachment file" | ||||
|                 ] | ||||
|                 [ i [ class "eye icon" ] [] | ||||
|                 ] | ||||
|     in | ||||
|     if pageCount == 0 || (List.length item.attachments == 1 && pageCount == 1) then | ||||
|         div [ class "card-attachment-nav" ] | ||||
|             [ gotoFileBtn | ||||
|             ] | ||||
|  | ||||
|     else if List.length item.attachments == 1 then | ||||
|         div [ class "card-attachment-nav" ] | ||||
|             [ div [ class "ui small top attached basic icon buttons" ] | ||||
|                 [ gotoFileBtn | ||||
|                 ] | ||||
|             , div [ class "ui attached basic fitted center aligned blue segment" ] | ||||
|                 [ span | ||||
|                     [ title "Number of pages" | ||||
|                     ] | ||||
|                     [ text (String.fromInt pageCount) | ||||
|                     , text "p." | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|  | ||||
|     else | ||||
|         div [ class "card-attachment-nav" ] | ||||
|             [ div [ class "ui small top attached basic icon buttons" ] | ||||
|                 [ gotoFileBtn | ||||
|                 , a | ||||
|                     [ class "ui compact icon button" | ||||
|                     , href "#" | ||||
|                     , onClick (CyclePreview item) | ||||
|                     ] | ||||
|                     [ i [ class "arrow right icon" ] [] | ||||
|                     ] | ||||
|                 ] | ||||
|             , div [ class "ui attached basic blue fitted center aligned segment" ] | ||||
|                 [ currentPosition model item | ||||
|                     |> String.fromInt | ||||
|                     |> text | ||||
|                 , text "/" | ||||
|                 , text (List.length item.attachments |> String.fromInt) | ||||
|                 , text ", " | ||||
|                 , text (String.fromInt pageCount) | ||||
|                 , text "p." | ||||
|                 ] | ||||
|             ] | ||||
|  | ||||
|  | ||||
| renderHighlightEntry : HighlightEntry -> Html Msg | ||||
| renderHighlightEntry entry = | ||||
|     let | ||||
|         stripWhitespace str = | ||||
|             String.trim str | ||||
|                 |> String.replace "```" "" | ||||
|                 |> String.replace "\t" "  " | ||||
|                 |> String.replace "\n\n" "\n" | ||||
|                 |> String.lines | ||||
|                 |> List.map String.trim | ||||
|                 |> String.join "\n" | ||||
|     in | ||||
|     div [ class "item" ] | ||||
|         [ div [ class "content" ] | ||||
|             (div [ class "header" ] | ||||
|                 [ i [ class "caret right icon" ] [] | ||||
|                 , text (entry.name ++ ":") | ||||
|                 ] | ||||
|                 :: List.map | ||||
|                     (\str -> | ||||
|                         Markdown.toHtml [ class "description" ] <| | ||||
|                             (stripWhitespace str ++ "…") | ||||
|                     ) | ||||
|                     entry.lines | ||||
|             ) | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -7,7 +7,6 @@ module Comp.ItemCardList exposing | ||||
|     , prevItem | ||||
|     , update | ||||
|     , updateDrag | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -140,7 +139,7 @@ updateDrag dm _ msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
| type alias ViewConfig = | ||||
| @@ -149,56 +148,6 @@ type alias ViewConfig = | ||||
|     } | ||||
|  | ||||
|  | ||||
| view : ViewConfig -> UiSettings -> Model -> Html Msg | ||||
| view cfg settings model = | ||||
|     div | ||||
|         [ classList | ||||
|             [ ( "ui container", True ) | ||||
|             , ( "multi-select-mode", isMultiSelectMode cfg ) | ||||
|             ] | ||||
|         ] | ||||
|         (List.map (viewGroup model cfg settings) model.results.groups) | ||||
|  | ||||
|  | ||||
| viewGroup : Model -> ViewConfig -> UiSettings -> ItemLightGroup -> Html Msg | ||||
| viewGroup model cfg settings group = | ||||
|     div [ class "item-group" ] | ||||
|         [ div [ class "ui horizontal divider header item-list" ] | ||||
|             [ i [ class "calendar alternate outline icon" ] [] | ||||
|             , text group.name | ||||
|             ] | ||||
|         , div [ class "ui stackable three cards" ] | ||||
|             (List.map (viewItem model cfg settings) group.items) | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewItem : Model -> ViewConfig -> UiSettings -> ItemLight -> Html Msg | ||||
| viewItem model cfg settings item = | ||||
|     let | ||||
|         currentClass = | ||||
|             if cfg.current == Just item.id then | ||||
|                 "current" | ||||
|  | ||||
|             else | ||||
|                 "" | ||||
|  | ||||
|         vvcfg = | ||||
|             Comp.ItemCard.ViewConfig cfg.selection currentClass | ||||
|  | ||||
|         cardModel = | ||||
|             Dict.get item.id model.itemCards | ||||
|                 |> Maybe.withDefault Comp.ItemCard.init | ||||
|  | ||||
|         cardHtml = | ||||
|             Comp.ItemCard.view vvcfg settings cardModel item | ||||
|     in | ||||
|     Html.map (ItemCardMsg item) cardHtml | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
| view2 : ViewConfig -> UiSettings -> Model -> Html Msg | ||||
| view2 cfg settings model = | ||||
|     div | ||||
|   | ||||
| @@ -2,14 +2,12 @@ module Comp.ItemDetail exposing | ||||
|     ( Model | ||||
|     , emptyModel | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| import Browser.Navigation as Nav | ||||
| import Comp.ItemDetail.Model exposing (Msg(..), UpdateResult) | ||||
| import Comp.ItemDetail.Update | ||||
| import Comp.ItemDetail.View | ||||
| import Comp.ItemDetail.View2 | ||||
| import Data.Flags exposing (Flags) | ||||
| import Data.ItemNav exposing (ItemNav) | ||||
| @@ -32,11 +30,6 @@ update = | ||||
|     Comp.ItemDetail.Update.update | ||||
|  | ||||
|  | ||||
| view : ItemNav -> UiSettings -> Model -> Html Msg | ||||
| view = | ||||
|     Comp.ItemDetail.View.view | ||||
|  | ||||
|  | ||||
| view2 : ItemNav -> UiSettings -> Model -> Html Msg | ||||
| view2 = | ||||
|     Comp.ItemDetail.View2.view | ||||
|   | ||||
| @@ -1,181 +0,0 @@ | ||||
| module Comp.ItemDetail.AttachmentTabMenu exposing (view) | ||||
|  | ||||
| import Api | ||||
| import Api.Model.Attachment exposing (Attachment) | ||||
| import Comp.ItemDetail.Model exposing (Model, Msg(..)) | ||||
| import Comp.SentMails | ||||
| import Html exposing (Html, a, div, i, img, text) | ||||
| import Html.Attributes exposing (class, classList, href, src, title) | ||||
| import Html.Events exposing (onClick) | ||||
| import Html5.DragDrop as DD | ||||
| import Util.List | ||||
| import Util.Maybe | ||||
| import Util.String | ||||
|  | ||||
|  | ||||
| view : Model -> List (Html Msg) | ||||
| view model = | ||||
|     [ div [ class "ui top attached tabular menu" ] | ||||
|         (activeAttach model | ||||
|             :: selectMenu model | ||||
|             ++ sentMailsTab model | ||||
|         ) | ||||
|     , div | ||||
|         [ classList | ||||
|             [ ( "ui attached segment", model.attachMenuOpen ) | ||||
|             , ( "invisible hidden", not model.attachMenuOpen ) | ||||
|             ] | ||||
|         ] | ||||
|         [ div [ class "ui doubling small cards" ] | ||||
|             (List.indexedMap (menuItem model) model.item.attachments) | ||||
|         ] | ||||
|     ] | ||||
|  | ||||
|  | ||||
| activeAttach : Model -> Html Msg | ||||
| activeAttach model = | ||||
|     let | ||||
|         attachM = | ||||
|             Util.Maybe.or | ||||
|                 [ Util.List.get model.item.attachments model.visibleAttach | ||||
|                     |> Maybe.map (Tuple.pair model.visibleAttach) | ||||
|                 , List.head model.item.attachments | ||||
|                     |> Maybe.map (Tuple.pair 0) | ||||
|                 ] | ||||
|  | ||||
|         visible = | ||||
|             not model.sentMailsOpen | ||||
|     in | ||||
|     case attachM of | ||||
|         Just ( pos, attach ) -> | ||||
|             a | ||||
|                 ([ classList | ||||
|                     [ ( "active", visible ) | ||||
|                     , ( "item", True ) | ||||
|                     ] | ||||
|                  , title (Maybe.withDefault "No Name" attach.name) | ||||
|                  , href "#" | ||||
|                  ] | ||||
|                     ++ (if visible then | ||||
|                             [] | ||||
|  | ||||
|                         else | ||||
|                             [ onClick (SetActiveAttachment pos) ] | ||||
|                        ) | ||||
|                 ) | ||||
|                 [ Maybe.map (Util.String.ellipsis 30) attach.name | ||||
|                     |> Maybe.withDefault "No Name" | ||||
|                     |> text | ||||
|                 , a | ||||
|                     [ classList | ||||
|                         [ ( "right-tab-icon-link", True ) | ||||
|                         , ( "invisible hidden", not visible ) | ||||
|                         ] | ||||
|                     , href "#" | ||||
|                     , onClick (EditAttachNameStart attach.id) | ||||
|                     ] | ||||
|                     [ i [ class "grey edit link icon" ] [] | ||||
|                     ] | ||||
|                 ] | ||||
|  | ||||
|         Nothing -> | ||||
|             div [] [] | ||||
|  | ||||
|  | ||||
| selectMenu : Model -> List (Html Msg) | ||||
| selectMenu model = | ||||
|     case model.item.attachments of | ||||
|         [] -> | ||||
|             [] | ||||
|  | ||||
|         [ _ ] -> | ||||
|             [] | ||||
|  | ||||
|         _ -> | ||||
|             [ a | ||||
|                 [ class "ui dropdown item" | ||||
|                 , href "#" | ||||
|                 , onClick ToggleAttachMenu | ||||
|                 ] | ||||
|                 [ i | ||||
|                     [ classList | ||||
|                         [ ( "large ellipsis icon", True ) | ||||
|                         , ( "horizontal", not model.attachMenuOpen ) | ||||
|                         , ( "vertical", model.attachMenuOpen ) | ||||
|                         ] | ||||
|                     ] | ||||
|                     [] | ||||
|                 ] | ||||
|             ] | ||||
|  | ||||
|  | ||||
| menuItem : Model -> Int -> Attachment -> Html Msg | ||||
| menuItem model pos attach = | ||||
|     let | ||||
|         highlight = | ||||
|             let | ||||
|                 dropId = | ||||
|                     DD.getDropId model.attachDD | ||||
|  | ||||
|                 dragId = | ||||
|                     DD.getDragId model.attachDD | ||||
|  | ||||
|                 enable = | ||||
|                     Just attach.id == dropId && dropId /= dragId | ||||
|             in | ||||
|             [ ( "current-drop-target", enable ) | ||||
|             ] | ||||
|  | ||||
|         active = | ||||
|             model.visibleAttach == pos | ||||
|     in | ||||
|     a | ||||
|         ([ classList <| | ||||
|             [ ( "ui  card", True ) | ||||
|             , ( "blue", pos == 0 ) | ||||
|             ] | ||||
|                 ++ highlight | ||||
|          , href "#" | ||||
|          , onClick (SetActiveAttachment pos) | ||||
|          ] | ||||
|             ++ DD.draggable AttachDDMsg attach.id | ||||
|             ++ DD.droppable AttachDDMsg attach.id | ||||
|         ) | ||||
|         [ div | ||||
|             [ classList [ ( "invisible hidden", not active ) ] | ||||
|             , class "ui corner icon label" | ||||
|             ] | ||||
|             [ i [ class "check icon" ] [] | ||||
|             ] | ||||
|         , div [ class "image" ] | ||||
|             [ img | ||||
|                 [ src (Api.attachmentPreviewURL attach.id) | ||||
|                 ] | ||||
|                 [] | ||||
|             ] | ||||
|         , div [ class "content" ] | ||||
|             [ div [ class "description" ] | ||||
|                 [ Maybe.map (Util.String.ellipsis 60) attach.name | ||||
|                     |> Maybe.withDefault "No Name" | ||||
|                     |> text | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| sentMailsTab : Model -> List (Html Msg) | ||||
| sentMailsTab model = | ||||
|     if Comp.SentMails.isEmpty model.sentMails then | ||||
|         [] | ||||
|  | ||||
|     else | ||||
|         [ div | ||||
|             [ classList | ||||
|                 [ ( "right item", True ) | ||||
|                 , ( "active", model.sentMailsOpen ) | ||||
|                 ] | ||||
|             , onClick ToggleSentMails | ||||
|             ] | ||||
|             [ text "E-Mails" | ||||
|             ] | ||||
|         ] | ||||
| @@ -6,7 +6,6 @@ module Comp.ItemDetail.MultiEditMenu exposing | ||||
|     , init | ||||
|     , loadModel | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -626,257 +625,12 @@ type alias ViewConfig = | ||||
|  | ||||
| defaultViewConfig : ViewConfig | ||||
| defaultViewConfig = | ||||
|     { menuClass = "ui vertical segment" | ||||
|     { menuClass = "" | ||||
|     , nameState = SaveSuccess | ||||
|     , customFieldState = \_ -> SaveSuccess | ||||
|     } | ||||
|  | ||||
|  | ||||
| view : ViewConfig -> UiSettings -> Model -> Html Msg | ||||
| view = | ||||
|     renderEditForm | ||||
|  | ||||
|  | ||||
| renderEditForm : ViewConfig -> UiSettings -> Model -> Html Msg | ||||
| renderEditForm cfg settings model = | ||||
|     let | ||||
|         fieldVisible field = | ||||
|             Data.UiSettings.fieldVisible settings field | ||||
|  | ||||
|         optional fields html = | ||||
|             if | ||||
|                 List.map fieldVisible fields | ||||
|                     |> List.foldl (||) False | ||||
|             then | ||||
|                 html | ||||
|  | ||||
|             else | ||||
|                 span [ class "invisible hidden" ] [] | ||||
|  | ||||
|         tagModeIcon = | ||||
|             case model.tagEditMode of | ||||
|                 AddTags -> | ||||
|                     i [ class "grey plus link icon" ] [] | ||||
|  | ||||
|                 RemoveTags -> | ||||
|                     i [ class "grey eraser link icon" ] [] | ||||
|  | ||||
|                 ReplaceTags -> | ||||
|                     i [ class "grey redo alternate link icon" ] [] | ||||
|  | ||||
|         tagModeMsg = | ||||
|             case model.tagEditMode of | ||||
|                 AddTags -> | ||||
|                     "Tags chosen here are *added* to all selected items." | ||||
|  | ||||
|                 RemoveTags -> | ||||
|                     "Tags chosen here are *removed* from all selected items." | ||||
|  | ||||
|                 ReplaceTags -> | ||||
|                     "Tags chosen here *replace* those on selected items." | ||||
|  | ||||
|         customFieldIcon field = | ||||
|             case cfg.customFieldState field.id of | ||||
|                 SaveSuccess -> | ||||
|                     Nothing | ||||
|  | ||||
|                 SaveFailed -> | ||||
|                     Just "red exclamation triangle icon" | ||||
|  | ||||
|                 Saving -> | ||||
|                     Just "refresh loading icon" | ||||
|  | ||||
|         customFieldSettings = | ||||
|             Comp.CustomFieldMultiInput.ViewSettings | ||||
|                 False | ||||
|                 "field" | ||||
|                 customFieldIcon | ||||
|     in | ||||
|     div [ class cfg.menuClass ] | ||||
|         [ div [ class "ui form warning" ] | ||||
|             [ div [ class "field" ] | ||||
|                 [ div | ||||
|                     [ class "ui fluid buttons" | ||||
|                     ] | ||||
|                     [ button | ||||
|                         [ class "ui primary button" | ||||
|                         , onClick (ConfirmMsg True) | ||||
|                         ] | ||||
|                         [ text "Confirm" | ||||
|                         ] | ||||
|                     , div [ class "or" ] [] | ||||
|                     , button | ||||
|                         [ class "ui secondary button" | ||||
|                         , onClick (ConfirmMsg False) | ||||
|                         ] | ||||
|                         [ text "Unconfirm" | ||||
|                         ] | ||||
|                     ] | ||||
|                 ] | ||||
|             , optional [ Data.Fields.Tag ] <| | ||||
|                 div [ class "field" ] | ||||
|                     [ label [] | ||||
|                         [ Icons.tagsIcon "grey" | ||||
|                         , text "Tags" | ||||
|                         , a | ||||
|                             [ class "right-float" | ||||
|                             , href "#" | ||||
|                             , title "Change tag edit mode" | ||||
|                             , onClick ToggleTagEditMode | ||||
|                             ] | ||||
|                             [ tagModeIcon | ||||
|                             ] | ||||
|                         ] | ||||
|                     , Html.map TagDropdownMsg (Comp.Dropdown.view settings model.tagModel) | ||||
|                     , Markdown.toHtml [ class "small-info" ] tagModeMsg | ||||
|                     ] | ||||
|             , div [ class " field" ] | ||||
|                 [ label [] [ text "Name" ] | ||||
|                 , div [ class "ui icon input" ] | ||||
|                     [ input [ type_ "text", value model.nameModel, onInput SetName ] [] | ||||
|                     , i | ||||
|                         [ classList | ||||
|                             [ ( "green check icon", cfg.nameState == SaveSuccess ) | ||||
|                             , ( "red exclamation triangle icon", cfg.nameState == SaveFailed ) | ||||
|                             , ( "sync loading icon", cfg.nameState == Saving ) | ||||
|                             ] | ||||
|                         ] | ||||
|                         [] | ||||
|                     ] | ||||
|                 ] | ||||
|             , optional [ Data.Fields.Folder ] <| | ||||
|                 div [ class "field" ] | ||||
|                     [ label [] | ||||
|                         [ Icons.folderIcon "grey" | ||||
|                         , text "Folder" | ||||
|                         ] | ||||
|                     , Html.map FolderDropdownMsg (Comp.Dropdown.view settings model.folderModel) | ||||
|                     , div | ||||
|                         [ classList | ||||
|                             [ ( "ui warning message", True ) | ||||
|                             , ( "hidden", isFolderMember model ) | ||||
|                             ] | ||||
|                         ] | ||||
|                         [ Markdown.toHtml [] """ | ||||
| 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. | ||||
|                       """ | ||||
|                         ] | ||||
|                     ] | ||||
|             , optional [ Data.Fields.CustomFields ] <| | ||||
|                 h4 [ class "ui dividing header" ] | ||||
|                     [ Icons.customFieldIcon "" | ||||
|                     , text "Custom Fields" | ||||
|                     ] | ||||
|             , optional [ Data.Fields.CustomFields ] <| | ||||
|                 Html.map CustomFieldMsg | ||||
|                     (Comp.CustomFieldMultiInput.view customFieldSettings model.customFieldModel) | ||||
|             , optional [ Data.Fields.Date, Data.Fields.DueDate ] <| | ||||
|                 h4 [ class "ui dividing header" ] | ||||
|                     [ Icons.itemDatesIcon "" | ||||
|                     , text "Item Dates" | ||||
|                     ] | ||||
|             , optional [ Data.Fields.Date ] <| | ||||
|                 div [ class "field" ] | ||||
|                     [ label [] | ||||
|                         [ Icons.dateIcon "grey" | ||||
|                         , text "Date" | ||||
|                         ] | ||||
|                     , div [ class "ui left icon action input" ] | ||||
|                         [ Html.map ItemDatePickerMsg | ||||
|                             (Comp.DatePicker.viewTime | ||||
|                                 model.itemDate | ||||
|                                 actionInputDatePicker | ||||
|                                 model.itemDatePicker | ||||
|                             ) | ||||
|                         , a [ class "ui icon button", href "#", onClick RemoveDate ] | ||||
|                             [ i [ class "trash alternate outline icon" ] [] | ||||
|                             ] | ||||
|                         , Icons.dateIcon "" | ||||
|                         ] | ||||
|                     ] | ||||
|             , optional [ Data.Fields.DueDate ] <| | ||||
|                 div [ class " field" ] | ||||
|                     [ label [] | ||||
|                         [ Icons.dueDateIcon "grey" | ||||
|                         , text "Due Date" | ||||
|                         ] | ||||
|                     , div [ class "ui left icon action input" ] | ||||
|                         [ Html.map DueDatePickerMsg | ||||
|                             (Comp.DatePicker.viewTime | ||||
|                                 model.dueDate | ||||
|                                 actionInputDatePicker | ||||
|                                 model.dueDatePicker | ||||
|                             ) | ||||
|                         , a [ class "ui icon button", href "#", onClick RemoveDueDate ] | ||||
|                             [ i [ class "trash alternate outline icon" ] [] ] | ||||
|                         , Icons.dueDateIcon "" | ||||
|                         ] | ||||
|                     ] | ||||
|             , optional [ Data.Fields.CorrOrg, Data.Fields.CorrPerson ] <| | ||||
|                 h4 [ class "ui dividing header" ] | ||||
|                     [ Icons.correspondentIcon "" | ||||
|                     , text "Correspondent" | ||||
|                     ] | ||||
|             , optional [ Data.Fields.CorrOrg ] <| | ||||
|                 div [ class "field" ] | ||||
|                     [ label [] | ||||
|                         [ Icons.organizationIcon "grey" | ||||
|                         , text "Organization" | ||||
|                         ] | ||||
|                     , Html.map OrgDropdownMsg (Comp.Dropdown.view settings model.corrOrgModel) | ||||
|                     ] | ||||
|             , optional [ Data.Fields.CorrPerson ] <| | ||||
|                 div [ class "field" ] | ||||
|                     [ label [] | ||||
|                         [ Icons.personIcon "grey" | ||||
|                         , text "Person" | ||||
|                         ] | ||||
|                     , Html.map CorrPersonMsg (Comp.Dropdown.view settings model.corrPersonModel) | ||||
|                     ] | ||||
|             , optional [ Data.Fields.ConcPerson, Data.Fields.ConcEquip ] <| | ||||
|                 h4 [ class "ui dividing header" ] | ||||
|                     [ Icons.concernedIcon | ||||
|                     , text "Concerning" | ||||
|                     ] | ||||
|             , optional [ Data.Fields.ConcPerson ] <| | ||||
|                 div [ class "field" ] | ||||
|                     [ label [] | ||||
|                         [ Icons.personIcon "grey" | ||||
|                         , text "Person" | ||||
|                         ] | ||||
|                     , Html.map ConcPersonMsg (Comp.Dropdown.view settings model.concPersonModel) | ||||
|                     ] | ||||
|             , optional [ Data.Fields.ConcEquip ] <| | ||||
|                 div [ class "field" ] | ||||
|                     [ label [] | ||||
|                         [ Icons.equipmentIcon "grey" | ||||
|                         , text "Equipment" | ||||
|                         ] | ||||
|                     , Html.map ConcEquipMsg (Comp.Dropdown.view settings model.concEquipModel) | ||||
|                     ] | ||||
|             , optional [ Data.Fields.Direction ] <| | ||||
|                 div [ class "field" ] | ||||
|                     [ label [] | ||||
|                         [ Icons.directionIcon "grey" | ||||
|                         , text "Direction" | ||||
|                         ] | ||||
|                     , Html.map DirDropdownMsg (Comp.Dropdown.view settings model.directionModel) | ||||
|                     ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| actionInputDatePicker : DatePicker.Settings | ||||
| actionInputDatePicker = | ||||
|     let | ||||
|         ds = | ||||
|             Comp.DatePicker.defaultSettings | ||||
|     in | ||||
|     { ds | containerClassList = [ ( "ui action input", True ) ] } | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,285 +0,0 @@ | ||||
| module Comp.ItemList exposing | ||||
|     ( Model | ||||
|     , Msg(..) | ||||
|     , emptyModel | ||||
|     , nextItem | ||||
|     , prevItem | ||||
|     , update | ||||
|     , view | ||||
|     ) | ||||
|  | ||||
| import Api.Model.ItemLight exposing (ItemLight) | ||||
| import Api.Model.ItemLightGroup exposing (ItemLightGroup) | ||||
| import Api.Model.ItemLightList exposing (ItemLightList) | ||||
| import Data.Direction | ||||
| import Data.Flags exposing (Flags) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onClick) | ||||
| import Set exposing (Set) | ||||
| import Util.List | ||||
| import Util.Maybe | ||||
| import Util.String | ||||
| import Util.Time | ||||
|  | ||||
|  | ||||
| type alias Model = | ||||
|     { results : ItemLightList | ||||
|     , openGroups : Set String | ||||
|     } | ||||
|  | ||||
|  | ||||
| emptyModel : Model | ||||
| emptyModel = | ||||
|     { results = Api.Model.ItemLightList.empty | ||||
|     , openGroups = Set.empty | ||||
|     } | ||||
|  | ||||
|  | ||||
| type Msg | ||||
|     = SetResults ItemLightList | ||||
|     | ToggleGroupState ItemLightGroup | ||||
|     | CollapseAll | ||||
|     | ExpandAll | ||||
|     | SelectItem ItemLight | ||||
|  | ||||
|  | ||||
| nextItem : Model -> String -> Maybe ItemLight | ||||
| nextItem model id = | ||||
|     List.concatMap .items model.results.groups | ||||
|         |> Util.List.findNext (\i -> i.id == id) | ||||
|  | ||||
|  | ||||
| prevItem : Model -> String -> Maybe ItemLight | ||||
| prevItem model id = | ||||
|     List.concatMap .items model.results.groups | ||||
|         |> Util.List.findPrev (\i -> i.id == id) | ||||
|  | ||||
|  | ||||
| openAllGroups : Model -> Set String | ||||
| openAllGroups model = | ||||
|     List.foldl | ||||
|         (\g -> \set -> Set.insert g.name set) | ||||
|         model.openGroups | ||||
|         model.results.groups | ||||
|  | ||||
|  | ||||
| update : Flags -> Msg -> Model -> ( Model, Cmd Msg, Maybe ItemLight ) | ||||
| update _ msg model = | ||||
|     case msg of | ||||
|         SetResults list -> | ||||
|             let | ||||
|                 newModel = | ||||
|                     { model | results = list, openGroups = Set.empty } | ||||
|             in | ||||
|             ( { newModel | openGroups = openAllGroups newModel }, Cmd.none, Nothing ) | ||||
|  | ||||
|         ToggleGroupState group -> | ||||
|             let | ||||
|                 m2 = | ||||
|                     if isGroupOpen model group then | ||||
|                         closeGroup model group | ||||
|  | ||||
|                     else | ||||
|                         openGroup model group | ||||
|             in | ||||
|             ( m2, Cmd.none, Nothing ) | ||||
|  | ||||
|         CollapseAll -> | ||||
|             ( { model | openGroups = Set.empty }, Cmd.none, Nothing ) | ||||
|  | ||||
|         ExpandAll -> | ||||
|             let | ||||
|                 open = | ||||
|                     openAllGroups model | ||||
|             in | ||||
|             ( { model | openGroups = open }, Cmd.none, Nothing ) | ||||
|  | ||||
|         SelectItem item -> | ||||
|             ( model, Cmd.none, Just item ) | ||||
|  | ||||
|  | ||||
| view : Model -> Html Msg | ||||
| view model = | ||||
|     div [] | ||||
|         [ div [ class "ui ablue-comp menu" ] | ||||
|             [ div [ class "right floated menu" ] | ||||
|                 [ a | ||||
|                     [ class "item" | ||||
|                     , title "Expand all" | ||||
|                     , onClick ExpandAll | ||||
|                     , href "#" | ||||
|                     ] | ||||
|                     [ i [ class "double angle down icon" ] [] | ||||
|                     ] | ||||
|                 , a | ||||
|                     [ class "item" | ||||
|                     , title "Collapse all" | ||||
|                     , onClick CollapseAll | ||||
|                     , href "#" | ||||
|                     ] | ||||
|                     [ i [ class "double angle up icon" ] [] | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "ui middle aligned very relaxed divided basic list segment" ] | ||||
|             (List.map (viewGroup model) model.results.groups) | ||||
|         ] | ||||
|  | ||||
|  | ||||
| isGroupOpen : Model -> ItemLightGroup -> Bool | ||||
| isGroupOpen model group = | ||||
|     Set.member group.name model.openGroups | ||||
|  | ||||
|  | ||||
| openGroup : Model -> ItemLightGroup -> Model | ||||
| openGroup model group = | ||||
|     { model | openGroups = Set.insert group.name model.openGroups } | ||||
|  | ||||
|  | ||||
| closeGroup : Model -> ItemLightGroup -> Model | ||||
| closeGroup model group = | ||||
|     { model | openGroups = Set.remove group.name model.openGroups } | ||||
|  | ||||
|  | ||||
| viewGroup : Model -> ItemLightGroup -> Html Msg | ||||
| viewGroup model group = | ||||
|     let | ||||
|         groupOpen = | ||||
|             isGroupOpen model group | ||||
|  | ||||
|         children = | ||||
|             [ i | ||||
|                 [ classList | ||||
|                     [ ( "large middle aligned icon", True ) | ||||
|                     , ( "caret right", not groupOpen ) | ||||
|                     , ( "caret down", groupOpen ) | ||||
|                     ] | ||||
|                 ] | ||||
|                 [] | ||||
|             , div [ class "content" ] | ||||
|                 [ div [ class "right floated content" ] | ||||
|                     [ div [ class "ui blue label" ] | ||||
|                         [ List.length group.items |> String.fromInt |> text | ||||
|                         ] | ||||
|                     ] | ||||
|                 , a | ||||
|                     [ class "header" | ||||
|                     , onClick (ToggleGroupState group) | ||||
|                     , href "#" | ||||
|                     ] | ||||
|                     [ text group.name | ||||
|                     ] | ||||
|                 , div [ class "description" ] | ||||
|                     [ makeSummary group |> text | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|  | ||||
|         itemTable = | ||||
|             div [ class "ui basic content segment no-margin" ] | ||||
|                 [ renderItemTable model group.items | ||||
|                 ] | ||||
|     in | ||||
|     if isGroupOpen model group then | ||||
|         div [ class "item" ] | ||||
|             (List.append children [ itemTable ]) | ||||
|  | ||||
|     else | ||||
|         div [ class "item" ] | ||||
|             children | ||||
|  | ||||
|  | ||||
| renderItemTable : Model -> List ItemLight -> Html Msg | ||||
| renderItemTable model items = | ||||
|     table [ class "ui selectable padded table" ] | ||||
|         [ thead [] | ||||
|             [ tr [] | ||||
|                 [ th [ class "collapsing" ] [] | ||||
|                 , th [ class "collapsing" ] [ text "Name" ] | ||||
|                 , th [ class "collapsing" ] [ text "Date" ] | ||||
|                 , th [ class "collapsing" ] [ text "Source" ] | ||||
|                 , th [] [ text "Correspondent" ] | ||||
|                 , th [] [ text "Concerning" ] | ||||
|                 ] | ||||
|             ] | ||||
|         , tbody [] | ||||
|             (List.map (renderItemLine model) items) | ||||
|         ] | ||||
|  | ||||
|  | ||||
| renderItemLine : Model -> ItemLight -> Html Msg | ||||
| renderItemLine _ item = | ||||
|     let | ||||
|         dirIcon = | ||||
|             i [ class (Data.Direction.iconFromMaybe item.direction) ] [] | ||||
|  | ||||
|         corr = | ||||
|             List.filterMap identity [ item.corrOrg, item.corrPerson ] | ||||
|                 |> List.map .name | ||||
|                 |> List.intersperse ", " | ||||
|                 |> String.concat | ||||
|  | ||||
|         conc = | ||||
|             List.filterMap identity [ item.concPerson, item.concEquip ] | ||||
|                 |> List.map .name | ||||
|                 |> List.intersperse ", " | ||||
|                 |> String.concat | ||||
|     in | ||||
|     tr [ onClick (SelectItem item) ] | ||||
|         [ td [ class "collapsing" ] | ||||
|             [ div | ||||
|                 [ classList | ||||
|                     [ ( "ui teal ribbon label", True ) | ||||
|                     , ( "invisible", item.state /= "created" ) | ||||
|                     ] | ||||
|                 ] | ||||
|                 [ text "New" | ||||
|                 ] | ||||
|             ] | ||||
|         , td [ class "collapsing" ] | ||||
|             [ dirIcon | ||||
|             , Util.String.ellipsis 45 item.name |> text | ||||
|             ] | ||||
|         , td [ class "collapsing" ] | ||||
|             [ Util.Time.formatDateShort item.date |> text | ||||
|             , span | ||||
|                 [ classList | ||||
|                     [ ( "invisible", Util.Maybe.isEmpty item.dueDate ) | ||||
|                     ] | ||||
|                 ] | ||||
|                 [ text " " | ||||
|                 , div [ class "ui basic label" ] | ||||
|                     [ i [ class "bell icon" ] [] | ||||
|                     , Maybe.map Util.Time.formatDateShort item.dueDate |> Maybe.withDefault "" |> text | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         , td [ class "collapsing" ] [ text item.source ] | ||||
|         , td [] [ text corr ] | ||||
|         , td [] [ text conc ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| makeSummary : ItemLightGroup -> String | ||||
| makeSummary group = | ||||
|     let | ||||
|         corrOrgs = | ||||
|             List.filterMap .corrOrg group.items | ||||
|  | ||||
|         corrPers = | ||||
|             List.filterMap .corrPerson group.items | ||||
|  | ||||
|         concPers = | ||||
|             List.filterMap .concPerson group.items | ||||
|  | ||||
|         concEqui = | ||||
|             List.filterMap .concEquip group.items | ||||
|  | ||||
|         all = | ||||
|             List.concat [ corrOrgs, corrPers, concPers, concEqui ] | ||||
|     in | ||||
|     List.map .name all | ||||
|         |> Util.List.distinct | ||||
|         |> List.intersperse ", " | ||||
|         |> String.concat | ||||
| @@ -6,7 +6,6 @@ module Comp.ItemMail exposing | ||||
|     , emptyModel | ||||
|     , init | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -22,7 +21,7 @@ import Data.Flags exposing (Flags) | ||||
| import Data.UiSettings exposing (UiSettings) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onCheck, onClick, onInput) | ||||
| import Html.Events exposing (onClick, onInput) | ||||
| import Http | ||||
| import Styles as S | ||||
| import Util.Http | ||||
| @@ -222,89 +221,6 @@ isValid model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : UiSettings -> Model -> Html Msg | ||||
| view settings model = | ||||
|     div | ||||
|         [ classList | ||||
|             [ ( "ui form", True ) | ||||
|             , ( "error", model.formError /= Nothing ) | ||||
|             ] | ||||
|         ] | ||||
|         [ div [ class "field" ] | ||||
|             [ label [] [ text "Send via" ] | ||||
|             , Html.map ConnMsg (Comp.Dropdown.view settings model.connectionModel) | ||||
|             ] | ||||
|         , div [ class "ui error message" ] | ||||
|             [ Maybe.withDefault "" model.formError |> text | ||||
|             ] | ||||
|         , div [ class "field" ] | ||||
|             [ label [] | ||||
|                 [ text "Recipient(s)" | ||||
|                 ] | ||||
|             , Html.map RecipientMsg (Comp.EmailInput.view model.recipients model.recipientsModel) | ||||
|             ] | ||||
|         , div [ class "field" ] | ||||
|             [ label [] | ||||
|                 [ text "CC(s)" | ||||
|                 ] | ||||
|             , Html.map CCRecipientMsg (Comp.EmailInput.view model.ccRecipients model.ccRecipientsModel) | ||||
|             ] | ||||
|         , div [ class "field" ] | ||||
|             [ label [] | ||||
|                 [ text "BCC(s)" | ||||
|                 ] | ||||
|             , Html.map BCCRecipientMsg (Comp.EmailInput.view model.bccRecipients model.bccRecipientsModel) | ||||
|             ] | ||||
|         , div [ class "field" ] | ||||
|             [ label [] [ text "Subject" ] | ||||
|             , input | ||||
|                 [ type_ "text" | ||||
|                 , onInput SetSubject | ||||
|                 , value model.subject | ||||
|                 ] | ||||
|                 [] | ||||
|             ] | ||||
|         , div [ class "field" ] | ||||
|             [ label [] [ text "Body" ] | ||||
|             , textarea | ||||
|                 [ onInput SetBody | ||||
|                 , value model.body | ||||
|                 ] | ||||
|                 [] | ||||
|             ] | ||||
|         , div [ class "inline field" ] | ||||
|             [ div [ class "ui checkbox" ] | ||||
|                 [ input | ||||
|                     [ type_ "checkbox" | ||||
|                     , checked model.attachAll | ||||
|                     , onCheck (\_ -> ToggleAttachAll) | ||||
|                     ] | ||||
|                     [] | ||||
|                 , label [] [ text "Include all item attachments" ] | ||||
|                 ] | ||||
|             ] | ||||
|         , button | ||||
|             [ classList | ||||
|                 [ ( "ui primary button", True ) | ||||
|                 , ( "disabled", not (isValid model) ) | ||||
|                 ] | ||||
|             , onClick Send | ||||
|             ] | ||||
|             [ text "Send" | ||||
|             ] | ||||
|         , button | ||||
|             [ class "ui secondary button" | ||||
|             , onClick Cancel | ||||
|             ] | ||||
|             [ text "Cancel" | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -1,181 +0,0 @@ | ||||
| module Comp.MappingForm exposing | ||||
|     ( FormData | ||||
|     , Model | ||||
|     , Msg | ||||
|     , ViewOpts | ||||
|     , init | ||||
|     , update | ||||
|     , view | ||||
|     ) | ||||
|  | ||||
| import Comp.FixedDropdown | ||||
| import Dict exposing (Dict) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onClick) | ||||
| import Util.Maybe | ||||
|  | ||||
|  | ||||
| type alias FormData = | ||||
|     Dict String String | ||||
|  | ||||
|  | ||||
| type alias Model = | ||||
|     { leftDropdown : Comp.FixedDropdown.Model String | ||||
|     , rightDropdown : Comp.FixedDropdown.Model String | ||||
|     , leftSelect : Maybe String | ||||
|     , rightSelect : Maybe String | ||||
|     } | ||||
|  | ||||
|  | ||||
| type Msg | ||||
|     = AddPair FormData | ||||
|     | DeleteItem FormData String | ||||
|     | EditItem String String | ||||
|     | LeftMsg (Comp.FixedDropdown.Msg String) | ||||
|     | RightMsg (Comp.FixedDropdown.Msg String) | ||||
|  | ||||
|  | ||||
| init : List String -> List String -> Model | ||||
| init leftSel rightSel = | ||||
|     { leftDropdown = Comp.FixedDropdown.initString leftSel | ||||
|     , rightDropdown = Comp.FixedDropdown.initString rightSel | ||||
|     , leftSelect = Nothing | ||||
|     , rightSelect = Nothing | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
| --- Update | ||||
|  | ||||
|  | ||||
| update : Msg -> Model -> ( Model, Maybe FormData ) | ||||
| update msg model = | ||||
|     case msg of | ||||
|         AddPair data -> | ||||
|             case ( model.leftSelect, model.rightSelect ) of | ||||
|                 ( Just l, Just r ) -> | ||||
|                     ( { model | ||||
|                         | leftSelect = Nothing | ||||
|                         , rightSelect = Nothing | ||||
|                       } | ||||
|                     , Just (Dict.insert l r data) | ||||
|                     ) | ||||
|  | ||||
|                 _ -> | ||||
|                     ( model, Nothing ) | ||||
|  | ||||
|         DeleteItem data k -> | ||||
|             ( model, Just (Dict.remove k data) ) | ||||
|  | ||||
|         EditItem k v -> | ||||
|             ( { model | ||||
|                 | leftSelect = Just k | ||||
|                 , rightSelect = Just v | ||||
|               } | ||||
|             , Nothing | ||||
|             ) | ||||
|  | ||||
|         LeftMsg lm -> | ||||
|             let | ||||
|                 ( m_, la ) = | ||||
|                     Comp.FixedDropdown.update lm model.leftDropdown | ||||
|             in | ||||
|             ( { model | ||||
|                 | leftDropdown = m_ | ||||
|                 , leftSelect = Util.Maybe.withDefault model.leftSelect la | ||||
|               } | ||||
|             , Nothing | ||||
|             ) | ||||
|  | ||||
|         RightMsg lm -> | ||||
|             let | ||||
|                 ( m_, la ) = | ||||
|                     Comp.FixedDropdown.update lm model.rightDropdown | ||||
|             in | ||||
|             ( { model | ||||
|                 | rightDropdown = m_ | ||||
|                 , rightSelect = Util.Maybe.withDefault model.rightSelect la | ||||
|               } | ||||
|             , Nothing | ||||
|             ) | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| type alias ViewOpts = | ||||
|     { renderItem : ( String, String ) -> Html Msg | ||||
|     , label : String | ||||
|     , description : Maybe String | ||||
|     } | ||||
|  | ||||
|  | ||||
| view : FormData -> ViewOpts -> Model -> Html Msg | ||||
| view data opts model = | ||||
|     div [ class "field" ] | ||||
|         [ label [] [ text opts.label ] | ||||
|         , div [ class "fields" ] | ||||
|             [ div [ class "inline field" ] | ||||
|                 [ Html.map LeftMsg | ||||
|                     (Comp.FixedDropdown.viewString | ||||
|                         model.leftSelect | ||||
|                         model.leftDropdown | ||||
|                     ) | ||||
|                 ] | ||||
|             , div [ class "inline field" ] | ||||
|                 [ Html.map RightMsg | ||||
|                     (Comp.FixedDropdown.viewString | ||||
|                         model.rightSelect | ||||
|                         model.rightDropdown | ||||
|                     ) | ||||
|                 ] | ||||
|             , button | ||||
|                 [ class "ui icon button" | ||||
|                 , onClick (AddPair data) | ||||
|                 , href "#" | ||||
|                 ] | ||||
|                 [ i [ class "add icon" ] [] | ||||
|                 ] | ||||
|             ] | ||||
|         , renderFormData opts data | ||||
|         , span | ||||
|             [ classList | ||||
|                 [ ( "small-info", True ) | ||||
|                 , ( "invisible hidden", opts.description == Nothing ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ Maybe.withDefault "" opts.description | ||||
|                 |> text | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| renderFormData : ViewOpts -> FormData -> Html Msg | ||||
| renderFormData opts data = | ||||
|     let | ||||
|         values = | ||||
|             Dict.toList data | ||||
|  | ||||
|         renderItem ( k, v ) = | ||||
|             div [ class "item" ] | ||||
|                 [ a | ||||
|                     [ class "link icon" | ||||
|                     , href "#" | ||||
|                     , onClick (DeleteItem data k) | ||||
|                     ] | ||||
|                     [ i [ class "trash icon" ] [] | ||||
|                     ] | ||||
|                 , a | ||||
|                     [ class "link icon" | ||||
|                     , href "#" | ||||
|                     , onClick (EditItem k v) | ||||
|                     ] | ||||
|                     [ i [ class "edit icon" ] [] | ||||
|                     ] | ||||
|                 , opts.renderItem ( k, v ) | ||||
|                 ] | ||||
|     in | ||||
|     div [ class "ui list" ] | ||||
|         (List.map renderItem values) | ||||
| @@ -3,16 +3,10 @@ module Comp.MarkdownInput exposing | ||||
|     , Msg | ||||
|     , init | ||||
|     , update | ||||
|     , view | ||||
|     , viewCheatLink | ||||
|     , viewCheatLink2 | ||||
|     , viewContent | ||||
|     , viewContent2 | ||||
|     , viewEditLink | ||||
|     , viewEditLink2 | ||||
|     , viewPreviewLink | ||||
|     , viewPreviewLink2 | ||||
|     , viewSplitLink | ||||
|     , viewSplitLink2 | ||||
|     ) | ||||
|  | ||||
| @@ -58,133 +52,6 @@ update txt msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| viewContent : String -> Model -> Html Msg | ||||
| viewContent txt model = | ||||
|     case model.display of | ||||
|         Edit -> | ||||
|             editDisplay txt | ||||
|  | ||||
|         Preview -> | ||||
|             previewDisplay txt | ||||
|  | ||||
|         Split -> | ||||
|             splitDisplay txt | ||||
|  | ||||
|  | ||||
| viewEditLink : (Bool -> Attribute Msg) -> Model -> Html Msg | ||||
| viewEditLink classes model = | ||||
|     a | ||||
|         [ onClick (SetDisplay Edit) | ||||
|         , classes (model.display == Edit) | ||||
|         , href "#" | ||||
|         ] | ||||
|         [ text "Edit" | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewPreviewLink : (Bool -> Attribute Msg) -> Model -> Html Msg | ||||
| viewPreviewLink classes model = | ||||
|     a | ||||
|         [ onClick (SetDisplay Preview) | ||||
|         , classes (model.display == Preview) | ||||
|         , href "#" | ||||
|         ] | ||||
|         [ text "Preview" | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewSplitLink : (Bool -> Attribute Msg) -> Model -> Html Msg | ||||
| viewSplitLink classes model = | ||||
|     a | ||||
|         [ onClick (SetDisplay Split) | ||||
|         , classes (model.display == Split) | ||||
|         , href "#" | ||||
|         ] | ||||
|         [ text "Split" | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewCheatLink : String -> Model -> Html msg | ||||
| viewCheatLink classes model = | ||||
|     a | ||||
|         [ class classes | ||||
|         , target "_new" | ||||
|         , href model.cheatSheetUrl | ||||
|         ] | ||||
|         [ i [ class "ui help icon" ] [] | ||||
|         , text "Supports Markdown" | ||||
|         ] | ||||
|  | ||||
|  | ||||
| view : String -> Model -> Html Msg | ||||
| view txt model = | ||||
|     div [] | ||||
|         [ div [ class "ui top attached tabular mini menu" ] | ||||
|             [ viewEditLink | ||||
|                 (\act -> | ||||
|                     classList | ||||
|                         [ ( "ui link item", True ) | ||||
|                         , ( "active", act ) | ||||
|                         ] | ||||
|                 ) | ||||
|                 model | ||||
|             , viewPreviewLink | ||||
|                 (\act -> | ||||
|                     classList | ||||
|                         [ ( "ui link item", True ) | ||||
|                         , ( "active", act ) | ||||
|                         ] | ||||
|                 ) | ||||
|                 model | ||||
|             , viewSplitLink | ||||
|                 (\act -> | ||||
|                     classList | ||||
|                         [ ( "ui link item", True ) | ||||
|                         , ( "active", act ) | ||||
|                         ] | ||||
|                 ) | ||||
|                 model | ||||
|             , viewCheatLink "ui right floated help-link link item" model | ||||
|             ] | ||||
|         , div [ class "ui bottom attached segment" ] | ||||
|             [ viewContent txt model | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| editDisplay : String -> Html Msg | ||||
| editDisplay txt = | ||||
|     textarea | ||||
|         [ class "markdown-editor" | ||||
|         , onInput SetText | ||||
|         , placeholder "Add notes here…" | ||||
|         ] | ||||
|         [ text txt ] | ||||
|  | ||||
|  | ||||
| previewDisplay : String -> Html Msg | ||||
| previewDisplay txt = | ||||
|     Markdown.toHtml [ class "markdown-preview" ] txt | ||||
|  | ||||
|  | ||||
| splitDisplay : String -> Html Msg | ||||
| splitDisplay txt = | ||||
|     div [ class "ui grid" ] | ||||
|         [ div [ class "row" ] | ||||
|             [ div [ class "eight wide column markdown-split" ] | ||||
|                 [ editDisplay txt | ||||
|                 ] | ||||
|             , div [ class "eight wide column markdown-split" ] | ||||
|                 [ previewDisplay txt | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -9,10 +9,9 @@ module Comp.MenuBar exposing | ||||
|     , viewSide | ||||
|     ) | ||||
|  | ||||
| import Data.DropdownStyle exposing (DropdownStyle) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onBlur, onCheck, onClick, onFocus, onInput) | ||||
| import Html.Events exposing (onCheck, onClick, onInput) | ||||
| import Styles as S | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -5,7 +5,6 @@ module Comp.NotificationForm exposing | ||||
|     , init | ||||
|     , initWith | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -29,7 +28,6 @@ import Data.UiSettings exposing (UiSettings) | ||||
| import Data.Validated exposing (Validated(..)) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onCheck, onClick) | ||||
| import Http | ||||
| import Styles as S | ||||
| import Util.Http | ||||
| @@ -454,7 +452,7 @@ update flags msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
| isFormError : Model -> Bool | ||||
| @@ -470,169 +468,6 @@ isFormSuccess model = | ||||
|         |> Maybe.withDefault False | ||||
|  | ||||
|  | ||||
| view : String -> UiSettings -> Model -> Html Msg | ||||
| view extraClasses settings model = | ||||
|     div | ||||
|         [ classList | ||||
|             [ ( "ui form", True ) | ||||
|             , ( extraClasses, True ) | ||||
|             , ( "error", isFormError model ) | ||||
|             , ( "success", isFormSuccess model ) | ||||
|             ] | ||||
|         ] | ||||
|         [ Html.map YesNoDeleteMsg (Comp.YesNoDimmer.view model.yesNoDelete) | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui dimmer", True ) | ||||
|                 , ( "active", model.loading > 0 ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ div [ class "ui text loader" ] | ||||
|                 [ text "Loading..." | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "inline field" ] | ||||
|             [ div [ class "ui checkbox" ] | ||||
|                 [ input | ||||
|                     [ type_ "checkbox" | ||||
|                     , onCheck (\_ -> ToggleEnabled) | ||||
|                     , checked model.enabled | ||||
|                     ] | ||||
|                     [] | ||||
|                 , label [] [ text "Enabled" ] | ||||
|                 ] | ||||
|             , span [ class "small-info" ] | ||||
|                 [ text "Enable or disable this task." | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "required field" ] | ||||
|             [ label [] [ text "Send via" ] | ||||
|             , Html.map ConnMsg (Comp.Dropdown.view settings model.connectionModel) | ||||
|             , span [ class "small-info" ] | ||||
|                 [ text "The SMTP connection to use when sending notification mails." | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "required field" ] | ||||
|             [ label [] | ||||
|                 [ text "Recipient(s)" | ||||
|                 ] | ||||
|             , Html.map RecipientMsg | ||||
|                 (Comp.EmailInput.view model.recipients model.recipientsModel) | ||||
|             , span [ class "small-info" ] | ||||
|                 [ text "One or more mail addresses, confirm each by pressing 'Return'." | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "field" ] | ||||
|             [ label [] [ text "Tags Include (and)" ] | ||||
|             , Html.map TagIncMsg (Comp.Dropdown.view settings model.tagInclModel) | ||||
|             , span [ class "small-info" ] | ||||
|                 [ text "Items must have all the tags specified here." | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "field" ] | ||||
|             [ label [] [ text "Tags Exclude (or)" ] | ||||
|             , Html.map TagExcMsg (Comp.Dropdown.view settings model.tagExclModel) | ||||
|             , span [ class "small-info" ] | ||||
|                 [ text "Items must not have any tag specified here." | ||||
|                 ] | ||||
|             ] | ||||
|         , Html.map RemindDaysMsg | ||||
|             (Comp.IntField.viewWithInfo | ||||
|                 "Select items with a due date *lower than* `today+remindDays`" | ||||
|                 model.remindDays | ||||
|                 "required field" | ||||
|                 model.remindDaysModel | ||||
|             ) | ||||
|         , div [ class "required inline field" ] | ||||
|             [ div [ class "ui checkbox" ] | ||||
|                 [ input | ||||
|                     [ type_ "checkbox" | ||||
|                     , onCheck (\_ -> ToggleCapOverdue) | ||||
|                     , checked model.capOverdue | ||||
|                     ] | ||||
|                     [] | ||||
|                 , label [] | ||||
|                     [ text "Cap overdue items" | ||||
|                     ] | ||||
|                 ] | ||||
|             , div [ class "small-info" ] | ||||
|                 [ text "If checked, only items with a due date" | ||||
|                 , em [] [ text " greater than " ] | ||||
|                 , code [] [ text "today-remindDays" ] | ||||
|                 , text " are considered." | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "required field" ] | ||||
|             [ label [] | ||||
|                 [ text "Schedule" | ||||
|                 , a | ||||
|                     [ class "right-float" | ||||
|                     , href "https://github.com/eikek/calev#what-are-calendar-events" | ||||
|                     , target "_blank" | ||||
|                     ] | ||||
|                     [ i [ class "help icon" ] [] | ||||
|                     , text "Click here for help" | ||||
|                     ] | ||||
|                 ] | ||||
|             , Html.map CalEventMsg | ||||
|                 (Comp.CalEventInput.view "" | ||||
|                     (Data.Validated.value model.schedule) | ||||
|                     model.scheduleModel | ||||
|                 ) | ||||
|             , span [ class "small-info" ] | ||||
|                 [ text "Specify how often and when this task should run. " | ||||
|                 , 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." | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "ui divider" ] [] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui message", True ) | ||||
|                 , ( "success", isFormSuccess model ) | ||||
|                 , ( "error", isFormError model ) | ||||
|                 , ( "hidden", model.formMsg == Nothing ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ Maybe.map .message model.formMsg | ||||
|                 |> Maybe.withDefault "" | ||||
|                 |> text | ||||
|             ] | ||||
|         , button | ||||
|             [ class "ui primary button" | ||||
|             , onClick Submit | ||||
|             ] | ||||
|             [ text "Submit" | ||||
|             ] | ||||
|         , button | ||||
|             [ class "ui secondary button" | ||||
|             , onClick Cancel | ||||
|             ] | ||||
|             [ text "Cancel" | ||||
|             ] | ||||
|         , button | ||||
|             [ classList | ||||
|                 [ ( "ui red button", True ) | ||||
|                 , ( "hidden invisible", model.settings.id == "" ) | ||||
|                 ] | ||||
|             , onClick RequestDelete | ||||
|             ] | ||||
|             [ text "Delete" | ||||
|             ] | ||||
|         , button | ||||
|             [ class "ui right floated button" | ||||
|             , onClick StartOnce | ||||
|             ] | ||||
|             [ text "Start Once" | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View 2 | ||||
|  | ||||
|  | ||||
| view2 : String -> UiSettings -> Model -> Html Msg | ||||
| view2 extraClasses settings model = | ||||
|     let | ||||
|   | ||||
| @@ -4,7 +4,6 @@ module Comp.NotificationList exposing | ||||
|     , Msg | ||||
|     , init | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -12,7 +11,6 @@ import Api.Model.NotificationSettings exposing (NotificationSettings) | ||||
| import Comp.Basic as B | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onClick) | ||||
| import Styles as S | ||||
| import Util.Html | ||||
|  | ||||
| @@ -43,66 +41,6 @@ update msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : Model -> List NotificationSettings -> Html Msg | ||||
| view _ items = | ||||
|     div [] | ||||
|         [ table [ class "ui very basic center aligned table" ] | ||||
|             [ thead [] | ||||
|                 [ tr [] | ||||
|                     [ th [ class "collapsing" ] [] | ||||
|                     , th [ class "collapsing" ] | ||||
|                         [ i [ class "check icon" ] [] | ||||
|                         ] | ||||
|                     , th [] [ text "Schedule" ] | ||||
|                     , th [] [ text "Connection" ] | ||||
|                     , th [] [ text "Recipients" ] | ||||
|                     , th [] [ text "Remind Days" ] | ||||
|                     ] | ||||
|                 ] | ||||
|             , tbody [] | ||||
|                 (List.map viewItem items) | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewItem : NotificationSettings -> Html Msg | ||||
| viewItem item = | ||||
|     tr [] | ||||
|         [ td [ class "collapsing" ] | ||||
|             [ a | ||||
|                 [ href "#" | ||||
|                 , class "ui basic small blue label" | ||||
|                 , onClick (EditSettings item) | ||||
|                 ] | ||||
|                 [ i [ class "edit icon" ] [] | ||||
|                 , text "Edit" | ||||
|                 ] | ||||
|             ] | ||||
|         , td [ class "collapsing" ] | ||||
|             [ Util.Html.checkbox item.enabled | ||||
|             ] | ||||
|         , td [] | ||||
|             [ code [] | ||||
|                 [ text item.schedule | ||||
|                 ] | ||||
|             ] | ||||
|         , td [] | ||||
|             [ text item.smtpConnection | ||||
|             ] | ||||
|         , td [] | ||||
|             [ String.join ", " item.recipients |> text | ||||
|             ] | ||||
|         , td [] | ||||
|             [ String.fromInt item.remindDays | ||||
|                 |> text | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -3,7 +3,6 @@ module Comp.NotificationManage exposing | ||||
|     , Msg | ||||
|     , init | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -18,7 +17,6 @@ import Data.Flags exposing (Flags) | ||||
| import Data.UiSettings exposing (UiSettings) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onClick) | ||||
| import Http | ||||
| import Styles as S | ||||
| import Util.Http | ||||
| @@ -211,61 +209,13 @@ update flags msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : UiSettings -> Model -> Html Msg | ||||
| view settings model = | ||||
|     div [] | ||||
|         [ div [ class "ui menu" ] | ||||
|             [ a | ||||
|                 [ class "link item" | ||||
|                 , href "#" | ||||
|                 , onClick NewTask | ||||
|                 ] | ||||
|                 [ i [ class "add icon" ] [] | ||||
|                 , text "New Task" | ||||
|                 ] | ||||
|             ] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui message", True ) | ||||
|                 , ( "error", Maybe.map .success model.result == Just False ) | ||||
|                 , ( "success", Maybe.map .success model.result == Just True ) | ||||
|                 , ( "invisible hidden", model.result == Nothing ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ Maybe.map .message model.result | ||||
|                 |> Maybe.withDefault "" | ||||
|                 |> text | ||||
|             ] | ||||
|         , case model.detailModel of | ||||
|             Just msett -> | ||||
|                 viewForm settings msett | ||||
|  | ||||
|             Nothing -> | ||||
|                 viewList model | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewForm : UiSettings -> Comp.NotificationForm.Model -> Html Msg | ||||
| viewForm settings model = | ||||
|     Html.map DetailMsg (Comp.NotificationForm.view "segment" settings model) | ||||
|  | ||||
|  | ||||
| viewList : Model -> Html Msg | ||||
| viewList model = | ||||
|     Html.map ListMsg (Comp.NotificationList.view model.listModel model.items) | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
| view2 : UiSettings -> Model -> Html Msg | ||||
| view2 settings model = | ||||
|     div [ class "flex flex-col" ] | ||||
|         ([ div | ||||
|         (div | ||||
|             [ classList | ||||
|                 [ ( S.errorMessage, Maybe.map .success model.result == Just False ) | ||||
|                 , ( S.successMessage, Maybe.map .success model.result == Just True ) | ||||
| @@ -276,8 +226,7 @@ view2 settings model = | ||||
|                 |> Maybe.withDefault "" | ||||
|                 |> text | ||||
|             ] | ||||
|          ] | ||||
|             ++ (case model.detailModel of | ||||
|             :: (case model.detailModel of | ||||
|                     Just msett -> | ||||
|                         viewForm2 settings msett | ||||
|  | ||||
|   | ||||
| @@ -5,8 +5,6 @@ module Comp.OrgForm exposing | ||||
|     , getOrg | ||||
|     , isValid | ||||
|     , update | ||||
|     , view | ||||
|     , view1 | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -121,50 +119,6 @@ update flags msg model = | ||||
|             ) | ||||
|  | ||||
|  | ||||
| view : UiSettings -> Model -> Html Msg | ||||
| view settings model = | ||||
|     view1 settings False model | ||||
|  | ||||
|  | ||||
| view1 : UiSettings -> Bool -> Model -> Html Msg | ||||
| view1 settings compact model = | ||||
|     div [ class "ui form" ] | ||||
|         [ div | ||||
|             [ classList | ||||
|                 [ ( "field", True ) | ||||
|                 , ( "error", not (isValid model) ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ label [] [ text "Name*" ] | ||||
|             , input | ||||
|                 [ type_ "text" | ||||
|                 , onInput SetName | ||||
|                 , placeholder "Name" | ||||
|                 , value model.name | ||||
|                 ] | ||||
|                 [] | ||||
|             ] | ||||
|         , h3 [ class "ui dividing header" ] | ||||
|             [ text "Address" | ||||
|             ] | ||||
|         , Html.map AddressMsg (Comp.AddressForm.view settings model.addressModel) | ||||
|         , h3 [ class "ui dividing header" ] | ||||
|             [ text "Contacts" | ||||
|             ] | ||||
|         , Html.map ContactMsg (Comp.ContactField.view1 settings compact model.contactModel) | ||||
|         , h3 [ class "ui dividing header" ] | ||||
|             [ text "Notes" | ||||
|             ] | ||||
|         , div [ class "field" ] | ||||
|             [ textarea | ||||
|                 [ onInput SetNotes | ||||
|                 , Maybe.withDefault "" model.notes |> value | ||||
|                 ] | ||||
|                 [] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|   | ||||
| @@ -3,7 +3,6 @@ module Comp.OrgManage exposing | ||||
|     , Msg(..) | ||||
|     , emptyModel | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -20,7 +19,7 @@ import Data.Flags exposing (Flags) | ||||
| import Data.UiSettings exposing (UiSettings) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onClick, onInput, onSubmit) | ||||
| import Html.Events exposing (onSubmit) | ||||
| import Http | ||||
| import Styles as S | ||||
| import Util.Http | ||||
| @@ -202,111 +201,6 @@ update flags msg model = | ||||
|             ( m, Api.getOrganizations flags str OrgResp ) | ||||
|  | ||||
|  | ||||
| view : UiSettings -> Model -> Html Msg | ||||
| view settings model = | ||||
|     if model.viewMode == Table then | ||||
|         viewTable model | ||||
|  | ||||
|     else | ||||
|         viewForm settings model | ||||
|  | ||||
|  | ||||
| viewTable : Model -> Html Msg | ||||
| viewTable model = | ||||
|     div [] | ||||
|         [ div [ class "ui secondary menu" ] | ||||
|             [ div [ class "horizontally fitted item" ] | ||||
|                 [ div [ class "ui icon input" ] | ||||
|                     [ input | ||||
|                         [ type_ "text" | ||||
|                         , onInput SetQuery | ||||
|                         , value model.query | ||||
|                         , placeholder "Search…" | ||||
|                         ] | ||||
|                         [] | ||||
|                     , i [ class "ui search icon" ] | ||||
|                         [] | ||||
|                     ] | ||||
|                 ] | ||||
|             , div [ class "right menu" ] | ||||
|                 [ div [ class "item" ] | ||||
|                     [ a | ||||
|                         [ class "ui primary button" | ||||
|                         , href "#" | ||||
|                         , onClick InitNewOrg | ||||
|                         ] | ||||
|                         [ i [ class "plus icon" ] [] | ||||
|                         , text "New Organization" | ||||
|                         ] | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         , Html.map TableMsg (Comp.OrgTable.view model.tableModel) | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui dimmer", True ) | ||||
|                 , ( "active", model.loading ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ div [ class "ui loader" ] [] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewForm : UiSettings -> Model -> Html Msg | ||||
| viewForm settings model = | ||||
|     let | ||||
|         newOrg = | ||||
|             model.formModel.org.id == "" | ||||
|     in | ||||
|     Html.form [ class "ui segment", onSubmit Submit ] | ||||
|         [ Html.map YesNoMsg (Comp.YesNoDimmer.view model.deleteConfirm) | ||||
|         , if newOrg then | ||||
|             h3 [ class "ui dividing header" ] | ||||
|                 [ text "Create new organization" | ||||
|                 ] | ||||
|  | ||||
|           else | ||||
|             h3 [ class "ui dividing header" ] | ||||
|                 [ text ("Edit org: " ++ model.formModel.org.name) | ||||
|                 , div [ class "sub header" ] | ||||
|                     [ text "Id: " | ||||
|                     , text model.formModel.org.id | ||||
|                     ] | ||||
|                 ] | ||||
|         , Html.map FormMsg (Comp.OrgForm.view settings model.formModel) | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui error message", True ) | ||||
|                 , ( "invisible", Util.Maybe.isEmpty model.formError ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ Maybe.withDefault "" model.formError |> text | ||||
|             ] | ||||
|         , div [ class "ui horizontal divider" ] [] | ||||
|         , button [ class "ui primary button", type_ "submit" ] | ||||
|             [ text "Submit" | ||||
|             ] | ||||
|         , a [ class "ui secondary button", onClick (SetViewMode Table), href "#" ] | ||||
|             [ text "Cancel" | ||||
|             ] | ||||
|         , if not newOrg then | ||||
|             a [ class "ui right floated red button", href "#", onClick RequestDelete ] | ||||
|                 [ text "Delete" ] | ||||
|  | ||||
|           else | ||||
|             span [] [] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui dimmer", True ) | ||||
|                 , ( "active", model.loading ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ div [ class "ui loader" ] [] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|   | ||||
| @@ -3,7 +3,6 @@ module Comp.OrgTable exposing | ||||
|     , Msg(..) | ||||
|     , emptyModel | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -12,7 +11,6 @@ import Comp.Basic as B | ||||
| import Data.Flags exposing (Flags) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onClick) | ||||
| import Styles as S | ||||
| import Util.Address | ||||
| import Util.Contact | ||||
| @@ -50,49 +48,6 @@ update _ msg model = | ||||
|             ( { model | selected = Nothing }, Cmd.none ) | ||||
|  | ||||
|  | ||||
| view : Model -> Html Msg | ||||
| view model = | ||||
|     table [ class "ui very basic aligned table" ] | ||||
|         [ thead [] | ||||
|             [ tr [] | ||||
|                 [ th [ class "collapsing" ] [] | ||||
|                 , th [ class "collapsing" ] [ text "Name" ] | ||||
|                 , th [] [ text "Address" ] | ||||
|                 , th [] [ text "Contact" ] | ||||
|                 ] | ||||
|             ] | ||||
|         , tbody [] | ||||
|             (List.map (renderOrgLine model) model.orgs) | ||||
|         ] | ||||
|  | ||||
|  | ||||
| renderOrgLine : Model -> Organization -> Html Msg | ||||
| renderOrgLine model org = | ||||
|     tr | ||||
|         [ classList [ ( "active", model.selected == Just org ) ] | ||||
|         ] | ||||
|         [ td [ class "collapsing" ] | ||||
|             [ a | ||||
|                 [ href "#" | ||||
|                 , class "ui basic small blue label" | ||||
|                 , onClick (Select org) | ||||
|                 ] | ||||
|                 [ i [ class "edit icon" ] [] | ||||
|                 , text "Edit" | ||||
|                 ] | ||||
|             ] | ||||
|         , td [ class "collapsing" ] | ||||
|             [ text org.name | ||||
|             ] | ||||
|         , td [] | ||||
|             [ Util.Address.toString org.address |> text | ||||
|             ] | ||||
|         , td [] | ||||
|             [ Util.Contact.toString org.contacts |> text | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|   | ||||
| @@ -3,7 +3,6 @@ module Comp.PasswordInput exposing | ||||
|     , Msg | ||||
|     , init | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -46,36 +45,6 @@ update msg model = | ||||
|             ( model, pw ) | ||||
|  | ||||
|  | ||||
| view : Maybe String -> Model -> Html Msg | ||||
| view pw model = | ||||
|     div [ class "ui  left action input" ] | ||||
|         [ button | ||||
|             [ class "ui icon button" | ||||
|             , type_ "button" | ||||
|             , onClick (ToggleShow pw) | ||||
|             ] | ||||
|             [ i | ||||
|                 [ classList | ||||
|                     [ ( "ui eye icon", True ) | ||||
|                     , ( "slash", model.show ) | ||||
|                     ] | ||||
|                 ] | ||||
|                 [] | ||||
|             ] | ||||
|         , input | ||||
|             [ type_ <| | ||||
|                 if model.show then | ||||
|                     "text" | ||||
|  | ||||
|                 else | ||||
|                     "password" | ||||
|             , onInput SetPassword | ||||
|             , Maybe.withDefault "" pw |> value | ||||
|             ] | ||||
|             [] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|   | ||||
| @@ -5,8 +5,6 @@ module Comp.PersonForm exposing | ||||
|     , getPerson | ||||
|     , isValid | ||||
|     , update | ||||
|     , view | ||||
|     , view1 | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -178,59 +176,6 @@ update flags msg model = | ||||
|             ) | ||||
|  | ||||
|  | ||||
| view : UiSettings -> Model -> Html Msg | ||||
| view settings model = | ||||
|     view1 settings False model | ||||
|  | ||||
|  | ||||
| view1 : UiSettings -> Bool -> Model -> Html Msg | ||||
| view1 settings compact model = | ||||
|     div [ class "ui form" ] | ||||
|         [ div | ||||
|             [ classList | ||||
|                 [ ( "field", True ) | ||||
|                 , ( "error", not (isValid model) ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ label [] [ text "Name*" ] | ||||
|             , input | ||||
|                 [ type_ "text" | ||||
|                 , onInput SetName | ||||
|                 , placeholder "Name" | ||||
|                 , value model.name | ||||
|                 ] | ||||
|                 [] | ||||
|             ] | ||||
|         , div [ class "field" ] | ||||
|             [ label [] [ text "Use" ] | ||||
|             , Html.map UseDropdownMsg (Comp.FixedDropdown.view (makeUseItem model) model.useModel) | ||||
|             , label [] [ text "Use for concerning person suggestion only" ] | ||||
|             ] | ||||
|         , div [ class "field" ] | ||||
|             [ label [] [ text "Organization" ] | ||||
|             , Html.map OrgDropdownMsg (Comp.Dropdown.view settings model.orgModel) | ||||
|             ] | ||||
|         , h3 [ class "ui dividing header" ] | ||||
|             [ text "Address" | ||||
|             ] | ||||
|         , Html.map AddressMsg (Comp.AddressForm.view settings model.addressModel) | ||||
|         , h3 [ class "ui dividing header" ] | ||||
|             [ text "Contacts" | ||||
|             ] | ||||
|         , Html.map ContactMsg (Comp.ContactField.view1 settings compact model.contactModel) | ||||
|         , h3 [ class "ui dividing header" ] | ||||
|             [ text "Notes" | ||||
|             ] | ||||
|         , div [ class "field" ] | ||||
|             [ textarea | ||||
|                 [ onInput SetNotes | ||||
|                 , Maybe.withDefault "" model.notes |> value | ||||
|                 ] | ||||
|                 [] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| makeUseItem : Model -> Maybe (Comp.FixedDropdown.Item PersonUse) | ||||
| makeUseItem model = | ||||
|     Just <| | ||||
|   | ||||
| @@ -3,7 +3,6 @@ module Comp.PersonManage exposing | ||||
|     , Msg(..) | ||||
|     , emptyModel | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -21,7 +20,7 @@ import Data.Flags exposing (Flags) | ||||
| import Data.UiSettings exposing (UiSettings) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onClick, onInput, onSubmit) | ||||
| import Html.Events exposing (onSubmit) | ||||
| import Http | ||||
| import Styles as S | ||||
| import Util.Http | ||||
| @@ -239,122 +238,6 @@ isLoading model = | ||||
|     model.loading /= 0 | ||||
|  | ||||
|  | ||||
| view : UiSettings -> Model -> Html Msg | ||||
| view settings model = | ||||
|     if model.viewMode == Table then | ||||
|         viewTable model | ||||
|  | ||||
|     else | ||||
|         viewForm settings model | ||||
|  | ||||
|  | ||||
| viewTable : Model -> Html Msg | ||||
| viewTable model = | ||||
|     div [] | ||||
|         [ div [ class "ui secondary menu" ] | ||||
|             [ div [ class "horizontally fitted item" ] | ||||
|                 [ div [ class "ui icon input" ] | ||||
|                     [ input | ||||
|                         [ type_ "text" | ||||
|                         , onInput SetQuery | ||||
|                         , value model.query | ||||
|                         , placeholder "Search…" | ||||
|                         ] | ||||
|                         [] | ||||
|                     , i [ class "ui search icon" ] | ||||
|                         [] | ||||
|                     ] | ||||
|                 ] | ||||
|             , div [ class "right menu" ] | ||||
|                 [ div [ class "item" ] | ||||
|                     [ a | ||||
|                         [ class "ui primary button" | ||||
|                         , href "#" | ||||
|                         , onClick InitNewPerson | ||||
|                         ] | ||||
|                         [ i [ class "plus icon" ] [] | ||||
|                         , text "New Person" | ||||
|                         ] | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         , Html.map TableMsg (Comp.PersonTable.view model.tableModel) | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui dimmer", True ) | ||||
|                 , ( "active", isLoading model ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ div [ class "ui loader" ] [] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewForm : UiSettings -> Model -> Html Msg | ||||
| viewForm settings model = | ||||
|     let | ||||
|         newPerson = | ||||
|             model.formModel.person.id == "" | ||||
|     in | ||||
|     div [ class "ui segment" ] | ||||
|         [ Html.map YesNoMsg (Comp.YesNoDimmer.view model.deleteConfirm) | ||||
|         , if newPerson then | ||||
|             h3 [ class "ui dividing header" ] | ||||
|                 [ text "Create new person" | ||||
|                 ] | ||||
|  | ||||
|           else | ||||
|             h3 [ class "ui dividing header" ] | ||||
|                 [ text ("Edit person: " ++ model.formModel.person.name) | ||||
|                 , div [ class "sub header" ] | ||||
|                     [ text "Id: " | ||||
|                     , text model.formModel.person.id | ||||
|                     ] | ||||
|                 ] | ||||
|         , Html.map FormMsg (Comp.PersonForm.view settings model.formModel) | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui error message", True ) | ||||
|                 , ( "invisible", Util.Maybe.isEmpty model.formError ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ Maybe.withDefault "" model.formError |> text | ||||
|             ] | ||||
|         , div [ class "ui horizontal divider" ] [] | ||||
|         , button | ||||
|             [ class "ui primary button" | ||||
|             , onClick Submit | ||||
|             ] | ||||
|             [ text "Submit" | ||||
|             ] | ||||
|         , a | ||||
|             [ class "ui secondary button" | ||||
|             , onClick (SetViewMode Table) | ||||
|             , href "#" | ||||
|             ] | ||||
|             [ text "Cancel" | ||||
|             ] | ||||
|         , if not newPerson then | ||||
|             a | ||||
|                 [ class "ui right floated red button" | ||||
|                 , href "#" | ||||
|                 , onClick RequestDelete | ||||
|                 ] | ||||
|                 [ text "Delete" ] | ||||
|  | ||||
|           else | ||||
|             span [] [] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui dimmer", True ) | ||||
|                 , ( "active", isLoading model ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ div [ class "ui loader" ] [] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|   | ||||
| @@ -3,7 +3,6 @@ module Comp.PersonTable exposing | ||||
|     , Msg(..) | ||||
|     , emptyModel | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -13,11 +12,8 @@ import Data.Flags exposing (Flags) | ||||
| import Data.PersonUse | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onClick) | ||||
| import Styles as S | ||||
| import Util.Address | ||||
| import Util.Contact | ||||
| import Util.Html | ||||
|  | ||||
|  | ||||
| type alias Model = | ||||
| @@ -52,62 +48,6 @@ update _ msg model = | ||||
|             ( { model | selected = Nothing }, Cmd.none ) | ||||
|  | ||||
|  | ||||
| view : Model -> Html Msg | ||||
| view model = | ||||
|     table [ class "ui very basic aligned table" ] | ||||
|         [ thead [] | ||||
|             [ tr [] | ||||
|                 [ th [ class "collapsing" ] [] | ||||
|                 , th [ class "collapsing center aligned" ] [ text "Use" ] | ||||
|                 , th [] [ text "Name" ] | ||||
|                 , th [] [ text "Organization" ] | ||||
|                 , th [] [ text "Address" ] | ||||
|                 , th [] [ text "Contact" ] | ||||
|                 ] | ||||
|             ] | ||||
|         , tbody [] | ||||
|             (List.map (renderPersonLine model) model.equips) | ||||
|         ] | ||||
|  | ||||
|  | ||||
| renderPersonLine : Model -> Person -> Html Msg | ||||
| renderPersonLine model person = | ||||
|     tr | ||||
|         [ classList [ ( "active", model.selected == Just person ) ] | ||||
|         ] | ||||
|         [ td [ class "collapsing" ] | ||||
|             [ a | ||||
|                 [ href "#" | ||||
|                 , class "ui basic small blue label" | ||||
|                 , onClick (Select person) | ||||
|                 ] | ||||
|                 [ i [ class "edit icon" ] [] | ||||
|                 , text "Edit" | ||||
|                 ] | ||||
|             ] | ||||
|         , td [ class "center aligned" ] | ||||
|             [ Data.PersonUse.fromString person.use | ||||
|                 |> Maybe.withDefault Data.PersonUse.Both | ||||
|                 |> Data.PersonUse.label | ||||
|                 |> text | ||||
|             ] | ||||
|         , td [] | ||||
|             [ text person.name | ||||
|             ] | ||||
|         , td [] | ||||
|             [ Maybe.map .name person.organization | ||||
|                 |> Maybe.withDefault "-" | ||||
|                 |> text | ||||
|             ] | ||||
|         , td [] | ||||
|             [ Util.Address.toString person.address |> text | ||||
|             ] | ||||
|         , td [] | ||||
|             [ Util.Contact.toString person.contacts |> text | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|   | ||||
| @@ -8,7 +8,6 @@ module Comp.PowerSearchInput exposing | ||||
|     , viewResult | ||||
|     ) | ||||
|  | ||||
| import Data.DropdownStyle | ||||
| import Data.QueryParseResult exposing (QueryParseResult) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
|   | ||||
| @@ -5,7 +5,6 @@ module Comp.ScanMailboxForm exposing | ||||
|     , init | ||||
|     , initWith | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -76,7 +75,6 @@ type alias Model = | ||||
|     , languageModel : Comp.FixedDropdown.Model Language | ||||
|     , language : Maybe Language | ||||
|     , postHandleAll : Bool | ||||
|     , menuTab : MenuTab | ||||
|     , openTabs : Set String | ||||
|     } | ||||
|  | ||||
| @@ -122,7 +120,6 @@ type Msg | ||||
|     | LanguageMsg (Comp.FixedDropdown.Msg Language) | ||||
|     | RemoveLanguage | ||||
|     | TogglePostHandleAll | ||||
|     | SetMenuTab MenuTab | ||||
|     | ToggleAkkordionTab String | ||||
|  | ||||
|  | ||||
| @@ -170,7 +167,6 @@ initWith flags s = | ||||
|             Comp.FixedDropdown.init (List.map mkLanguageItem Data.Language.all) | ||||
|         , language = Maybe.andThen Data.Language.fromString s.language | ||||
|         , postHandleAll = Maybe.withDefault False s.postHandleAll | ||||
|         , menuTab = TabGeneral | ||||
|       } | ||||
|     , Cmd.batch | ||||
|         [ Api.getImapSettings flags "" ConnResp | ||||
| @@ -225,7 +221,6 @@ init flags = | ||||
|             Comp.FixedDropdown.init (List.map mkLanguageItem Data.Language.all) | ||||
|       , language = Nothing | ||||
|       , postHandleAll = False | ||||
|       , menuTab = TabGeneral | ||||
|       , openTabs = Set.insert (tabTitle TabGeneral) Set.empty | ||||
|       } | ||||
|     , Cmd.batch | ||||
| @@ -680,12 +675,6 @@ update flags msg model = | ||||
|             , Cmd.none | ||||
|             ) | ||||
|  | ||||
|         SetMenuTab tab -> | ||||
|             ( { model | menuTab = tab } | ||||
|             , NoAction | ||||
|             , Cmd.none | ||||
|             ) | ||||
|  | ||||
|         ToggleAkkordionTab title -> | ||||
|             let | ||||
|                 tabs = | ||||
| @@ -702,7 +691,7 @@ update flags msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
| isFormError : Model -> Bool | ||||
| @@ -729,426 +718,6 @@ isFolderMember model = | ||||
|     Util.Folder.isFolderMember model.allFolders selected | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : String -> UiSettings -> Model -> Html Msg | ||||
| view extraClasses settings model = | ||||
|     div | ||||
|         [ classList | ||||
|             [ ( "ui warning form", True ) | ||||
|             , ( extraClasses, True ) | ||||
|             , ( "error", isFormError model ) | ||||
|             , ( "success", isFormSuccess model ) | ||||
|             ] | ||||
|         ] | ||||
|         [ viewMenu model | ||||
|         , div [ class "ui bottom attached segment" ] | ||||
|             (case model.menuTab of | ||||
|                 TabGeneral -> | ||||
|                     viewGeneral settings model | ||||
|  | ||||
|                 TabProcessing -> | ||||
|                     viewProcessing model | ||||
|  | ||||
|                 TabAdditionalFilter -> | ||||
|                     viewAdditionalFilter model | ||||
|  | ||||
|                 TabPostProcessing -> | ||||
|                     viewPostProcessing model | ||||
|  | ||||
|                 TabMetadata -> | ||||
|                     viewMetadata settings model | ||||
|  | ||||
|                 TabSchedule -> | ||||
|                     viewSchedule model | ||||
|             ) | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui message", True ) | ||||
|                 , ( "success", isFormSuccess model ) | ||||
|                 , ( "error", isFormError model ) | ||||
|                 , ( "hidden", model.formMsg == Nothing ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ Maybe.map .message model.formMsg | ||||
|                 |> Maybe.withDefault "" | ||||
|                 |> text | ||||
|             ] | ||||
|         , button | ||||
|             [ class "ui primary button" | ||||
|             , onClick Submit | ||||
|             ] | ||||
|             [ text "Submit" | ||||
|             ] | ||||
|         , button | ||||
|             [ class "ui secondary button" | ||||
|             , onClick Cancel | ||||
|             ] | ||||
|             [ text "Cancel" | ||||
|             ] | ||||
|         , button | ||||
|             [ classList | ||||
|                 [ ( "ui red button", True ) | ||||
|                 , ( "hidden invisible", model.settings.id == "" ) | ||||
|                 ] | ||||
|             , onClick RequestDelete | ||||
|             ] | ||||
|             [ text "Delete" | ||||
|             ] | ||||
|         , button | ||||
|             [ class "ui right floated button" | ||||
|             , onClick StartOnce | ||||
|             ] | ||||
|             [ text "Start Once" | ||||
|             ] | ||||
|         , Html.map YesNoDeleteMsg (Comp.YesNoDimmer.view model.yesNoDelete) | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui dimmer", True ) | ||||
|                 , ( "active", model.loading > 0 ) | ||||
|                 , ( "invisible hidden", model.loading == 0 ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ div [ class "ui text loader" ] | ||||
|                 [ text "Loading..." | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewMenu : Model -> Html Msg | ||||
| viewMenu model = | ||||
|     let | ||||
|         tabLink tab txt = | ||||
|             a | ||||
|                 [ class "item" | ||||
|                 , classList | ||||
|                     [ ( "active", model.menuTab == tab ) ] | ||||
|                 , href "#" | ||||
|                 , onClick (SetMenuTab tab) | ||||
|                 ] | ||||
|                 [ text txt | ||||
|                 ] | ||||
|     in | ||||
|     div [ class "ui top attached stacked tabular menu" ] | ||||
|         [ tabLink TabGeneral "General" | ||||
|         , tabLink TabProcessing "Processing" | ||||
|         , tabLink TabAdditionalFilter "Additional Filter" | ||||
|         , tabLink TabPostProcessing "Post Processing" | ||||
|         , tabLink TabMetadata "Metadata" | ||||
|         , tabLink TabSchedule "Schedule" | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewGeneral : UiSettings -> Model -> List (Html Msg) | ||||
| viewGeneral settings model = | ||||
|     [ div [ class "inline field" ] | ||||
|         [ div [ class "ui checkbox" ] | ||||
|             [ input | ||||
|                 [ type_ "checkbox" | ||||
|                 , onCheck (\_ -> ToggleEnabled) | ||||
|                 , checked model.enabled | ||||
|                 ] | ||||
|                 [] | ||||
|             , label [] [ text "Enabled" ] | ||||
|             ] | ||||
|         , span [ class "small-info" ] | ||||
|             [ text "Enable or disable this task." | ||||
|             ] | ||||
|         ] | ||||
|     , div [ class "required field" ] | ||||
|         [ label [] [ text "Mailbox" ] | ||||
|         , Html.map ConnMsg (Comp.Dropdown.view settings model.connectionModel) | ||||
|         , span [ class "small-info" ] | ||||
|             [ text "The IMAP connection to use when sending notification mails." | ||||
|             ] | ||||
|         ] | ||||
|     ] | ||||
|  | ||||
|  | ||||
| viewProcessing : Model -> List (Html Msg) | ||||
| viewProcessing model = | ||||
|     [ div [ class "ui message" ] | ||||
|         [ text "These settings define which mails are fetched from the mail server." | ||||
|         ] | ||||
|     , div [ class "required field" ] | ||||
|         [ label [] [ text "Folders" ] | ||||
|         , Html.map FoldersMsg (Comp.StringListInput.view model.folders model.foldersModel) | ||||
|         , span [ class "small-info" ] | ||||
|             [ text "The folders to go through" | ||||
|             ] | ||||
|         ] | ||||
|     , Html.map ReceivedHoursMsg | ||||
|         (Comp.IntField.viewWithInfo | ||||
|             "Select mails newer than `now - receivedHours`" | ||||
|             model.receivedHours | ||||
|             "field" | ||||
|             model.receivedHoursModel | ||||
|         ) | ||||
|     ] | ||||
|  | ||||
|  | ||||
| viewAdditionalFilter : Model -> List (Html Msg) | ||||
| viewAdditionalFilter model = | ||||
|     [ div [ class "ui message" ] | ||||
|         [ text "These filters are applied to mails that have been fetched from the " | ||||
|         , text "mailbox to select those that should be imported." | ||||
|         ] | ||||
|     , div | ||||
|         [ class "field" | ||||
|         ] | ||||
|         [ label [] [ text "File Filter" ] | ||||
|         , input | ||||
|             [ type_ "text" | ||||
|             , onInput SetFileFilter | ||||
|             , placeholder "File Filter" | ||||
|             , model.fileFilter | ||||
|                 |> Maybe.withDefault "" | ||||
|                 |> value | ||||
|             ] | ||||
|             [] | ||||
|         , div [ class "small-info" ] | ||||
|             [ text "Specify a file glob to filter attachments. For example, to only extract pdf files: " | ||||
|             , code [] | ||||
|                 [ text "*.pdf" | ||||
|                 ] | ||||
|             , text ". If you want to include the mail body, allow html files or " | ||||
|             , code [] | ||||
|                 [ text "mail.html" | ||||
|                 ] | ||||
|             , text ". Globs can be combined via OR, like this: " | ||||
|             , code [] | ||||
|                 [ text "*.pdf|mail.html" | ||||
|                 ] | ||||
|             , text ". No file filter defaults to " | ||||
|             , code [] | ||||
|                 [ text "*" | ||||
|                 ] | ||||
|             , text " that includes all" | ||||
|             ] | ||||
|         ] | ||||
|     , div | ||||
|         [ class "field" | ||||
|         ] | ||||
|         [ label [] [ text "Subject Filter" ] | ||||
|         , input | ||||
|             [ type_ "text" | ||||
|             , onInput SetSubjectFilter | ||||
|             , placeholder "Subject Filter" | ||||
|             , model.subjectFilter | ||||
|                 |> Maybe.withDefault "" | ||||
|                 |> value | ||||
|             ] | ||||
|             [] | ||||
|         , div [ class "small-info" ] | ||||
|             [ text "Specify a file glob to filter mails by subject. For example: " | ||||
|             , code [] | ||||
|                 [ text "*Scanned Document*" | ||||
|                 ] | ||||
|             , text ". No file filter defaults to " | ||||
|             , code [] | ||||
|                 [ text "*" | ||||
|                 ] | ||||
|             , text " that includes all" | ||||
|             ] | ||||
|         ] | ||||
|     ] | ||||
|  | ||||
|  | ||||
| viewPostProcessing : Model -> List (Html Msg) | ||||
| viewPostProcessing model = | ||||
|     [ div [ class "ui message" ] | ||||
|         [ text "This defines what happens to mails that have been downloaded." | ||||
|         ] | ||||
|     , div [ class "inline field" ] | ||||
|         [ div [ class "ui checkbox" ] | ||||
|             [ input | ||||
|                 [ type_ "checkbox" | ||||
|                 , onCheck (\_ -> TogglePostHandleAll) | ||||
|                 , checked model.postHandleAll | ||||
|                 ] | ||||
|                 [] | ||||
|             , label [] [ text "Apply post-processing to all fetched mails." ] | ||||
|             ] | ||||
|         , span [ class "small-info" ] | ||||
|             [ text "When mails are not imported due to the 'Additional Filters', this flag can " | ||||
|             , text "control whether they should be moved to a target folder or deleted (whatever is " | ||||
|             , text "defined here) nevertheless. If unchecked only imported mails " | ||||
|             , text "are post-processed, others stay where they are." | ||||
|             ] | ||||
|         ] | ||||
|     , div [ class "field" ] | ||||
|         [ label [] [ text "Target folder" ] | ||||
|         , input | ||||
|             [ type_ "text" | ||||
|             , onInput SetTargetFolder | ||||
|             , Maybe.withDefault "" model.targetFolder |> value | ||||
|             ] | ||||
|             [] | ||||
|         , span [ class "small-info" ] | ||||
|             [ text "Move mails into this folder." | ||||
|             ] | ||||
|         ] | ||||
|     , div [ class "inline field" ] | ||||
|         [ div [ class "ui checkbox" ] | ||||
|             [ input | ||||
|                 [ type_ "checkbox" | ||||
|                 , onCheck (\_ -> ToggleDeleteMail) | ||||
|                 , checked model.deleteMail | ||||
|                 ] | ||||
|                 [] | ||||
|             , label [] [ text "Delete imported mails" ] | ||||
|             ] | ||||
|         , span [ class "small-info" ] | ||||
|             [ text "Whether to delete all mails fetched by docspell. This only applies if " | ||||
|             , em [] [ text "target folder" ] | ||||
|             , text " is not set." | ||||
|             ] | ||||
|         ] | ||||
|     ] | ||||
|  | ||||
|  | ||||
| viewMetadata : UiSettings -> Model -> List (Html Msg) | ||||
| viewMetadata settings model = | ||||
|     [ div [ class "ui message" ] | ||||
|         [ text "Define metadata that should be attached to all items created by this task." | ||||
|         ] | ||||
|     , div [ class "required field" ] | ||||
|         [ label [] [ text "Item direction" ] | ||||
|         , div [ class "grouped fields" ] | ||||
|             [ div [ class "field" ] | ||||
|                 [ div [ class "ui radio checkbox" ] | ||||
|                     [ input | ||||
|                         [ type_ "radio" | ||||
|                         , checked (model.direction == Nothing) | ||||
|                         , onCheck (\_ -> DirectionMsg Nothing) | ||||
|                         ] | ||||
|                         [] | ||||
|                     , label [] [ text "Automatic" ] | ||||
|                     ] | ||||
|                 ] | ||||
|             , div [ class "field" ] | ||||
|                 [ div [ class "ui radio checkbox" ] | ||||
|                     [ input | ||||
|                         [ type_ "radio" | ||||
|                         , checked (model.direction == Just Incoming) | ||||
|                         , onCheck (\_ -> DirectionMsg (Just Incoming)) | ||||
|                         ] | ||||
|                         [] | ||||
|                     , label [] [ text "Incoming" ] | ||||
|                     ] | ||||
|                 ] | ||||
|             , div [ class "field" ] | ||||
|                 [ div [ class "ui radio checkbox" ] | ||||
|                     [ input | ||||
|                         [ type_ "radio" | ||||
|                         , checked (model.direction == Just Outgoing) | ||||
|                         , onCheck (\_ -> DirectionMsg (Just Outgoing)) | ||||
|                         ] | ||||
|                         [] | ||||
|                     , label [] [ text "Outgoing" ] | ||||
|                     ] | ||||
|                 ] | ||||
|             , span [ class "small-info" ] | ||||
|                 [ text "Sets the direction for an item. If you know all mails are incoming or " | ||||
|                 , text "outgoing, you can set it here. Otherwise it will be guessed from looking " | ||||
|                 , text "at sender and receiver." | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|     , div [ class "field" ] | ||||
|         [ label [] | ||||
|             [ text "Item Folder" | ||||
|             ] | ||||
|         , Html.map FolderDropdownMsg (Comp.Dropdown.view settings model.folderModel) | ||||
|         , span [ class "small-info" ] | ||||
|             [ text "Put all items from this mailbox into the selected folder" | ||||
|             ] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui warning message", True ) | ||||
|                 , ( "hidden", isFolderMember model ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ Markdown.toHtml [] """ | ||||
| You are **not a member** of this folder. Items created from mails in | ||||
| this mailbox 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 "field" ] | ||||
|         [ label [] [ text "Tags" ] | ||||
|         , Html.map TagDropdownMsg (Comp.Dropdown.view settings model.tagModel) | ||||
|         , div [ class "small-info" ] | ||||
|             [ text "Choose tags that should be applied to items." | ||||
|             ] | ||||
|         ] | ||||
|     , div [ class "field" ] | ||||
|         [ label [] | ||||
|             [ text "Language" | ||||
|             ] | ||||
|         , div [ class "ui action input" ] | ||||
|             [ Html.map LanguageMsg | ||||
|                 (Comp.FixedDropdown.viewStyled "fluid" | ||||
|                     (Maybe.map mkLanguageItem model.language) | ||||
|                     model.languageModel | ||||
|                 ) | ||||
|             , a | ||||
|                 [ class "ui icon button" | ||||
|                 , href "#" | ||||
|                 , onClick RemoveLanguage | ||||
|                 ] | ||||
|                 [ i [ class "delete icon" ] [] | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "small-info" ] | ||||
|             [ text "Used for text extraction and text analysis. The " | ||||
|             , text "collective's default language is used, if not specified here." | ||||
|             ] | ||||
|         ] | ||||
|     ] | ||||
|  | ||||
|  | ||||
| viewSchedule : Model -> List (Html Msg) | ||||
| viewSchedule model = | ||||
|     [ div [ class "ui message" ] | ||||
|         [ text "Define when mails should be imported." | ||||
|         ] | ||||
|     , div [ class "required field" ] | ||||
|         [ label [] | ||||
|             [ text "Schedule" | ||||
|             , a | ||||
|                 [ class "right-float" | ||||
|                 , href "https://github.com/eikek/calev#what-are-calendar-events" | ||||
|                 , target "_blank" | ||||
|                 ] | ||||
|                 [ i [ class "help icon" ] [] | ||||
|                 , text "Click here for help" | ||||
|                 ] | ||||
|             ] | ||||
|         , Html.map CalEventMsg | ||||
|             (Comp.CalEventInput.view "" | ||||
|                 (Data.Validated.value model.schedule) | ||||
|                 model.scheduleModel | ||||
|             ) | ||||
|         , span [ class "small-info" ] | ||||
|             [ text "Specify how often and when this task should run. " | ||||
|             , 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." | ||||
|             ] | ||||
|         ] | ||||
|     ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
| view2 : String -> UiSettings -> Model -> Html Msg | ||||
| view2 extraClasses settings model = | ||||
|     let | ||||
|   | ||||
| @@ -4,7 +4,6 @@ module Comp.ScanMailboxList exposing | ||||
|     , Msg | ||||
|     , init | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -12,7 +11,6 @@ import Api.Model.ScanMailboxSettings exposing (ScanMailboxSettings) | ||||
| import Comp.Basic as B | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onClick) | ||||
| import Styles as S | ||||
| import Util.Html | ||||
|  | ||||
| @@ -43,77 +41,6 @@ update msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : Model -> List ScanMailboxSettings -> Html Msg | ||||
| view _ items = | ||||
|     div [] | ||||
|         [ table [ class "ui very basic center aligned table" ] | ||||
|             [ thead [] | ||||
|                 [ tr [] | ||||
|                     [ th [ class "collapsing" ] [] | ||||
|                     , th [ class "collapsing" ] | ||||
|                         [ i [ class "check icon" ] [] | ||||
|                         ] | ||||
|                     , th [] [ text "Schedule" ] | ||||
|                     , th [] [ text "Connection" ] | ||||
|                     , th [] [ text "Folders" ] | ||||
|                     , th [] [ text "Received Since" ] | ||||
|                     , th [] [ text "Target" ] | ||||
|                     , th [] [ text "Delete" ] | ||||
|                     ] | ||||
|                 ] | ||||
|             , tbody [] | ||||
|                 (List.map viewItem items) | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewItem : ScanMailboxSettings -> Html Msg | ||||
| viewItem item = | ||||
|     tr [] | ||||
|         [ td [ class "collapsing" ] | ||||
|             [ a | ||||
|                 [ href "#" | ||||
|                 , class "ui basic small blue label" | ||||
|                 , onClick (EditSettings item) | ||||
|                 ] | ||||
|                 [ i [ class "edit icon" ] [] | ||||
|                 , text "Edit" | ||||
|                 ] | ||||
|             ] | ||||
|         , td [ class "collapsing" ] | ||||
|             [ Util.Html.checkbox item.enabled | ||||
|             ] | ||||
|         , td [] | ||||
|             [ code [] | ||||
|                 [ text item.schedule | ||||
|                 ] | ||||
|             ] | ||||
|         , td [] | ||||
|             [ text item.imapConnection | ||||
|             ] | ||||
|         , td [] | ||||
|             [ String.join ", " item.folders |> text | ||||
|             ] | ||||
|         , td [] | ||||
|             [ Maybe.map String.fromInt item.receivedSinceHours | ||||
|                 |> Maybe.withDefault "-" | ||||
|                 |> text | ||||
|             , text " h" | ||||
|             ] | ||||
|         , td [] | ||||
|             [ Maybe.withDefault "-" item.targetFolder | ||||
|                 |> text | ||||
|             ] | ||||
|         , td [] | ||||
|             [ Util.Html.checkbox item.deleteMail | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -3,7 +3,6 @@ module Comp.ScanMailboxManage exposing | ||||
|     , Msg | ||||
|     , init | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -211,61 +210,13 @@ update flags msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : UiSettings -> Model -> Html Msg | ||||
| view settings model = | ||||
|     div [] | ||||
|         [ div [ class "ui menu" ] | ||||
|             [ a | ||||
|                 [ class "link item" | ||||
|                 , href "#" | ||||
|                 , onClick NewTask | ||||
|                 ] | ||||
|                 [ i [ class "add icon" ] [] | ||||
|                 , text "New Task" | ||||
|                 ] | ||||
|             ] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui message", True ) | ||||
|                 , ( "error", Maybe.map .success model.result == Just False ) | ||||
|                 , ( "success", Maybe.map .success model.result == Just True ) | ||||
|                 , ( "invisible hidden", model.result == Nothing ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ Maybe.map .message model.result | ||||
|                 |> Maybe.withDefault "" | ||||
|                 |> text | ||||
|             ] | ||||
|         , case model.detailModel of | ||||
|             Just msett -> | ||||
|                 viewForm settings msett | ||||
|  | ||||
|             Nothing -> | ||||
|                 viewList model | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewForm : UiSettings -> Comp.ScanMailboxForm.Model -> Html Msg | ||||
| viewForm settings model = | ||||
|     Html.map DetailMsg (Comp.ScanMailboxForm.view "" settings model) | ||||
|  | ||||
|  | ||||
| viewList : Model -> Html Msg | ||||
| viewList model = | ||||
|     Html.map ListMsg (Comp.ScanMailboxList.view model.listModel model.items) | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
| view2 : UiSettings -> Model -> Html Msg | ||||
| view2 settings model = | ||||
|     div [ class "flex flex-col" ] | ||||
|         ([ div | ||||
|         (div | ||||
|             [ classList | ||||
|                 [ ( S.errorMessage, Maybe.map .success model.result == Just False ) | ||||
|                 , ( S.successMessage, Maybe.map .success model.result == Just True ) | ||||
| @@ -276,8 +227,7 @@ view2 settings model = | ||||
|                 |> Maybe.withDefault "" | ||||
|                 |> text | ||||
|             ] | ||||
|          ] | ||||
|             ++ (case model.detailModel of | ||||
|             :: (case model.detailModel of | ||||
|                     Just msett -> | ||||
|                         viewForm2 settings msett | ||||
|  | ||||
|   | ||||
| @@ -10,8 +10,6 @@ module Comp.SearchMenu exposing | ||||
|     , textSearchString | ||||
|     , update | ||||
|     , updateDrop | ||||
|     , view | ||||
|     , viewDrop | ||||
|     , viewDrop2 | ||||
|     ) | ||||
|  | ||||
| @@ -37,14 +35,13 @@ import Data.Direction exposing (Direction) | ||||
| import Data.DropdownStyle as DS | ||||
| import Data.Fields | ||||
| import Data.Flags exposing (Flags) | ||||
| import Data.Icons as Icons | ||||
| import Data.ItemQuery as Q exposing (ItemQuery) | ||||
| import Data.PersonUse | ||||
| import Data.UiSettings exposing (UiSettings) | ||||
| import DatePicker exposing (DatePicker) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onCheck, onClick, onInput) | ||||
| import Html.Events exposing (onClick, onInput) | ||||
| import Http | ||||
| import Set exposing (Set) | ||||
| import Styles as S | ||||
| @@ -221,20 +218,6 @@ isNamesSearch model = | ||||
|             True | ||||
|  | ||||
|  | ||||
| getDirection : Model -> Maybe Direction | ||||
| getDirection model = | ||||
|     let | ||||
|         selection = | ||||
|             Comp.Dropdown.getSelected model.directionModel | ||||
|     in | ||||
|     case selection of | ||||
|         [ d ] -> | ||||
|             Just d | ||||
|  | ||||
|         _ -> | ||||
|             Nothing | ||||
|  | ||||
|  | ||||
| getItemQuery : Model -> Maybe ItemQuery | ||||
| getItemQuery model = | ||||
|     let | ||||
| @@ -956,289 +939,6 @@ updateDrop ddm flags settings msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| -- View | ||||
|  | ||||
|  | ||||
| view : Flags -> UiSettings -> Model -> Html Msg | ||||
| view = | ||||
|     viewDrop (DD.DragDropData DD.init Nothing) | ||||
|  | ||||
|  | ||||
| viewDrop : DD.DragDropData -> Flags -> UiSettings -> Model -> Html Msg | ||||
| viewDrop ddd flags settings model = | ||||
|     let | ||||
|         formHeader icon headline = | ||||
|             div [ class "ui tiny header" ] | ||||
|                 [ icon | ||||
|                 , div [ class "content" ] | ||||
|                     [ text headline | ||||
|                     ] | ||||
|                 ] | ||||
|  | ||||
|         segmentClass = | ||||
|             "ui vertical segment" | ||||
|  | ||||
|         fieldVisible field = | ||||
|             Data.UiSettings.fieldVisible settings field | ||||
|  | ||||
|         fieldHidden field = | ||||
|             Data.UiSettings.fieldHidden settings field | ||||
|  | ||||
|         optional fields html = | ||||
|             if | ||||
|                 List.map fieldVisible fields | ||||
|                     |> List.foldl (||) False | ||||
|             then | ||||
|                 html | ||||
|  | ||||
|             else | ||||
|                 span [ class "invisible hidden" ] [] | ||||
|     in | ||||
|     div [ class "ui form" ] | ||||
|         [ div [ class segmentClass ] | ||||
|             [ div [ class "inline field" ] | ||||
|                 [ div [ class "ui checkbox" ] | ||||
|                     [ input | ||||
|                         [ type_ "checkbox" | ||||
|                         , onCheck (\_ -> ToggleInbox) | ||||
|                         , checked model.inboxCheckbox | ||||
|                         ] | ||||
|                         [] | ||||
|                     , label [] | ||||
|                         [ text "Only New" | ||||
|                         ] | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class segmentClass ] | ||||
|             [ div | ||||
|                 [ class "field" | ||||
|                 ] | ||||
|                 [ label [] | ||||
|                     [ text | ||||
|                         (case model.textSearchModel of | ||||
|                             Fulltext _ -> | ||||
|                                 "Fulltext Search" | ||||
|  | ||||
|                             Names _ -> | ||||
|                                 "Search in names" | ||||
|                         ) | ||||
|                     , a | ||||
|                         [ classList | ||||
|                             [ ( "right-float", True ) | ||||
|                             , ( "invisible hidden", not flags.config.fullTextSearchEnabled ) | ||||
|                             ] | ||||
|                         , href "#" | ||||
|                         , onClick SwapTextSearch | ||||
|                         , title "Switch between text search modes" | ||||
|                         ] | ||||
|                         [ i [ class "small grey exchange alternate icon" ] [] | ||||
|                         ] | ||||
|                     ] | ||||
|                 , input | ||||
|                     [ type_ "text" | ||||
|                     , onInput SetTextSearch | ||||
|                     , Util.Html.onKeyUpCode KeyUpMsg | ||||
|                     , textSearchString model.textSearchModel |> Maybe.withDefault "" |> value | ||||
|                     , case model.textSearchModel of | ||||
|                         Fulltext _ -> | ||||
|                             placeholder "Content search…" | ||||
|  | ||||
|                         Names _ -> | ||||
|                             placeholder "Search in various names…" | ||||
|                     ] | ||||
|                     [] | ||||
|                 , span [ class "small-info" ] | ||||
|                     [ case model.textSearchModel of | ||||
|                         Fulltext _ -> | ||||
|                             text "Fulltext search in document contents and notes." | ||||
|  | ||||
|                         Names _ -> | ||||
|                             text "Looks in correspondents, concerned entities, item name and notes." | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( segmentClass, True ) | ||||
|                 , ( "invisible hidden", fieldHidden Data.Fields.Tag && fieldHidden Data.Fields.Folder ) | ||||
|                 ] | ||||
|             ] | ||||
|             ((if fieldVisible Data.Fields.Tag then | ||||
|                 List.map (Html.map TagSelectMsg) | ||||
|                     (Comp.TagSelect.viewAll | ||||
|                         ddd.model | ||||
|                         settings | ||||
|                         model.tagSelection | ||||
|                         model.tagSelectModel | ||||
|                     ) | ||||
|  | ||||
|               else | ||||
|                 [] | ||||
|              ) | ||||
|                 ++ [ optional [ Data.Fields.Folder ] <| | ||||
|                         Html.map FolderSelectMsg | ||||
|                             (Comp.FolderSelect.viewDrop ddd.model | ||||
|                                 settings.searchMenuFolderCount | ||||
|                                 model.folderList | ||||
|                             ) | ||||
|                    ] | ||||
|             ) | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( segmentClass, True ) | ||||
|                 , ( "hidden invisible", fieldHidden Data.Fields.CorrOrg && fieldHidden Data.Fields.CorrPerson ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ optional | ||||
|                 [ Data.Fields.CorrOrg | ||||
|                 , Data.Fields.CorrPerson | ||||
|                 ] | ||||
|               <| | ||||
|                 formHeader (Icons.correspondentIcon "") | ||||
|                     (case getDirection model of | ||||
|                         Just Data.Direction.Incoming -> | ||||
|                             "Sender" | ||||
|  | ||||
|                         Just Data.Direction.Outgoing -> | ||||
|                             "Recipient" | ||||
|  | ||||
|                         Nothing -> | ||||
|                             "Correspondent" | ||||
|                     ) | ||||
|             , optional [ Data.Fields.CorrOrg ] <| | ||||
|                 div [ class "field" ] | ||||
|                     [ label [] [ text "Organization" ] | ||||
|                     , Html.map OrgMsg (Comp.Dropdown.view settings model.orgModel) | ||||
|                     ] | ||||
|             , optional [ Data.Fields.CorrPerson ] <| | ||||
|                 div [ class "field" ] | ||||
|                     [ label [] [ text "Person" ] | ||||
|                     , Html.map CorrPersonMsg (Comp.Dropdown.view settings model.corrPersonModel) | ||||
|                     ] | ||||
|             , optional | ||||
|                 [ Data.Fields.ConcPerson | ||||
|                 , Data.Fields.ConcEquip | ||||
|                 ] | ||||
|               <| | ||||
|                 formHeader Icons.concernedIcon "Concerned" | ||||
|             , optional [ Data.Fields.ConcPerson ] <| | ||||
|                 div [ class "field" ] | ||||
|                     [ label [] [ text "Person" ] | ||||
|                     , Html.map ConcPersonMsg (Comp.Dropdown.view settings model.concPersonModel) | ||||
|                     ] | ||||
|             , optional [ Data.Fields.ConcEquip ] <| | ||||
|                 div [ class "field" ] | ||||
|                     [ label [] [ text "Equipment" ] | ||||
|                     , Html.map ConcEquipmentMsg (Comp.Dropdown.view settings model.concEquipmentModel) | ||||
|                     ] | ||||
|             ] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( segmentClass, True ) | ||||
|                 , ( "hidden invisible" | ||||
|                   , fieldHidden Data.Fields.CustomFields | ||||
|                         || Comp.CustomFieldMultiInput.isEmpty model.customFieldModel | ||||
|                   ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ formHeader (Icons.customFieldIcon "") "Custom Fields" | ||||
|             , Html.map CustomFieldMsg | ||||
|                 (Comp.CustomFieldMultiInput.view | ||||
|                     (Comp.CustomFieldMultiInput.ViewSettings False "field" (\_ -> Nothing)) | ||||
|                     model.customFieldModel | ||||
|                 ) | ||||
|             ] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( segmentClass, True ) | ||||
|                 , ( "invisible hidden", fieldHidden Data.Fields.Date && fieldHidden Data.Fields.DueDate ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ optional [ Data.Fields.Date ] <| | ||||
|                 formHeader (Icons.dateIcon "") "Date" | ||||
|             , optional [ Data.Fields.Date ] <| | ||||
|                 div [ class "fields" ] | ||||
|                     [ div [ class "field" ] | ||||
|                         [ label [] | ||||
|                             [ text "From" | ||||
|                             ] | ||||
|                         , Html.map FromDateMsg | ||||
|                             (Comp.DatePicker.viewTimeDefault | ||||
|                                 model.fromDate | ||||
|                                 model.fromDateModel | ||||
|                             ) | ||||
|                         ] | ||||
|                     , div [ class "field" ] | ||||
|                         [ label [] | ||||
|                             [ text "To" | ||||
|                             ] | ||||
|                         , Html.map UntilDateMsg | ||||
|                             (Comp.DatePicker.viewTimeDefault | ||||
|                                 model.untilDate | ||||
|                                 model.untilDateModel | ||||
|                             ) | ||||
|                         ] | ||||
|                     ] | ||||
|             , optional [ Data.Fields.DueDate ] <| | ||||
|                 formHeader (Icons.dueDateIcon "") "Due Date" | ||||
|             , optional [ Data.Fields.DueDate ] <| | ||||
|                 div [ class "fields" ] | ||||
|                     [ div [ class "field" ] | ||||
|                         [ label [] | ||||
|                             [ text "Due From" | ||||
|                             ] | ||||
|                         , Html.map FromDueDateMsg | ||||
|                             (Comp.DatePicker.viewTimeDefault | ||||
|                                 model.fromDueDate | ||||
|                                 model.fromDueDateModel | ||||
|                             ) | ||||
|                         ] | ||||
|                     , div [ class "field" ] | ||||
|                         [ label [] | ||||
|                             [ text "Due To" | ||||
|                             ] | ||||
|                         , Html.map UntilDueDateMsg | ||||
|                             (Comp.DatePicker.viewTimeDefault | ||||
|                                 model.untilDueDate | ||||
|                                 model.untilDueDateModel | ||||
|                             ) | ||||
|                         ] | ||||
|                     ] | ||||
|             ] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( segmentClass, not (fieldHidden Data.Fields.SourceName) ) | ||||
|                 , ( "invisible hidden", fieldHidden Data.Fields.SourceName ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ formHeader (Icons.sourceIcon "") "Source" | ||||
|             , div [ class "field" ] | ||||
|                 [ input | ||||
|                     [ type_ "text" | ||||
|                     , onInput SetSource | ||||
|                     , Util.Html.onKeyUpCode KeyUpMsg | ||||
|                     , model.sourceModel |> Maybe.withDefault "" |> value | ||||
|                     , placeholder "Search in item source…" | ||||
|                     ] | ||||
|                     [] | ||||
|                 ] | ||||
|             ] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( segmentClass, True ) | ||||
|                 , ( "invisible hidden", fieldHidden Data.Fields.Direction ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ formHeader (Icons.directionIcon "") "Direction" | ||||
|             , div [ class "field" ] | ||||
|                 [ Html.map DirectionMsg (Comp.Dropdown.view settings model.directionModel) | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| module Comp.SearchStatsView exposing | ||||
|     ( nameOrLabel | ||||
|     , sortFields | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -26,78 +25,6 @@ sortFields fields = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : SearchStats -> List (Html msg) | ||||
| view stats = | ||||
|     let | ||||
|         isNumField f = | ||||
|             f.sum > 0 | ||||
|  | ||||
|         statValues f = | ||||
|             tr [ class "center aligned" ] | ||||
|                 [ td [ class "left aligned" ] | ||||
|                     [ div [ class "ui basic label" ] | ||||
|                         [ Icons.customFieldTypeIconString "" f.ftype | ||||
|                         , text (nameOrLabel f) | ||||
|                         ] | ||||
|                     ] | ||||
|                 , td [] | ||||
|                     [ f.count |> String.fromInt |> text | ||||
|                     ] | ||||
|                 , td [] | ||||
|                     [ f.sum |> Data.Money.format |> text | ||||
|                     ] | ||||
|                 , td [] | ||||
|                     [ f.avg |> Data.Money.format |> text | ||||
|                     ] | ||||
|                 , td [] | ||||
|                     [ f.min |> Data.Money.format |> text | ||||
|                     ] | ||||
|                 , td [] | ||||
|                     [ f.max |> Data.Money.format |> text | ||||
|                     ] | ||||
|                 ] | ||||
|  | ||||
|         fields = | ||||
|             List.filter isNumField stats.fieldStats | ||||
|                 |> sortFields | ||||
|     in | ||||
|     [ div [ class "ui container" ] | ||||
|         [ div [ class "ui middle aligned stackable grid" ] | ||||
|             [ div [ class "three wide center aligned column" ] | ||||
|                 [ div [ class "ui small statistic" ] | ||||
|                     [ div [ class "value" ] | ||||
|                         [ String.fromInt stats.count |> text | ||||
|                         ] | ||||
|                     , div [ class "label" ] | ||||
|                         [ text "Items" | ||||
|                         ] | ||||
|                     ] | ||||
|                 ] | ||||
|             , div [ class "thirteen wide column" ] | ||||
|                 [ table [ class "ui very basic tiny six column table" ] | ||||
|                     [ thead [] | ||||
|                         [ tr [ class "center aligned" ] | ||||
|                             [ th [] [] | ||||
|                             , th [] [ text "Count" ] | ||||
|                             , th [] [ text "Sum" ] | ||||
|                             , th [] [ text "Avg" ] | ||||
|                             , th [] [ text "Min" ] | ||||
|                             , th [] [ text "Max" ] | ||||
|                             ] | ||||
|                         ] | ||||
|                     , tbody [] | ||||
|                         (List.map statValues fields) | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|     ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -5,7 +5,6 @@ module Comp.SentMails exposing | ||||
|     , initMails | ||||
|     , isEmpty | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -57,88 +56,6 @@ update msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : Model -> Html Msg | ||||
| view model = | ||||
|     case model.selected of | ||||
|         Just mail -> | ||||
|             div [ class "ui blue basic segment" ] | ||||
|                 [ div [ class "ui list" ] | ||||
|                     [ div [ class "item" ] | ||||
|                         [ text "From" | ||||
|                         , div [ class "header" ] | ||||
|                             [ text mail.sender | ||||
|                             , text " (" | ||||
|                             , text mail.connection | ||||
|                             , text ")" | ||||
|                             ] | ||||
|                         ] | ||||
|                     , div [ class "item" ] | ||||
|                         [ text "Date" | ||||
|                         , div [ class "header" ] | ||||
|                             [ Util.Time.formatDateTime mail.created |> text | ||||
|                             ] | ||||
|                         ] | ||||
|                     , div [ class "item" ] | ||||
|                         [ text "Recipients" | ||||
|                         , div [ class "header" ] | ||||
|                             [ String.join ", " mail.recipients |> text | ||||
|                             ] | ||||
|                         ] | ||||
|                     , div [ class "item" ] | ||||
|                         [ text "Subject" | ||||
|                         , div [ class "header" ] | ||||
|                             [ text mail.subject | ||||
|                             ] | ||||
|                         ] | ||||
|                     ] | ||||
|                 , div [ class "ui horizontal divider" ] [] | ||||
|                 , div [ class "mail-body" ] | ||||
|                     [ text mail.body | ||||
|                     ] | ||||
|                 , a | ||||
|                     [ class "ui right corner label" | ||||
|                     , onClick Hide | ||||
|                     , href "#" | ||||
|                     ] | ||||
|                     [ i [ class "close icon" ] [] | ||||
|                     ] | ||||
|                 ] | ||||
|  | ||||
|         Nothing -> | ||||
|             table [ class "ui selectable pointer very basic table" ] | ||||
|                 [ thead [] | ||||
|                     [ tr [] | ||||
|                         [ th [ class "collapsing" ] [ text "Recipients" ] | ||||
|                         , th [] [ text "Subject" ] | ||||
|                         , th [ class "collapsible" ] [ text "Sent" ] | ||||
|                         , th [ class "collapsible" ] [ text "Sender" ] | ||||
|                         ] | ||||
|                     ] | ||||
|                 , tbody [] <| | ||||
|                     List.map | ||||
|                         renderLine | ||||
|                         model.mails | ||||
|                 ] | ||||
|  | ||||
|  | ||||
| renderLine : SentMail -> Html Msg | ||||
| renderLine mail = | ||||
|     tr [ onClick (Show mail) ] | ||||
|         [ td [ class "collapsing" ] | ||||
|             [ String.join ", " mail.recipients |> text | ||||
|             ] | ||||
|         , td [] [ text mail.subject ] | ||||
|         , td [ class "collapsing" ] | ||||
|             [ Util.Time.formatDateTime mail.created |> text | ||||
|             ] | ||||
|         , td [ class "collapsing" ] [ text mail.sender ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -5,7 +5,6 @@ module Comp.SourceForm exposing | ||||
|     , init | ||||
|     , isValid | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -327,141 +326,6 @@ update flags msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : Flags -> UiSettings -> Model -> Html Msg | ||||
| view flags settings model = | ||||
|     let | ||||
|         priorityItem = | ||||
|             Comp.FixedDropdown.Item | ||||
|                 model.priority | ||||
|                 (Data.Priority.toName model.priority) | ||||
|     in | ||||
|     div [ class "ui warning form" ] | ||||
|         [ div | ||||
|             [ classList | ||||
|                 [ ( "field", True ) | ||||
|                 , ( "error", not (isValid model) ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ label [] [ text "Abbrev*" ] | ||||
|             , input | ||||
|                 [ type_ "text" | ||||
|                 , onInput SetAbbrev | ||||
|                 , placeholder "Abbrev" | ||||
|                 , value model.abbrev | ||||
|                 ] | ||||
|                 [] | ||||
|             ] | ||||
|         , div [ class "field" ] | ||||
|             [ label [] [ text "Description" ] | ||||
|             , textarea | ||||
|                 [ onInput SetDescr | ||||
|                 , model.description |> Maybe.withDefault "" |> value | ||||
|                 , rows 3 | ||||
|                 ] | ||||
|                 [] | ||||
|             ] | ||||
|         , div [ class "inline field" ] | ||||
|             [ div [ class "ui checkbox" ] | ||||
|                 [ input | ||||
|                     [ type_ "checkbox" | ||||
|                     , onCheck (\_ -> ToggleEnabled) | ||||
|                     , checked model.enabled | ||||
|                     ] | ||||
|                     [] | ||||
|                 , label [] [ text "Enabled" ] | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "field" ] | ||||
|             [ label [] [ text "Priority" ] | ||||
|             , Html.map PrioDropdownMsg | ||||
|                 (Comp.FixedDropdown.view | ||||
|                     (Just priorityItem) | ||||
|                     model.priorityModel | ||||
|                 ) | ||||
|             , div [ class "small-info" ] | ||||
|                 [ text "The priority used by the scheduler when processing uploaded files." | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "ui dividing header" ] | ||||
|             [ text "Metadata" | ||||
|             ] | ||||
|         , div [ class "ui message" ] | ||||
|             [ text "Metadata specified here is automatically attached to each item uploaded " | ||||
|             , 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 "field" ] | ||||
|             [ label [] | ||||
|                 [ text "Folder" | ||||
|                 ] | ||||
|             , Html.map FolderDropdownMsg (Comp.Dropdown.view settings model.folderModel) | ||||
|             , div [ class "small-info" ] | ||||
|                 [ text "Choose a folder to automatically put items into." | ||||
|                 ] | ||||
|             , div | ||||
|                 [ classList | ||||
|                     [ ( "ui warning message", True ) | ||||
|                     , ( "hidden", isFolderMember model ) | ||||
|                     ] | ||||
|                 ] | ||||
|                 [ Markdown.toHtml [] """ | ||||
| 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 "field" ] | ||||
|             [ label [] [ text "Tags" ] | ||||
|             , Html.map TagDropdownMsg (Comp.Dropdown.view settings model.tagModel) | ||||
|             , div [ class "small-info" ] | ||||
|                 [ text "Choose tags that should be applied to items." | ||||
|                 ] | ||||
|             ] | ||||
|         , div | ||||
|             [ class "field" | ||||
|             ] | ||||
|             [ label [] [ text "File Filter" ] | ||||
|             , input | ||||
|                 [ type_ "text" | ||||
|                 , onInput SetFileFilter | ||||
|                 , placeholder "File Filter" | ||||
|                 , model.fileFilter | ||||
|                     |> Maybe.withDefault "" | ||||
|                     |> value | ||||
|                 ] | ||||
|                 [] | ||||
|             , div [ class "small-info" ] | ||||
|                 [ text "Specify a file glob to filter files when uploading archives " | ||||
|                 , text "(e.g. for email and zip). For example, to only extract pdf files: " | ||||
|                 , code [] | ||||
|                     [ text "*.pdf" | ||||
|                     ] | ||||
|                 , text ". Globs can be combined via OR, like this: " | ||||
|                 , code [] | ||||
|                     [ text "*.pdf|mail.html" | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| isFolderMember : Model -> Bool | ||||
| isFolderMember model = | ||||
|     let | ||||
|         selected = | ||||
|             Comp.Dropdown.getSelected model.folderModel | ||||
|                 |> List.head | ||||
|                 |> Maybe.map .id | ||||
|     in | ||||
|     Util.Folder.isFolderMember model.allFolders selected | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -3,7 +3,6 @@ module Comp.SourceManage exposing | ||||
|     , Msg(..) | ||||
|     , init | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -20,7 +19,7 @@ import Data.Flags exposing (Flags) | ||||
| import Data.UiSettings exposing (UiSettings) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onClick, onSubmit) | ||||
| import Html.Events exposing (onSubmit) | ||||
| import Http | ||||
| import Ports | ||||
| import QRCode | ||||
| @@ -209,7 +208,7 @@ update flags msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
| qrCodeView : String -> Html msg | ||||
| @@ -220,203 +219,6 @@ qrCodeView message = | ||||
|             (Html.text "Error generating QR-Code") | ||||
|  | ||||
|  | ||||
| view : Flags -> UiSettings -> Model -> Html Msg | ||||
| view flags settings model = | ||||
|     case model.viewMode of | ||||
|         None -> | ||||
|             viewTable model | ||||
|  | ||||
|         Edit _ -> | ||||
|             div [] (viewForm flags settings model) | ||||
|  | ||||
|         Display source -> | ||||
|             viewLinks flags settings source | ||||
|  | ||||
|  | ||||
| viewTable : Model -> Html Msg | ||||
| viewTable model = | ||||
|     div [] | ||||
|         [ button [ class "ui basic button", onClick InitNewSource ] | ||||
|             [ i [ class "plus icon" ] [] | ||||
|             , text "Create new" | ||||
|             ] | ||||
|         , Html.map TableMsg (Comp.SourceTable.view model.sources) | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui dimmer", True ) | ||||
|                 , ( "active", model.loading ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ div [ class "ui loader" ] [] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewLinks : Flags -> UiSettings -> SourceAndTags -> Html Msg | ||||
| viewLinks flags _ source = | ||||
|     let | ||||
|         appUrl = | ||||
|             flags.config.baseUrl ++ "/app/upload/" ++ source.source.id | ||||
|  | ||||
|         apiUrl = | ||||
|             flags.config.baseUrl ++ "/api/v1/open/upload/item/" ++ source.source.id | ||||
|     in | ||||
|     div | ||||
|         [] | ||||
|         [ h3 [ class "ui dividing header" ] | ||||
|             [ text "Public Uploads: " | ||||
|             , text source.source.abbrev | ||||
|             , div [ class "sub header" ] | ||||
|                 [ text source.source.id | ||||
|                 ] | ||||
|             ] | ||||
|         , p [] | ||||
|             [ text "This source defines URLs that can be used by anyone to send files to " | ||||
|             , text "you. There is a web page that you can share or the API url can be used " | ||||
|             , text "with other clients." | ||||
|             ] | ||||
|         , p [] | ||||
|             [ text "There have been " | ||||
|             , String.fromInt source.source.counter |> text | ||||
|             , text " items created through this source." | ||||
|             ] | ||||
|         , h4 [ class "ui header" ] | ||||
|             [ text "Public Upload Page" | ||||
|             ] | ||||
|         , div [ class "ui attached message" ] | ||||
|             [ div [ class "ui fluid left action input" ] | ||||
|                 [ a | ||||
|                     [ class "ui left icon button" | ||||
|                     , title "Copy to clipboard" | ||||
|                     , href "#" | ||||
|                     , Tuple.second appClipboardData | ||||
|                         |> String.dropLeft 1 | ||||
|                         |> id | ||||
|                     , attribute "data-clipboard-target" "#app-url" | ||||
|                     ] | ||||
|                     [ i [ class "copy icon" ] [] | ||||
|                     ] | ||||
|                 , a | ||||
|                     [ class "ui icon button" | ||||
|                     , href appUrl | ||||
|                     , target "_blank" | ||||
|                     , title "Open in new tab/window" | ||||
|                     ] | ||||
|                     [ i [ class "link external icon" ] [] | ||||
|                     ] | ||||
|                 , input | ||||
|                     [ type_ "text" | ||||
|                     , id "app-url" | ||||
|                     , value appUrl | ||||
|                     , readonly True | ||||
|                     ] | ||||
|                     [] | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "ui attached segment" ] | ||||
|             [ div [ class "qr-code" ] | ||||
|                 [ qrCodeView appUrl | ||||
|                 ] | ||||
|             ] | ||||
|         , h4 [ class "ui header" ] | ||||
|             [ text "Public API Upload URL" | ||||
|             ] | ||||
|         , div [ class "ui attached message" ] | ||||
|             [ div [ class "ui fluid left action input" ] | ||||
|                 [ a | ||||
|                     [ class "ui left icon button" | ||||
|                     , title "Copy to clipboard" | ||||
|                     , href "#" | ||||
|                     , Tuple.second apiClipboardData | ||||
|                         |> String.dropLeft 1 | ||||
|                         |> id | ||||
|                     , attribute "data-clipboard-target" "#api-url" | ||||
|                     ] | ||||
|                     [ i [ class "copy icon" ] [] | ||||
|                     ] | ||||
|                 , input | ||||
|                     [ type_ "text" | ||||
|                     , value apiUrl | ||||
|                     , readonly True | ||||
|                     , id "api-url" | ||||
|                     ] | ||||
|                     [] | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "ui attached segment" ] | ||||
|             [ div [ class "qr-code" ] | ||||
|                 [ qrCodeView apiUrl | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "ui divider" ] [] | ||||
|         , button | ||||
|             [ class "ui button" | ||||
|             , onClick SetTableView | ||||
|             ] | ||||
|             [ text "Back" | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewForm : Flags -> UiSettings -> Model -> List (Html Msg) | ||||
| viewForm flags settings model = | ||||
|     let | ||||
|         newSource = | ||||
|             model.formModel.source.source.id == "" | ||||
|     in | ||||
|     [ if newSource then | ||||
|         h3 [ class "ui top attached header" ] | ||||
|             [ text "Create new source" | ||||
|             ] | ||||
|  | ||||
|       else | ||||
|         h3 [ class "ui top attached header" ] | ||||
|             [ text ("Edit: " ++ model.formModel.source.source.abbrev) | ||||
|             , div [ class "sub header" ] | ||||
|                 [ text "Id: " | ||||
|                 , text model.formModel.source.source.id | ||||
|                 ] | ||||
|             ] | ||||
|     , Html.form [ class "ui attached segment", onSubmit Submit ] | ||||
|         [ Html.map YesNoMsg (Comp.YesNoDimmer.view model.deleteConfirm) | ||||
|         , Html.map FormMsg (Comp.SourceForm.view flags settings model.formModel) | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui error message", True ) | ||||
|                 , ( "invisible", Util.Maybe.isEmpty model.formError ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ Maybe.withDefault "" model.formError |> text | ||||
|             ] | ||||
|         , div [ class "ui horizontal divider" ] [] | ||||
|         , button [ class "ui primary button", type_ "submit" ] | ||||
|             [ text "Submit" | ||||
|             ] | ||||
|         , a [ class "ui secondary button", onClick SetTableView, href "#" ] | ||||
|             [ text "Cancel" | ||||
|             ] | ||||
|         , if not newSource then | ||||
|             a [ class "ui right floated red button", href "#", onClick RequestDelete ] | ||||
|                 [ text "Delete" ] | ||||
|  | ||||
|           else | ||||
|             span [] [] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui dimmer", True ) | ||||
|                 , ( "active", model.loading ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ div [ class "ui loader" ] [] | ||||
|             ] | ||||
|         ] | ||||
|     ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
| view2 : Flags -> UiSettings -> Model -> Html Msg | ||||
| view2 flags settings model = | ||||
|     case model.viewMode of | ||||
|   | ||||
| @@ -3,7 +3,6 @@ module Comp.SourceTable exposing | ||||
|     , SelectMode(..) | ||||
|     , isEdit | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -13,7 +12,6 @@ import Data.Flags exposing (Flags) | ||||
| import Data.Priority | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onClick) | ||||
| import Styles as S | ||||
| import Util.Html | ||||
|  | ||||
| @@ -53,79 +51,6 @@ update _ msg = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : List SourceAndTags -> Html Msg | ||||
| view sources = | ||||
|     table [ class "ui table" ] | ||||
|         [ thead [] | ||||
|             [ tr [] | ||||
|                 [ th [ class "collapsing" ] [] | ||||
|                 , th [ class "collapsing" ] [ text "Abbrev" ] | ||||
|                 , th [ class "collapsing" ] [ text "Enabled" ] | ||||
|                 , th [ class "collapsing" ] [ text "Counter" ] | ||||
|                 , th [ class "collapsing" ] [ text "Priority" ] | ||||
|                 , th [] [ text "Id" ] | ||||
|                 ] | ||||
|             ] | ||||
|         , tbody [] | ||||
|             (List.map renderSourceLine sources) | ||||
|         ] | ||||
|  | ||||
|  | ||||
| renderSourceLine : SourceAndTags -> Html Msg | ||||
| renderSourceLine source = | ||||
|     tr | ||||
|         [] | ||||
|         [ td [ class "collapsing" ] | ||||
|             [ a | ||||
|                 [ class "ui basic tiny primary button" | ||||
|                 , href "#" | ||||
|                 , onClick (Select source) | ||||
|                 ] | ||||
|                 [ i [ class "edit icon" ] [] | ||||
|                 , text "Edit" | ||||
|                 ] | ||||
|             , a | ||||
|                 [ classList | ||||
|                     [ ( "ui basic tiny primary button", True ) | ||||
|                     , ( "disabled", not source.source.enabled ) | ||||
|                     ] | ||||
|                 , href "#" | ||||
|                 , disabled (not source.source.enabled) | ||||
|                 , onClick (Show source) | ||||
|                 ] | ||||
|                 [ i [ class "eye icon" ] [] | ||||
|                 , text "Show" | ||||
|                 ] | ||||
|             ] | ||||
|         , td [ class "collapsing" ] | ||||
|             [ text source.source.abbrev | ||||
|             ] | ||||
|         , td [ class "collapsing" ] | ||||
|             [ if source.source.enabled then | ||||
|                 i [ class "check square outline icon" ] [] | ||||
|  | ||||
|               else | ||||
|                 i [ class "minus square outline icon" ] [] | ||||
|             ] | ||||
|         , td [ class "collapsing" ] | ||||
|             [ source.source.counter |> String.fromInt |> text | ||||
|             ] | ||||
|         , td [ class "collapsing" ] | ||||
|             [ Data.Priority.fromString source.source.priority | ||||
|                 |> Maybe.map Data.Priority.toName | ||||
|                 |> Maybe.withDefault source.source.priority | ||||
|                 |> text | ||||
|             ] | ||||
|         , td [] | ||||
|             [ text source.source.id | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -4,7 +4,6 @@ module Comp.StringListInput exposing | ||||
|     , Msg | ||||
|     , init | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -62,45 +61,6 @@ update msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : List String -> Model -> Html Msg | ||||
| view values model = | ||||
|     let | ||||
|         valueItem s = | ||||
|             div [ class "item" ] | ||||
|                 [ a | ||||
|                     [ class "ui icon link" | ||||
|                     , onClick (RemoveString s) | ||||
|                     , href "#" | ||||
|                     ] | ||||
|                     [ i [ class "delete icon" ] [] | ||||
|                     ] | ||||
|                 , text s | ||||
|                 ] | ||||
|     in | ||||
|     div [ class "string-list-input" ] | ||||
|         [ div [ class "ui list" ] | ||||
|             (List.map valueItem values) | ||||
|         , div [ class "ui icon input" ] | ||||
|             [ input | ||||
|                 [ placeholder "" | ||||
|                 , type_ "text" | ||||
|                 , onInput SetString | ||||
|                 , value model.currentInput | ||||
|                 ] | ||||
|                 [] | ||||
|             , i | ||||
|                 [ class "circular add link icon" | ||||
|                 , onClick AddString | ||||
|                 ] | ||||
|                 [] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -5,7 +5,6 @@ module Comp.TagForm exposing | ||||
|     , getTag | ||||
|     , isValid | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -117,30 +116,8 @@ update _ msg model = | ||||
|             ( { model | catDropdown = dm_ }, Cmd.map CatMsg cmd_ ) | ||||
|  | ||||
|  | ||||
| view : Model -> Html Msg | ||||
| view model = | ||||
|     div [ class "ui form" ] | ||||
|         [ div | ||||
|             [ classList | ||||
|                 [ ( "field", True ) | ||||
|                 , ( "error", not (isValid model) ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ label [] [ text "Name*" ] | ||||
|             , input | ||||
|                 [ type_ "text" | ||||
|                 , onInput SetName | ||||
|                 , placeholder "Name" | ||||
|                 , value model.name | ||||
|                 ] | ||||
|                 [] | ||||
|             ] | ||||
|         , div [ class "field" ] | ||||
|             [ label [] | ||||
|                 [ text "Category" ] | ||||
|             , Html.map CatMsg (Comp.Dropdown.viewSingle model.catDropdown) | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
| view2 : Model -> Html Msg | ||||
|   | ||||
| @@ -3,7 +3,6 @@ module Comp.TagManage exposing | ||||
|     , Msg(..) | ||||
|     , emptyModel | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -19,7 +18,7 @@ import Comp.YesNoDimmer | ||||
| import Data.Flags exposing (Flags) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onClick, onInput, onSubmit) | ||||
| import Html.Events exposing (onSubmit) | ||||
| import Http | ||||
| import Styles as S | ||||
| import Util.Http | ||||
| @@ -56,11 +55,6 @@ emptyModel = | ||||
|     } | ||||
|  | ||||
|  | ||||
| dimmerSettings : Comp.YesNoDimmer.Settings | ||||
| dimmerSettings = | ||||
|     Comp.YesNoDimmer.defaultSettings | ||||
|  | ||||
|  | ||||
| type Msg | ||||
|     = TableMsg Comp.TagTable.Msg | ||||
|     | FormMsg Comp.TagForm.Msg | ||||
| @@ -215,109 +209,8 @@ update flags msg model = | ||||
|             ( m, Api.getTags flags str TagResp ) | ||||
|  | ||||
|  | ||||
| view : Model -> Html Msg | ||||
| view model = | ||||
|     if model.viewMode == Table then | ||||
|         viewTable model | ||||
|  | ||||
|     else | ||||
|         viewForm model | ||||
|  | ||||
|  | ||||
| viewTable : Model -> Html Msg | ||||
| viewTable model = | ||||
|     div [] | ||||
|         [ div [ class "ui secondary menu" ] | ||||
|             [ div [ class "horizontally fitted item" ] | ||||
|                 [ div [ class "ui icon input" ] | ||||
|                     [ input | ||||
|                         [ type_ "text" | ||||
|                         , onInput SetQuery | ||||
|                         , value model.query | ||||
|                         , placeholder "Search…" | ||||
|                         ] | ||||
|                         [] | ||||
|                     , i [ class "ui search icon" ] | ||||
|                         [] | ||||
|                     ] | ||||
|                 ] | ||||
|             , div [ class "right menu" ] | ||||
|                 [ div [ class "item" ] | ||||
|                     [ a | ||||
|                         [ class "ui primary button" | ||||
|                         , href "#" | ||||
|                         , onClick InitNewTag | ||||
|                         ] | ||||
|                         [ i [ class "plus icon" ] [] | ||||
|                         , text "New Tag" | ||||
|                         ] | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         , Html.map TableMsg (Comp.TagTable.view model.tagTableModel) | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui dimmer", True ) | ||||
|                 , ( "active", model.loading ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ div [ class "ui loader" ] [] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewForm : Model -> Html Msg | ||||
| viewForm model = | ||||
|     let | ||||
|         newTag = | ||||
|             model.tagFormModel.tag.id == "" | ||||
|     in | ||||
|     Html.form [ class "ui segment", onSubmit Submit ] | ||||
|         [ Html.map YesNoMsg (Comp.YesNoDimmer.view model.deleteConfirm) | ||||
|         , if newTag then | ||||
|             h3 [ class "ui dividing header" ] | ||||
|                 [ text "Create new tag" | ||||
|                 ] | ||||
|  | ||||
|           else | ||||
|             h3 [ class "ui dividing header" ] | ||||
|                 [ text ("Edit tag: " ++ model.tagFormModel.tag.name) | ||||
|                 , div [ class "sub header" ] | ||||
|                     [ text "Id: " | ||||
|                     , text model.tagFormModel.tag.id | ||||
|                     ] | ||||
|                 ] | ||||
|         , Html.map FormMsg (Comp.TagForm.view model.tagFormModel) | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui error message", True ) | ||||
|                 , ( "invisible", Util.Maybe.isEmpty model.formError ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ Maybe.withDefault "" model.formError |> text | ||||
|             ] | ||||
|         , div [ class "ui horizontal divider" ] [] | ||||
|         , button [ class "ui primary button", type_ "submit" ] | ||||
|             [ text "Submit" | ||||
|             ] | ||||
|         , a [ class "ui secondary button", onClick (SetViewMode Table), href "#" ] | ||||
|             [ text "Cancel" | ||||
|             ] | ||||
|         , if not newTag then | ||||
|             a [ class "ui right floated red button", href "#", onClick RequestDelete ] | ||||
|                 [ text "Delete" ] | ||||
|  | ||||
|           else | ||||
|             span [] [] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui dimmer", True ) | ||||
|                 , ( "active", model.loading ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ div [ class "ui loader" ] [] | ||||
|             ] | ||||
|         ] | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
| view2 : Model -> Html Msg | ||||
|   | ||||
| @@ -13,7 +13,6 @@ module Comp.TagSelect exposing | ||||
|     , toggleTag | ||||
|     , update | ||||
|     , updateDrop | ||||
|     , viewAll | ||||
|     , viewAll2 | ||||
|     , viewCats2 | ||||
|     , viewTagsDrop2 | ||||
| @@ -420,229 +419,6 @@ catState model name = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| viewAll : DD.Model -> UiSettings -> Selection -> Model -> List (Html Msg) | ||||
| viewAll ddm settings sel model = | ||||
|     let | ||||
|         wm = | ||||
|             makeWorkModel sel model | ||||
|     in | ||||
|     viewTagsDrop ddm wm settings model ++ [ viewCats settings wm model ] | ||||
|  | ||||
|  | ||||
| viewTagsDrop : DD.Model -> WorkModel -> UiSettings -> Model -> List (Html Msg) | ||||
| viewTagsDrop ddm wm settings model = | ||||
|     [ div [ class "ui tiny fluid secondary menu" ] | ||||
|         [ a | ||||
|             [ class "borderless item" | ||||
|             , href "#" | ||||
|             , onClick ToggleShowEmpty | ||||
|             ] | ||||
|             [ if model.showEmpty then | ||||
|                 text " Hide empty" | ||||
|  | ||||
|               else | ||||
|                 text " Show empty" | ||||
|             ] | ||||
|         , div [ class "right menu" ] | ||||
|             [ div [ class "right fitted item width-80" ] | ||||
|                 [ div [ class "ui small transparent icon input" ] | ||||
|                     [ input | ||||
|                         [ type_ "text" | ||||
|                         , placeholder "Filter …" | ||||
|                         , onInput Search | ||||
|                         ] | ||||
|                         [] | ||||
|                     , i [ class "search icon" ] [] | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|     , div [ class "ui list" ] | ||||
|         [ div [ class "item" ] | ||||
|             [ I.tagIcon "" | ||||
|             , div [ class "content" ] | ||||
|                 [ div [ class "header" ] | ||||
|                     [ text "Tags" | ||||
|                     ] | ||||
|                 , div [ class "ui relaxed list" ] | ||||
|                     (renderTagItems ddm settings model wm) | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|     ] | ||||
|  | ||||
|  | ||||
| viewCats : UiSettings -> WorkModel -> Model -> Html Msg | ||||
| viewCats settings wm model = | ||||
|     div [ class "ui list" ] | ||||
|         [ div [ class "item" ] | ||||
|             [ I.tagsIcon "" | ||||
|             , div [ class "content" ] | ||||
|                 [ div [ class "header" ] | ||||
|                     [ text "Categories" | ||||
|                     ] | ||||
|                 , div [ class "ui relaxed list" ] | ||||
|                     (renderCatItems settings model wm) | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| renderTagItems : DD.Model -> UiSettings -> Model -> WorkModel -> List (Html Msg) | ||||
| renderTagItems ddm settings model wm = | ||||
|     let | ||||
|         tags = | ||||
|             wm.filteredTags | ||||
|  | ||||
|         max = | ||||
|             settings.searchMenuTagCount | ||||
|  | ||||
|         expLink = | ||||
|             Util.ExpandCollapse.expandToggle | ||||
|                 max | ||||
|                 (List.length tags) | ||||
|                 ToggleExpandTags | ||||
|  | ||||
|         cpsLink = | ||||
|             Util.ExpandCollapse.collapseToggle | ||||
|                 max | ||||
|                 (List.length tags) | ||||
|                 ToggleExpandTags | ||||
|     in | ||||
|     if max <= 0 then | ||||
|         List.map (viewTagItem ddm settings wm) tags | ||||
|  | ||||
|     else if model.expandedTags then | ||||
|         List.map (viewTagItem ddm settings wm) tags ++ cpsLink | ||||
|  | ||||
|     else | ||||
|         List.map (viewTagItem ddm settings wm) (List.take max tags) ++ expLink | ||||
|  | ||||
|  | ||||
| renderCatItems : UiSettings -> Model -> WorkModel -> List (Html Msg) | ||||
| renderCatItems settings model wm = | ||||
|     let | ||||
|         cats = | ||||
|             wm.filteredCats | ||||
|  | ||||
|         max = | ||||
|             settings.searchMenuTagCatCount | ||||
|  | ||||
|         expLink = | ||||
|             Util.ExpandCollapse.expandToggle | ||||
|                 max | ||||
|                 (List.length cats) | ||||
|                 ToggleExpandCats | ||||
|  | ||||
|         cpsLink = | ||||
|             Util.ExpandCollapse.collapseToggle | ||||
|                 max | ||||
|                 (List.length cats) | ||||
|                 ToggleExpandCats | ||||
|     in | ||||
|     if max <= 0 then | ||||
|         List.map (viewCategoryItem settings wm) cats | ||||
|  | ||||
|     else if model.expandedCats then | ||||
|         List.map (viewCategoryItem settings wm) cats ++ cpsLink | ||||
|  | ||||
|     else | ||||
|         List.map (viewCategoryItem settings wm) (List.take max cats) ++ expLink | ||||
|  | ||||
|  | ||||
| viewCategoryItem : UiSettings -> WorkModel -> Category -> Html Msg | ||||
| viewCategoryItem settings model cat = | ||||
|     let | ||||
|         state = | ||||
|             catState model cat.name | ||||
|  | ||||
|         color = | ||||
|             Data.UiSettings.catColorString settings cat.name | ||||
|  | ||||
|         icon = | ||||
|             getIcon state color I.tagsIcon | ||||
|     in | ||||
|     a | ||||
|         [ class "item" | ||||
|         , href "#" | ||||
|         , onClick (ToggleCat cat.name) | ||||
|         ] | ||||
|         [ icon | ||||
|         , div [ class "content" ] | ||||
|             [ div | ||||
|                 [ classList | ||||
|                     [ ( "header", state == Include ) | ||||
|                     , ( "description", state /= Include ) | ||||
|                     ] | ||||
|                 ] | ||||
|                 [ text cat.name | ||||
|                 , div [ class "ui right floated circular label" ] | ||||
|                     [ text (String.fromInt cat.count) | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewTagItem : DD.Model -> UiSettings -> WorkModel -> TagCount -> Html Msg | ||||
| viewTagItem ddm settings model tag = | ||||
|     let | ||||
|         state = | ||||
|             tagState model tag.tag.id | ||||
|  | ||||
|         color = | ||||
|             Data.UiSettings.tagColorString tag.tag settings | ||||
|  | ||||
|         icon = | ||||
|             getIcon state color I.tagIcon | ||||
|  | ||||
|         dropActive = | ||||
|             DD.getDropId ddm == Just (DD.Tag tag.tag.id) | ||||
|     in | ||||
|     a | ||||
|         ([ classList | ||||
|             [ ( "item", True ) | ||||
|             , ( "current-drop-target", dropActive ) | ||||
|             ] | ||||
|          , href "#" | ||||
|          , onClick (ToggleTag tag.tag.id) | ||||
|          ] | ||||
|             ++ DD.droppable TagDDMsg (DD.Tag tag.tag.id) | ||||
|         ) | ||||
|         [ icon | ||||
|         , div [ class "content" ] | ||||
|             [ div | ||||
|                 [ classList | ||||
|                     [ ( "header", state == Include ) | ||||
|                     , ( "description", state /= Include ) | ||||
|                     ] | ||||
|                 ] | ||||
|                 [ text tag.tag.name | ||||
|                 , div [ class "ui right floated circular label" ] | ||||
|                     [ text (String.fromInt tag.count) | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| getIcon : SelState -> String -> (String -> Html msg) -> Html msg | ||||
| getIcon state color default = | ||||
|     case state of | ||||
|         Include -> | ||||
|             i [ class ("check icon " ++ color) ] [] | ||||
|  | ||||
|         Exclude -> | ||||
|             i [ class ("minus icon " ++ color) ] [] | ||||
|  | ||||
|         Deselect -> | ||||
|             default color | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -3,7 +3,6 @@ module Comp.TagTable exposing | ||||
|     , Msg(..) | ||||
|     , emptyModel | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -12,7 +11,6 @@ import Comp.Basic as B | ||||
| import Data.Flags exposing (Flags) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onClick) | ||||
| import Styles as S | ||||
|  | ||||
|  | ||||
| @@ -48,44 +46,6 @@ update _ msg model = | ||||
|             ( { model | selected = Nothing }, Cmd.none ) | ||||
|  | ||||
|  | ||||
| view : Model -> Html Msg | ||||
| view model = | ||||
|     table [ class "ui very basic aligned table" ] | ||||
|         [ thead [] | ||||
|             [ tr [] | ||||
|                 [ th [ class "collapsing" ] [] | ||||
|                 , th [ class "eight wide" ] [ text "Name" ] | ||||
|                 , th [] [ text "Category" ] | ||||
|                 ] | ||||
|             ] | ||||
|         , tbody [] | ||||
|             (List.map (renderTagLine model) model.tags) | ||||
|         ] | ||||
|  | ||||
|  | ||||
| renderTagLine : Model -> Tag -> Html Msg | ||||
| renderTagLine model tag = | ||||
|     tr | ||||
|         [] | ||||
|         [ td [ class "collapsing" ] | ||||
|             [ a | ||||
|                 [ href "#" | ||||
|                 , class "ui basic small blue label" | ||||
|                 , onClick (Select tag) | ||||
|                 ] | ||||
|                 [ i [ class "edit icon" ] [] | ||||
|                 , text "Edit" | ||||
|                 ] | ||||
|             ] | ||||
|         , td [] | ||||
|             [ text tag.name | ||||
|             ] | ||||
|         , td [] | ||||
|             [ Maybe.withDefault "-" tag.category |> text | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|   | ||||
| @@ -3,7 +3,6 @@ module Comp.UiSettingsForm exposing | ||||
|     , Msg | ||||
|     , init | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -24,7 +23,7 @@ import Data.UiSettings exposing (ItemPattern, Pos(..), UiSettings) | ||||
| import Dict exposing (Dict) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onCheck, onClick, onInput) | ||||
| import Html.Events exposing (onClick, onInput) | ||||
| import Http | ||||
| import Markdown | ||||
| import Set exposing (Set) | ||||
| @@ -41,7 +40,6 @@ type alias Model = | ||||
|     , nativePdfPreview : Bool | ||||
|     , itemSearchNoteLength : Maybe Int | ||||
|     , searchNoteLengthModel : Comp.IntField.Model | ||||
|     , itemDetailNotesPosition : Pos | ||||
|     , searchMenuFolderCount : Maybe Int | ||||
|     , searchMenuFolderCountModel : Comp.IntField.Model | ||||
|     , searchMenuTagCount : Maybe Int | ||||
| @@ -50,7 +48,6 @@ type alias Model = | ||||
|     , searchMenuTagCatCountModel : Comp.IntField.Model | ||||
|     , formFields : List Field | ||||
|     , itemDetailShortcuts : Bool | ||||
|     , searchMenuVisible : Bool | ||||
|     , editMenuVisible : Bool | ||||
|     , cardPreviewSize : BasicSize | ||||
|     , cardTitlePattern : PatternModel | ||||
| @@ -120,7 +117,6 @@ init flags settings = | ||||
|                 (Just flags.config.maxNoteLength) | ||||
|                 False | ||||
|                 "Max. Note Length" | ||||
|       , itemDetailNotesPosition = settings.itemDetailNotesPosition | ||||
|       , searchMenuFolderCount = Just settings.searchMenuFolderCount | ||||
|       , searchMenuFolderCountModel = | ||||
|             Comp.IntField.init | ||||
| @@ -144,7 +140,6 @@ init flags settings = | ||||
|                 "Number of categories in search menu" | ||||
|       , formFields = settings.formFields | ||||
|       , itemDetailShortcuts = settings.itemDetailShortcuts | ||||
|       , searchMenuVisible = settings.searchMenuVisible | ||||
|       , editMenuVisible = settings.editMenuVisible | ||||
|       , cardPreviewSize = settings.cardPreviewSize | ||||
|       , cardTitlePattern = initPatternModel settings.cardTitleTemplate | ||||
| @@ -165,13 +160,11 @@ type Msg | ||||
|     | GetTagsResp (Result Http.Error TagList) | ||||
|     | TogglePdfPreview | ||||
|     | NoteLengthMsg Comp.IntField.Msg | ||||
|     | SetNotesPosition Pos | ||||
|     | SearchMenuFolderMsg Comp.IntField.Msg | ||||
|     | SearchMenuTagMsg Comp.IntField.Msg | ||||
|     | SearchMenuTagCatMsg Comp.IntField.Msg | ||||
|     | FieldListMsg Comp.FieldListSelect.Msg | ||||
|     | ToggleItemDetailShortcuts | ||||
|     | ToggleSearchMenuVisible | ||||
|     | ToggleEditMenuVisible | ||||
|     | CardPreviewSizeMsg Comp.BasicSizeField.Msg | ||||
|     | SetCardTitlePattern String | ||||
| @@ -270,17 +263,6 @@ update sett msg model = | ||||
|             in | ||||
|             ( model_, nextSettings ) | ||||
|  | ||||
|         SetNotesPosition pos -> | ||||
|             let | ||||
|                 model_ = | ||||
|                     { model | itemDetailNotesPosition = pos } | ||||
|             in | ||||
|             if model_.itemDetailNotesPosition == sett.itemDetailNotesPosition then | ||||
|                 ( model_, Nothing ) | ||||
|  | ||||
|             else | ||||
|                 ( model_, Just { sett | itemDetailNotesPosition = model_.itemDetailNotesPosition } ) | ||||
|  | ||||
|         TagColorMsg lm -> | ||||
|             let | ||||
|                 ( m_, d_ ) = | ||||
| @@ -348,15 +330,6 @@ update sett msg model = | ||||
|             , Just { sett | itemDetailShortcuts = flag } | ||||
|             ) | ||||
|  | ||||
|         ToggleSearchMenuVisible -> | ||||
|             let | ||||
|                 flag = | ||||
|                     not model.searchMenuVisible | ||||
|             in | ||||
|             ( { model | searchMenuVisible = flag } | ||||
|             , Just { sett | searchMenuVisible = flag } | ||||
|             ) | ||||
|  | ||||
|         ToggleEditMenuVisible -> | ||||
|             let | ||||
|                 flag = | ||||
| @@ -474,235 +447,6 @@ update sett msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| tagColorViewOpts : Comp.ColorTagger.ViewOpts | ||||
| tagColorViewOpts = | ||||
|     { renderItem = | ||||
|         \( k, v ) -> | ||||
|             span [ class ("ui label " ++ Data.Color.toString v) ] | ||||
|                 [ text k ] | ||||
|     , label = "Choose color for tag categories" | ||||
|     , description = Just "Tags can be represented differently based on their category." | ||||
|     } | ||||
|  | ||||
|  | ||||
| view : Flags -> UiSettings -> Model -> Html Msg | ||||
| view flags _ model = | ||||
|     div [ class "ui form" ] | ||||
|         [ div [ class "ui dividing header" ] | ||||
|             [ text "Item Search" | ||||
|             ] | ||||
|         , Html.map SearchPageSizeMsg | ||||
|             (Comp.IntField.viewWithInfo | ||||
|                 ("Maximum results in one page when searching items. At most " | ||||
|                     ++ String.fromInt flags.config.maxPageSize | ||||
|                     ++ "." | ||||
|                 ) | ||||
|                 model.itemSearchPageSize | ||||
|                 "field" | ||||
|                 model.searchPageSizeModel | ||||
|             ) | ||||
|         , div [ class "field" ] | ||||
|             [ div [ class "ui checkbox" ] | ||||
|                 [ input | ||||
|                     [ type_ "checkbox" | ||||
|                     , onCheck (\_ -> ToggleSearchStatsVisible) | ||||
|                     , checked model.searchStatsVisible | ||||
|                     ] | ||||
|                     [] | ||||
|                 , label [] | ||||
|                     [ text "Show basic search statistics by default" | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "ui dividing header" ] | ||||
|             [ text "Item Cards" | ||||
|             ] | ||||
|         , Html.map NoteLengthMsg | ||||
|             (Comp.IntField.viewWithInfo | ||||
|                 ("Maximum size of the item notes to display in card view. Between 0 - " | ||||
|                     ++ String.fromInt flags.config.maxNoteLength | ||||
|                     ++ "." | ||||
|                 ) | ||||
|                 model.itemSearchNoteLength | ||||
|                 "field" | ||||
|                 model.searchNoteLengthModel | ||||
|             ) | ||||
|         , Html.map CardPreviewSizeMsg | ||||
|             (Comp.BasicSizeField.view | ||||
|                 "Size of item preview" | ||||
|                 model.cardPreviewSize | ||||
|             ) | ||||
|         , div [ class "field" ] | ||||
|             [ label [] | ||||
|                 [ text "Card Title Pattern" | ||||
|                 , a | ||||
|                     [ class "right-float" | ||||
|                     , title "Toggle pattern help text" | ||||
|                     , href "#" | ||||
|                     , onClick TogglePatternHelpMsg | ||||
|                     ] | ||||
|                     [ i [ class "help link icon" ] [] | ||||
|                     ] | ||||
|                 ] | ||||
|             , input | ||||
|                 [ type_ "text" | ||||
|                 , Maybe.withDefault "" model.cardTitlePattern.pattern |> value | ||||
|                 , onInput SetCardTitlePattern | ||||
|                 ] | ||||
|                 [] | ||||
|             ] | ||||
|         , div [ class "field" ] | ||||
|             [ label [] | ||||
|                 [ text "Card Subtitle Pattern" | ||||
|                 , a | ||||
|                     [ class "right-float" | ||||
|                     , title "Toggle pattern help text" | ||||
|                     , href "#" | ||||
|                     , onClick TogglePatternHelpMsg | ||||
|                     ] | ||||
|                     [ i [ class "help link icon" ] [] | ||||
|                     ] | ||||
|                 ] | ||||
|             , input | ||||
|                 [ type_ "text" | ||||
|                 , Maybe.withDefault "" model.cardSubtitlePattern.pattern |> value | ||||
|                 , onInput SetCardSubtitlePattern | ||||
|                 ] | ||||
|                 [] | ||||
|             ] | ||||
|         , Markdown.toHtml | ||||
|             [ classList | ||||
|                 [ ( "ui message", True ) | ||||
|                 , ( "hidden", not model.showPatternHelp ) | ||||
|                 ] | ||||
|             ] | ||||
|             IT.helpMessage | ||||
|         , div [ class "ui dividing header" ] | ||||
|             [ text "Search Menu" ] | ||||
|         , div [ class "field" ] | ||||
|             [ div [ class "ui checkbox" ] | ||||
|                 [ input | ||||
|                     [ type_ "checkbox" | ||||
|                     , onCheck (\_ -> ToggleSearchMenuVisible) | ||||
|                     , checked model.searchMenuVisible | ||||
|                     ] | ||||
|                     [] | ||||
|                 , label [] | ||||
|                     [ text "Show search side menu by default" | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         , Html.map SearchMenuTagMsg | ||||
|             (Comp.IntField.viewWithInfo | ||||
|                 "How many tags to display in search menu at once. Others can be expanded. Use 0 to always show all." | ||||
|                 model.searchMenuTagCount | ||||
|                 "field" | ||||
|                 model.searchMenuTagCountModel | ||||
|             ) | ||||
|         , Html.map SearchMenuTagCatMsg | ||||
|             (Comp.IntField.viewWithInfo | ||||
|                 "How many categories to display in search menu at once. Others can be expanded. Use 0 to always show all." | ||||
|                 model.searchMenuTagCatCount | ||||
|                 "field" | ||||
|                 model.searchMenuTagCatCountModel | ||||
|             ) | ||||
|         , Html.map SearchMenuFolderMsg | ||||
|             (Comp.IntField.viewWithInfo | ||||
|                 "How many folders to display in search menu at once. Other folders can be expanded. Use 0 to always show all." | ||||
|                 model.searchMenuFolderCount | ||||
|                 "field" | ||||
|                 model.searchMenuFolderCountModel | ||||
|             ) | ||||
|         , div [ class "ui dividing header" ] | ||||
|             [ text "Item Detail" | ||||
|             ] | ||||
|         , div [ class "field" ] | ||||
|             [ div [ class "ui checkbox" ] | ||||
|                 [ input | ||||
|                     [ type_ "checkbox" | ||||
|                     , onCheck (\_ -> TogglePdfPreview) | ||||
|                     , checked model.nativePdfPreview | ||||
|                     ] | ||||
|                     [] | ||||
|                 , label [] | ||||
|                     [ text "Browser-native PDF preview" | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "field" ] | ||||
|             [ div [ class "ui checkbox" ] | ||||
|                 [ input | ||||
|                     [ type_ "checkbox" | ||||
|                     , onCheck (\_ -> ToggleItemDetailShortcuts) | ||||
|                     , checked model.itemDetailShortcuts | ||||
|                     ] | ||||
|                     [] | ||||
|                 , label [] | ||||
|                     [ text "Use keyboard shortcuts for navigation and confirm/unconfirm with open edit menu." | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "field" ] | ||||
|             [ div [ class "ui checkbox" ] | ||||
|                 [ input | ||||
|                     [ type_ "checkbox" | ||||
|                     , onCheck (\_ -> ToggleEditMenuVisible) | ||||
|                     , checked model.editMenuVisible | ||||
|                     ] | ||||
|                     [] | ||||
|                 , label [] | ||||
|                     [ text "Show edit side menu by default" | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "grouped fields" ] | ||||
|             [ label [] [ text "Position of item notes" ] | ||||
|             , div [ class "field" ] | ||||
|                 [ div [ class "ui radio checkbox" ] | ||||
|                     [ input | ||||
|                         [ type_ "radio" | ||||
|                         , checked (model.itemDetailNotesPosition == Top) | ||||
|                         , onCheck (\_ -> SetNotesPosition Top) | ||||
|                         ] | ||||
|                         [] | ||||
|                     , label [] [ text "Top" ] | ||||
|                     ] | ||||
|                 ] | ||||
|             , div [ class "field" ] | ||||
|                 [ div [ class "ui radio checkbox" ] | ||||
|                     [ input | ||||
|                         [ type_ "radio" | ||||
|                         , checked (model.itemDetailNotesPosition == Bottom) | ||||
|                         , onCheck (\_ -> SetNotesPosition Bottom) | ||||
|                         ] | ||||
|                         [] | ||||
|                     , label [] [ text "Bottom" ] | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "ui dividing header" ] | ||||
|             [ text "Tag Category Colors" | ||||
|             ] | ||||
|         , Html.map TagColorMsg | ||||
|             (Comp.ColorTagger.view | ||||
|                 model.tagColors | ||||
|                 tagColorViewOpts | ||||
|                 model.tagColorModel | ||||
|             ) | ||||
|         , div [ class "ui dividing header" ] | ||||
|             [ text "Fields" | ||||
|             ] | ||||
|         , span [ class "small-info" ] | ||||
|             [ text "Choose which fields to display in search and edit menus." | ||||
|             ] | ||||
|         , Html.map FieldListMsg (Comp.FieldListSelect.view model.formFields) | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -3,7 +3,6 @@ module Comp.UiSettingsManage exposing | ||||
|     , Msg(..) | ||||
|     , init | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -113,7 +112,7 @@ update flags settings msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
| isError : Model -> Bool | ||||
| @@ -126,36 +125,6 @@ isSuccess model = | ||||
|     Maybe.map .success model.message == Just True | ||||
|  | ||||
|  | ||||
| view : Flags -> UiSettings -> String -> Model -> Html Msg | ||||
| view flags settings classes model = | ||||
|     div [ class classes ] | ||||
|         [ Html.map UiSettingsFormMsg (Comp.UiSettingsForm.view flags settings model.formModel) | ||||
|         , div [ class "ui divider" ] [] | ||||
|         , button | ||||
|             [ class "ui primary button" | ||||
|             , onClick Submit | ||||
|             ] | ||||
|             [ text "Submit" | ||||
|             ] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui message", True ) | ||||
|                 , ( "success", isSuccess model ) | ||||
|                 , ( "error", isError model ) | ||||
|                 , ( "hidden invisible", model.message == Nothing ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ Maybe.map .message model.message | ||||
|                 |> Maybe.withDefault "" | ||||
|                 |> text | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
| view2 : Flags -> UiSettings -> String -> Model -> Html Msg | ||||
| view2 flags settings classes model = | ||||
|     div [ class classes ] | ||||
|   | ||||
| @@ -6,7 +6,6 @@ module Comp.UserForm exposing | ||||
|     , isNewUser | ||||
|     , isValid | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -164,61 +163,6 @@ update _ msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : UiSettings -> Model -> Html Msg | ||||
| view settings model = | ||||
|     div [ class "ui form" ] | ||||
|         [ div | ||||
|             [ classList | ||||
|                 [ ( "field", True ) | ||||
|                 , ( "error", model.login == "" ) | ||||
|                 , ( "invisible", model.user.login /= "" ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ label [] [ text "Login*" ] | ||||
|             , input | ||||
|                 [ type_ "text" | ||||
|                 , onInput SetLogin | ||||
|                 , placeholder "Login" | ||||
|                 , value model.login | ||||
|                 ] | ||||
|                 [] | ||||
|             ] | ||||
|         , div [ class "field" ] | ||||
|             [ label [] [ text "E-Mail" ] | ||||
|             , input | ||||
|                 [ onInput SetEmail | ||||
|                 , model.email |> Maybe.withDefault "" |> value | ||||
|                 , placeholder "E-Mail" | ||||
|                 ] | ||||
|                 [] | ||||
|             ] | ||||
|         , div [ class "field" ] | ||||
|             [ label [] [ text "State" ] | ||||
|             , Html.map StateMsg (Comp.Dropdown.view settings model.state) | ||||
|             ] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "field", True ) | ||||
|                 , ( "invisible", model.user.login /= "" ) | ||||
|                 , ( "error", Util.Maybe.isEmpty model.password ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ label [] [ text "Password*" ] | ||||
|             , input | ||||
|                 [ type_ "text" | ||||
|                 , onInput SetPassword | ||||
|                 , placeholder "Password" | ||||
|                 , Maybe.withDefault "" model.password |> value | ||||
|                 ] | ||||
|                 [] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -3,7 +3,6 @@ module Comp.UserManage exposing | ||||
|     , Msg(..) | ||||
|     , emptyModel | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -20,7 +19,7 @@ import Data.Flags exposing (Flags) | ||||
| import Data.UiSettings exposing (UiSettings) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onClick, onSubmit) | ||||
| import Html.Events exposing (onSubmit) | ||||
| import Http | ||||
| import Styles as S | ||||
| import Util.Http | ||||
| @@ -200,88 +199,6 @@ update flags msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : UiSettings -> Model -> Html Msg | ||||
| view settings model = | ||||
|     if model.viewMode == Table then | ||||
|         viewTable model | ||||
|  | ||||
|     else | ||||
|         viewForm settings model | ||||
|  | ||||
|  | ||||
| viewTable : Model -> Html Msg | ||||
| viewTable model = | ||||
|     div [] | ||||
|         [ button [ class "ui basic button", onClick InitNewUser ] | ||||
|             [ i [ class "plus icon" ] [] | ||||
|             , text "Create new" | ||||
|             ] | ||||
|         , Html.map TableMsg (Comp.UserTable.view model.tableModel) | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui dimmer", True ) | ||||
|                 , ( "active", model.loading ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ div [ class "ui loader" ] [] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewForm : UiSettings -> Model -> Html Msg | ||||
| viewForm settings model = | ||||
|     let | ||||
|         newUser = | ||||
|             Comp.UserForm.isNewUser model.formModel | ||||
|     in | ||||
|     Html.form [ class "ui segment", onSubmit Submit ] | ||||
|         [ Html.map YesNoMsg (Comp.YesNoDimmer.view model.deleteConfirm) | ||||
|         , if newUser then | ||||
|             h3 [ class "ui dividing header" ] | ||||
|                 [ text "Create new user" | ||||
|                 ] | ||||
|  | ||||
|           else | ||||
|             h3 [ class "ui dividing header" ] | ||||
|                 [ text ("Edit user: " ++ model.formModel.user.login) | ||||
|                 ] | ||||
|         , Html.map FormMsg (Comp.UserForm.view settings model.formModel) | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui error message", True ) | ||||
|                 , ( "invisible", Util.Maybe.isEmpty model.formError ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ Maybe.withDefault "" model.formError |> text | ||||
|             ] | ||||
|         , div [ class "ui horizontal divider" ] [] | ||||
|         , button [ class "ui primary button", type_ "submit" ] | ||||
|             [ text "Submit" | ||||
|             ] | ||||
|         , a [ class "ui secondary button", onClick (SetViewMode Table), href "#" ] | ||||
|             [ text "Cancel" | ||||
|             ] | ||||
|         , if not newUser then | ||||
|             a [ class "ui right floated red button", href "#", onClick RequestDelete ] | ||||
|                 [ text "Delete" ] | ||||
|  | ||||
|           else | ||||
|             span [] [] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "ui dimmer", True ) | ||||
|                 , ( "active", model.loading ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ div [ class "ui loader" ] [] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -3,7 +3,6 @@ module Comp.UserTable exposing | ||||
|     , Msg(..) | ||||
|     , emptyModel | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     ) | ||||
|  | ||||
| @@ -12,7 +11,6 @@ import Comp.Basic as B | ||||
| import Data.Flags exposing (Flags) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onClick) | ||||
| import Styles as S | ||||
| import Util.Time exposing (formatDateTime) | ||||
|  | ||||
| @@ -50,55 +48,6 @@ update _ msg model = | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : Model -> Html Msg | ||||
| view model = | ||||
|     table [ class "ui selectable table" ] | ||||
|         [ thead [] | ||||
|             [ tr [] | ||||
|                 [ th [ class "collapsing" ] [ text "Login" ] | ||||
|                 , th [ class "collapsing" ] [ text "State" ] | ||||
|                 , th [ class "collapsing" ] [ text "Email" ] | ||||
|                 , th [ class "collapsing" ] [ text "Logins" ] | ||||
|                 , th [ class "collapsing" ] [ text "Last Login" ] | ||||
|                 , th [ class "collapsing" ] [ text "Created" ] | ||||
|                 ] | ||||
|             ] | ||||
|         , tbody [] | ||||
|             (List.map (renderUserLine model) model.users) | ||||
|         ] | ||||
|  | ||||
|  | ||||
| renderUserLine : Model -> User -> Html Msg | ||||
| renderUserLine model user = | ||||
|     tr | ||||
|         [ classList [ ( "active", model.selected == Just user ) ] | ||||
|         , onClick (Select user) | ||||
|         ] | ||||
|         [ td [ class "collapsing" ] | ||||
|             [ text user.login | ||||
|             ] | ||||
|         , td [ class "collapsing" ] | ||||
|             [ text user.state | ||||
|             ] | ||||
|         , td [ class "collapsing" ] | ||||
|             [ Maybe.withDefault "" user.email |> text | ||||
|             ] | ||||
|         , td [ class "collapsing" ] | ||||
|             [ String.fromInt user.loginCount |> text | ||||
|             ] | ||||
|         , td [ class "collapsing" ] | ||||
|             [ Maybe.map formatDateTime user.lastLogin |> Maybe.withDefault "" |> text | ||||
|             ] | ||||
|         , td [ class "collapsing" ] | ||||
|             [ formatDateTime user.created |> text | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
|  | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -10,8 +10,6 @@ module Comp.YesNoDimmer exposing | ||||
|     , initActive | ||||
|     , initInactive | ||||
|     , update | ||||
|     , view | ||||
|     , view2 | ||||
|     , viewN | ||||
|     ) | ||||
|  | ||||
| @@ -105,42 +103,8 @@ update msg model = | ||||
|             ( { model | active = False }, True ) | ||||
|  | ||||
|  | ||||
| view : Model -> Html Msg | ||||
| view model = | ||||
|     view2 True defaultSettings model | ||||
|  | ||||
|  | ||||
| view2 : Bool -> Settings -> Model -> Html Msg | ||||
| view2 active settings model = | ||||
|     div | ||||
|         [ classList | ||||
|             [ ( "ui dimmer", True ) | ||||
|             , ( settings.extraClass, True ) | ||||
|             , ( "active", active && model.active ) | ||||
|             ] | ||||
|         ] | ||||
|         [ div [ class "content" ] | ||||
|             [ h3 [ class settings.headerClass ] | ||||
|                 [ if settings.headerIcon == "" then | ||||
|                     span [] [] | ||||
|  | ||||
|                   else | ||||
|                     i [ class settings.headerIcon ] [] | ||||
|                 , text settings.message | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "content" ] | ||||
|             [ div [ class "ui buttons" ] | ||||
|                 [ a [ class "ui primary button", onClick ConfirmDelete, href "#" ] | ||||
|                     [ text settings.confirmButton | ||||
|                     ] | ||||
|                 , div [ class "or" ] [] | ||||
|                 , a [ class "ui secondary button", onClick Disable, href "#" ] | ||||
|                     [ text settings.cancelButton | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
| --- View2 | ||||
|  | ||||
|  | ||||
| viewN : Bool -> Settings -> Model -> Html Msg | ||||
|   | ||||
| @@ -20,7 +20,6 @@ type alias Config = | ||||
|     , maxPageSize : Int | ||||
|     , maxNoteLength : Int | ||||
|     , showClassificationSettings : Bool | ||||
|     , uiVersion : Int | ||||
|     } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -3,7 +3,6 @@ module Main exposing (init, main) | ||||
| import Api | ||||
| import App.Data exposing (..) | ||||
| import App.Update exposing (..) | ||||
| import App.View | ||||
| import App.View2 | ||||
| import Browser exposing (Document) | ||||
| import Browser.Navigation exposing (Key) | ||||
| @@ -74,12 +73,7 @@ viewDoc model = | ||||
|     in | ||||
|     { title = model.flags.config.appName ++ ": " ++ title | ||||
|     , body = | ||||
|         if model.flags.config.uiVersion == 2 then | ||||
|             App.View2.view model | ||||
|  | ||||
|         else | ||||
|             [ App.View.view model | ||||
|             ] | ||||
|         App.View2.view model | ||||
|     } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -1,230 +0,0 @@ | ||||
| module Page.CollectiveSettings.View exposing (view) | ||||
|  | ||||
| import Api.Model.TagCount exposing (TagCount) | ||||
| import Comp.CollectiveSettingsForm | ||||
| import Comp.SourceManage | ||||
| import Comp.UserManage | ||||
| import Data.Flags exposing (Flags) | ||||
| import Data.Icons as Icons | ||||
| import Data.UiSettings exposing (UiSettings) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onClick) | ||||
| import Page.CollectiveSettings.Data exposing (..) | ||||
| import Util.Html exposing (classActive) | ||||
| import Util.Maybe | ||||
| import Util.Size | ||||
|  | ||||
|  | ||||
| view : Flags -> UiSettings -> Model -> Html Msg | ||||
| view flags settings model = | ||||
|     div [ class "collectivesetting-page ui padded grid" ] | ||||
|         [ div [ class "sixteen wide mobile four wide tablet four wide computer column" ] | ||||
|             [ h4 [ class "ui top attached ablue-comp header" ] | ||||
|                 [ text "Collective" | ||||
|                 ] | ||||
|             , div [ class "ui attached fluid segment" ] | ||||
|                 [ div [ class "ui fluid vertical secondary menu" ] | ||||
|                     [ div | ||||
|                         [ classActive (model.currentTab == Just InsightsTab) "link icon item" | ||||
|                         , onClick (SetTab InsightsTab) | ||||
|                         ] | ||||
|                         [ i [ class "chart bar outline icon" ] [] | ||||
|                         , text "Insights" | ||||
|                         ] | ||||
|                     , div | ||||
|                         [ classActive (model.currentTab == Just SourceTab) "link icon item" | ||||
|                         , onClick (SetTab SourceTab) | ||||
|                         ] | ||||
|                         [ Icons.sourceIcon "" | ||||
|                         , text "Sources" | ||||
|                         ] | ||||
|                     , div | ||||
|                         [ classActive (model.currentTab == Just SettingsTab) "link icon item" | ||||
|                         , onClick (SetTab SettingsTab) | ||||
|                         ] | ||||
|                         [ i [ class "cog icon" ] [] | ||||
|                         , text "Settings" | ||||
|                         ] | ||||
|                     , div | ||||
|                         [ classActive (model.currentTab == Just UserTab) "link icon item" | ||||
|                         , onClick (SetTab UserTab) | ||||
|                         ] | ||||
|                         [ i [ class "user icon" ] [] | ||||
|                         , text "Users" | ||||
|                         ] | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "sixteen wide mobile twelve wide tablet twelve wide computer column" ] | ||||
|             [ div [ class "" ] | ||||
|                 (case model.currentTab of | ||||
|                     Just SourceTab -> | ||||
|                         viewSources flags settings model | ||||
|  | ||||
|                     Just UserTab -> | ||||
|                         viewUsers settings model | ||||
|  | ||||
|                     Just InsightsTab -> | ||||
|                         viewInsights flags model | ||||
|  | ||||
|                     Just SettingsTab -> | ||||
|                         viewSettings flags settings model | ||||
|  | ||||
|                     Nothing -> | ||||
|                         [] | ||||
|                 ) | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewInsights : Flags -> Model -> List (Html Msg) | ||||
| viewInsights flags model = | ||||
|     let | ||||
|         ( coll, user ) = | ||||
|             Maybe.map (\a -> ( a.collective, a.user )) flags.account | ||||
|                 |> Maybe.withDefault ( "", "" ) | ||||
|     in | ||||
|     [ h1 [ class "ui header" ] | ||||
|         [ i [ class "chart bar outline icon" ] [] | ||||
|         , div [ class "content" ] | ||||
|             [ text "Insights" | ||||
|             ] | ||||
|         ] | ||||
|     , h2 [ class "ui sub header" ] | ||||
|         [ div [ class "ui horizontal list" ] | ||||
|             [ div | ||||
|                 [ class "item" | ||||
|                 , title "Collective" | ||||
|                 ] | ||||
|                 [ i [ class "users circle icon" ] [] | ||||
|                 , text coll | ||||
|                 ] | ||||
|             , div | ||||
|                 [ class "item" | ||||
|                 , title "User" | ||||
|                 ] | ||||
|                 [ i [ class "user outline icon" ] [] | ||||
|                 , text user | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|     , div [ class "ui basic blue segment" ] | ||||
|         [ h4 [ class "ui header" ] | ||||
|             [ text "Items" | ||||
|             ] | ||||
|         , div [ class "ui statistics" ] | ||||
|             [ div [ class "ui statistic" ] | ||||
|                 [ div [ class "value" ] | ||||
|                     [ String.fromInt (model.insights.incomingCount + model.insights.outgoingCount) |> text | ||||
|                     ] | ||||
|                 , div [ class "label" ] | ||||
|                     [ text "Items" | ||||
|                     ] | ||||
|                 ] | ||||
|             , div [ class "ui statistic" ] | ||||
|                 [ div [ class "value" ] | ||||
|                     [ String.fromInt model.insights.incomingCount |> text | ||||
|                     ] | ||||
|                 , div [ class "label" ] | ||||
|                     [ text "Incoming" | ||||
|                     ] | ||||
|                 ] | ||||
|             , div [ class "ui statistic" ] | ||||
|                 [ div [ class "value" ] | ||||
|                     [ String.fromInt model.insights.outgoingCount |> text | ||||
|                     ] | ||||
|                 , div [ class "label" ] | ||||
|                     [ text "Outgoing" | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|     , div [ class "ui basic blue segment" ] | ||||
|         [ h4 [ class "ui header" ] | ||||
|             [ text "Size" | ||||
|             ] | ||||
|         , div [ class "ui statistics" ] | ||||
|             [ div [ class "ui statistic" ] | ||||
|                 [ div [ class "value" ] | ||||
|                     [ toFloat model.insights.itemSize |> Util.Size.bytesReadable Util.Size.B |> text | ||||
|                     ] | ||||
|                 , div [ class "label" ] | ||||
|                     [ text "Size" | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|     , div [ class "ui basic blue segment" ] | ||||
|         [ h4 [ class "ui header" ] | ||||
|             [ text "Tags" | ||||
|             ] | ||||
|         , div [ class "ui statistics" ] | ||||
|             (List.map makeTagStats | ||||
|                 (List.sortBy .count model.insights.tagCloud.items | ||||
|                     |> List.reverse | ||||
|                 ) | ||||
|             ) | ||||
|         ] | ||||
|     ] | ||||
|  | ||||
|  | ||||
| makeTagStats : TagCount -> Html Msg | ||||
| makeTagStats nc = | ||||
|     div [ class "ui statistic" ] | ||||
|         [ div [ class "value" ] | ||||
|             [ String.fromInt nc.count |> text | ||||
|             ] | ||||
|         , div [ class "label" ] | ||||
|             [ text nc.tag.name | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewSources : Flags -> UiSettings -> Model -> List (Html Msg) | ||||
| viewSources flags settings model = | ||||
|     [ h2 [ class "ui header" ] | ||||
|         [ Icons.sourceIcon "" | ||||
|         , div [ class "content" ] | ||||
|             [ text "Sources" | ||||
|             ] | ||||
|         ] | ||||
|     , Html.map SourceMsg (Comp.SourceManage.view flags settings model.sourceModel) | ||||
|     ] | ||||
|  | ||||
|  | ||||
| viewUsers : UiSettings -> Model -> List (Html Msg) | ||||
| viewUsers settings model = | ||||
|     [ h2 [ class "ui header" ] | ||||
|         [ i [ class "ui user icon" ] [] | ||||
|         , div [ class "content" ] | ||||
|             [ text "Users" | ||||
|             ] | ||||
|         ] | ||||
|     , Html.map UserMsg (Comp.UserManage.view settings model.userModel) | ||||
|     ] | ||||
|  | ||||
|  | ||||
| viewSettings : Flags -> UiSettings -> Model -> List (Html Msg) | ||||
| viewSettings flags settings model = | ||||
|     [ h2 [ class "ui header" ] | ||||
|         [ i [ class "cog icon" ] [] | ||||
|         , text "Collective Settings" | ||||
|         ] | ||||
|     , div [ class "ui segment" ] | ||||
|         [ Html.map SettingsFormMsg | ||||
|             (Comp.CollectiveSettingsForm.view flags settings model.settingsModel) | ||||
|         ] | ||||
|     , div | ||||
|         [ classList | ||||
|             [ ( "ui message", True ) | ||||
|             , ( "hidden", Util.Maybe.isEmpty model.submitResult ) | ||||
|             , ( "success", Maybe.map .success model.submitResult |> Maybe.withDefault False ) | ||||
|             , ( "error", Maybe.map .success model.submitResult |> Maybe.map not |> Maybe.withDefault False ) | ||||
|             ] | ||||
|         ] | ||||
|         [ Maybe.map .message model.submitResult | ||||
|             |> Maybe.withDefault "" | ||||
|             |> text | ||||
|         ] | ||||
|     ] | ||||
| @@ -1,395 +0,0 @@ | ||||
| module Page.Home.View exposing (view) | ||||
|  | ||||
| import Api.Model.ItemSearch | ||||
| import Comp.FixedDropdown | ||||
| import Comp.ItemCardList | ||||
| import Comp.ItemDetail.MultiEditMenu | ||||
| import Comp.SearchMenu | ||||
| import Comp.SearchStatsView | ||||
| import Comp.YesNoDimmer | ||||
| import Data.Flags exposing (Flags) | ||||
| import Data.ItemSelection | ||||
| import Data.UiSettings exposing (UiSettings) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onClick, onInput) | ||||
| import Page exposing (Page(..)) | ||||
| import Page.Home.Data exposing (..) | ||||
| import Set | ||||
| import Util.Html | ||||
|  | ||||
|  | ||||
| view : Flags -> UiSettings -> Model -> Html Msg | ||||
| view flags settings model = | ||||
|     let | ||||
|         itemViewCfg = | ||||
|             case model.viewMode of | ||||
|                 SelectView svm -> | ||||
|                     Comp.ItemCardList.ViewConfig | ||||
|                         model.scrollToCard | ||||
|                         (Data.ItemSelection.Active svm.ids) | ||||
|  | ||||
|                 _ -> | ||||
|                     Comp.ItemCardList.ViewConfig | ||||
|                         model.scrollToCard | ||||
|                         Data.ItemSelection.Inactive | ||||
|  | ||||
|         selectAction = | ||||
|             case model.viewMode of | ||||
|                 SelectView svm -> | ||||
|                     svm.action | ||||
|  | ||||
|                 _ -> | ||||
|                     NoneAction | ||||
|     in | ||||
|     div [ class "home-page ui padded grid" ] | ||||
|         [ div | ||||
|             [ classList | ||||
|                 [ ( "sixteen wide mobile six wide tablet four wide computer search-menu column" | ||||
|                   , True | ||||
|                   ) | ||||
|                 , ( "invisible hidden", menuCollapsed model ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ div | ||||
|                 [ class "ui ablue-comp icon menu" | ||||
|                 ] | ||||
|                 [ a | ||||
|                     [ class "borderless item" | ||||
|                     , href "#" | ||||
|                     , onClick ToggleSearchMenu | ||||
|                     , title "Hide menu" | ||||
|                     ] | ||||
|                     [ i [ class "chevron left icon" ] [] | ||||
|                     ] | ||||
|                 , div [ class "right floated menu" ] | ||||
|                     [ a | ||||
|                         [ classList | ||||
|                             [ ( "borderless item", True ) | ||||
|                             , ( "active", selectActive model ) | ||||
|                             ] | ||||
|                         , href "#" | ||||
|                         , title "Toggle select items" | ||||
|                         , onClick ToggleSelectView | ||||
|                         ] | ||||
|                         [ i [ class "tasks icon" ] [] | ||||
|                         ] | ||||
|                     , a | ||||
|                         [ class "borderless item" | ||||
|                         , onClick ResetSearch | ||||
|                         , title "Reset form" | ||||
|                         , href "#" | ||||
|                         ] | ||||
|                         [ i [ class "undo icon" ] [] | ||||
|                         ] | ||||
|                     , a | ||||
|                         [ class "borderless item" | ||||
|                         , onClick (DoSearch BasicSearch) | ||||
|                         , title "Run search query" | ||||
|                         , href "#" | ||||
|                         , disabled model.searchInProgress | ||||
|                         ] | ||||
|                         [ i | ||||
|                             [ classList | ||||
|                                 [ ( "search icon", not model.searchInProgress ) | ||||
|                                 , ( "loading spinner icon", model.searchInProgress ) | ||||
|                                 ] | ||||
|                             ] | ||||
|                             [] | ||||
|                         ] | ||||
|                     ] | ||||
|                 ] | ||||
|             , div [ class "" ] | ||||
|                 (viewLeftMenu flags settings model) | ||||
|             ] | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "sixteen wide mobile ten wide tablet twelve wide computer column" | ||||
|                   , not (menuCollapsed model) | ||||
|                   ) | ||||
|                 , ( "sixteen wide column", menuCollapsed model ) | ||||
|                 , ( "item-card-list", True ) | ||||
|                 ] | ||||
|             , id "item-card-list" | ||||
|             ] | ||||
|             (List.concat | ||||
|                 [ viewBar flags model | ||||
|                 , case model.viewMode of | ||||
|                     SelectView svm -> | ||||
|                         [ Html.map DeleteSelectedConfirmMsg | ||||
|                             (Comp.YesNoDimmer.view2 (selectAction == DeleteSelected) | ||||
|                                 deleteAllDimmer | ||||
|                                 svm.deleteAllConfirm | ||||
|                             ) | ||||
|                         ] | ||||
|  | ||||
|                     _ -> | ||||
|                         [] | ||||
|                 , viewStats flags settings model | ||||
|                 , [ Html.map ItemCardListMsg | ||||
|                         (Comp.ItemCardList.view itemViewCfg settings model.itemListModel) | ||||
|                   ] | ||||
|                 ] | ||||
|             ) | ||||
|         , div | ||||
|             [ classList | ||||
|                 [ ( "sixteen wide column", True ) | ||||
|                 , ( "hidden invisible", resultsBelowLimit settings model ) | ||||
|                 ] | ||||
|             ] | ||||
|             [ div [ class "ui basic center aligned segment" ] | ||||
|                 [ button | ||||
|                     [ classList | ||||
|                         [ ( "ui basic tiny button", True ) | ||||
|                         , ( "disabled", not model.moreAvailable ) | ||||
|                         ] | ||||
|                     , disabled (not model.moreAvailable || model.moreInProgress || model.searchInProgress) | ||||
|                     , title "Load more items" | ||||
|                     , href "#" | ||||
|                     , onClick LoadMore | ||||
|                     ] | ||||
|                     [ if model.moreInProgress then | ||||
|                         i [ class "loading spinner icon" ] [] | ||||
|  | ||||
|                       else | ||||
|                         i [ class "angle double down icon" ] [] | ||||
|                     , if model.moreAvailable then | ||||
|                         text "Load more…" | ||||
|  | ||||
|                       else | ||||
|                         text "That's all" | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewStats : Flags -> UiSettings -> Model -> List (Html Msg) | ||||
| viewStats _ settings model = | ||||
|     if settings.searchStatsVisible then | ||||
|         Comp.SearchStatsView.view model.searchStats | ||||
|  | ||||
|     else | ||||
|         [] | ||||
|  | ||||
|  | ||||
| viewLeftMenu : Flags -> UiSettings -> Model -> List (Html Msg) | ||||
| viewLeftMenu flags settings model = | ||||
|     let | ||||
|         searchMenu = | ||||
|             [ Html.map SearchMenuMsg | ||||
|                 (Comp.SearchMenu.viewDrop model.dragDropData | ||||
|                     flags | ||||
|                     settings | ||||
|                     model.searchMenuModel | ||||
|                 ) | ||||
|             ] | ||||
|     in | ||||
|     case model.viewMode of | ||||
|         SelectView svm -> | ||||
|             case svm.action of | ||||
|                 EditSelected -> | ||||
|                     let | ||||
|                         cfg_ = | ||||
|                             Comp.ItemDetail.MultiEditMenu.defaultViewConfig | ||||
|  | ||||
|                         cfg = | ||||
|                             { cfg_ | ||||
|                                 | nameState = svm.saveNameState | ||||
|                                 , customFieldState = | ||||
|                                     \fId -> | ||||
|                                         if Set.member fId svm.saveCustomFieldState then | ||||
|                                             Comp.ItemDetail.MultiEditMenu.Saving | ||||
|  | ||||
|                                         else | ||||
|                                             Comp.ItemDetail.MultiEditMenu.SaveSuccess | ||||
|                             } | ||||
|                     in | ||||
|                     [ div [ class "ui dividing header" ] | ||||
|                         [ text "Multi-Edit" | ||||
|                         ] | ||||
|                     , div [ class "ui info message" ] | ||||
|                         [ text "Note that a change here immediatly affects all selected items on the right!" | ||||
|                         ] | ||||
|                     , Html.map EditMenuMsg | ||||
|                         (Comp.ItemDetail.MultiEditMenu.view cfg settings svm.editModel) | ||||
|                     ] | ||||
|  | ||||
|                 _ -> | ||||
|                     searchMenu | ||||
|  | ||||
|         _ -> | ||||
|             searchMenu | ||||
|  | ||||
|  | ||||
| viewBar : Flags -> Model -> List (Html Msg) | ||||
| viewBar flags model = | ||||
|     case model.viewMode of | ||||
|         SimpleView -> | ||||
|             [ viewSearchBar flags model ] | ||||
|  | ||||
|         SearchView -> | ||||
|             [] | ||||
|  | ||||
|         SelectView svm -> | ||||
|             [ viewActionBar flags svm model ] | ||||
|  | ||||
|  | ||||
| viewActionBar : Flags -> SelectViewModel -> Model -> Html Msg | ||||
| viewActionBar _ svm _ = | ||||
|     let | ||||
|         selectCount = | ||||
|             Set.size svm.ids |> String.fromInt | ||||
|     in | ||||
|     div | ||||
|         [ class "ui ablue-comp icon menu" | ||||
|         ] | ||||
|         [ a | ||||
|             [ classList | ||||
|                 [ ( "borderless item", True ) | ||||
|                 , ( "active", svm.action == EditSelected ) | ||||
|                 ] | ||||
|             , href "#" | ||||
|             , title <| "Edit " ++ selectCount ++ " selected items" | ||||
|             , onClick EditSelectedItems | ||||
|             ] | ||||
|             [ i [ class "ui edit icon" ] [] | ||||
|             ] | ||||
|         , a | ||||
|             [ classList | ||||
|                 [ ( "borderless item", True ) | ||||
|                 , ( "active", svm.action == DeleteSelected ) | ||||
|                 ] | ||||
|             , href "#" | ||||
|             , title <| "Delete " ++ selectCount ++ " selected items" | ||||
|             , onClick RequestDeleteSelected | ||||
|             ] | ||||
|             [ i [ class "trash icon" ] [] | ||||
|             ] | ||||
|         , div [ class "right menu" ] | ||||
|             [ a | ||||
|                 [ class "item" | ||||
|                 , href "#" | ||||
|                 , onClick SelectAllItems | ||||
|                 , title "Select all" | ||||
|                 ] | ||||
|                 [ i [ class "check square outline icon" ] [] | ||||
|                 ] | ||||
|             , a | ||||
|                 [ class "borderless item" | ||||
|                 , href "#" | ||||
|                 , title "Select none" | ||||
|                 , onClick SelectNoItems | ||||
|                 ] | ||||
|                 [ i [ class "square outline icon" ] [] | ||||
|                 ] | ||||
|             , div [ class "borderless label item" ] | ||||
|                 [ div [ class "ui circular purple icon label" ] | ||||
|                     [ text selectCount | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewSearchBar : Flags -> Model -> Html Msg | ||||
| viewSearchBar flags model = | ||||
|     let | ||||
|         searchTypeItem = | ||||
|             Comp.FixedDropdown.Item | ||||
|                 model.searchTypeDropdownValue | ||||
|                 (searchTypeString model.searchTypeDropdownValue) | ||||
|  | ||||
|         searchInput = | ||||
|             Comp.SearchMenu.textSearchString | ||||
|                 model.searchMenuModel.textSearchModel | ||||
|  | ||||
|         searchTypeClass = | ||||
|             if flags.config.fullTextSearchEnabled then | ||||
|                 "compact" | ||||
|  | ||||
|             else | ||||
|                 "hidden invisible" | ||||
|     in | ||||
|     div | ||||
|         [ classList | ||||
|             [ ( "invisible hidden", not (menuCollapsed model) ) | ||||
|             , ( "ui secondary stackable menu container", True ) | ||||
|             ] | ||||
|         ] | ||||
|         [ a | ||||
|             [ classList | ||||
|                 [ ( "search-menu-toggle ui icon button", True ) | ||||
|  | ||||
|                 -- , ( "primary", not (searchMenuFilled model) ) | ||||
|                 -- , ( "secondary", searchMenuFilled model ) | ||||
|                 ] | ||||
|             , onClick ToggleSearchMenu | ||||
|             , href "#" | ||||
|             , title "Open search menu" | ||||
|             ] | ||||
|             [ i [ class "filter icon" ] [] | ||||
|             ] | ||||
|         , div [ class "right menu" ] | ||||
|             [ div [ class "fitted item" ] | ||||
|                 [ div [ class "ui left icon right action input" ] | ||||
|                     [ -- i | ||||
|                       --    [ classList | ||||
|                       --        [ ( "search link icon", not model.searchInProgress ) | ||||
|                       --        , ( "loading spinner icon", model.searchInProgress ) | ||||
|                       --        ] | ||||
|                       --    , href "#" | ||||
|                       --    , onClick (DoSearch model.searchTypeDropdownValue) | ||||
|                       --    ] | ||||
|                       --    (if hasMoreSearch model then | ||||
|                       --        [ i [ class "icons search-corner-icons" ] | ||||
|                       --            [ i [ class "tiny blue circle icon" ] [] | ||||
|                       --            ] | ||||
|                       --        ] | ||||
|                       --     else | ||||
|                       --        [] | ||||
|                       --    ) | ||||
|                       input | ||||
|                         [ type_ "text" | ||||
|                         , placeholder | ||||
|                             (case model.searchTypeDropdownValue of | ||||
|                                 ContentOnlySearch -> | ||||
|                                     "Content search…" | ||||
|  | ||||
|                                 BasicSearch -> | ||||
|                                     "Search in names…" | ||||
|                             ) | ||||
|                         , onInput SetBasicSearch | ||||
|                         , Util.Html.onKeyUpCode KeyUpSearchbarMsg | ||||
|                         , Maybe.map value searchInput | ||||
|                             |> Maybe.withDefault (value "") | ||||
|                         ] | ||||
|                         [] | ||||
|                     , Html.map SearchTypeMsg | ||||
|                         (Comp.FixedDropdown.viewStyled searchTypeClass | ||||
|                             (Just searchTypeItem) | ||||
|                             model.searchTypeDropdown | ||||
|                         ) | ||||
|                     , a | ||||
|                         [ class "ui icon basic button" | ||||
|                         , href "#" | ||||
|                         , onClick ResetSearch | ||||
|                         , title "Reset search form" | ||||
|                         ] | ||||
|                         [ i [ class "undo icon" ] [] | ||||
|                         ] | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| deleteAllDimmer : Comp.YesNoDimmer.Settings | ||||
| deleteAllDimmer = | ||||
|     { message = "Really delete all selected items?" | ||||
|     , headerIcon = "exclamation icon" | ||||
|     , headerClass = "ui inverted icon header" | ||||
|     , confirmButton = "Yes" | ||||
|     , cancelButton = "No" | ||||
|     , extraClass = "top aligned" | ||||
|     } | ||||
| @@ -1,15 +0,0 @@ | ||||
| module Page.ItemDetail.View exposing (view) | ||||
|  | ||||
| import Comp.ItemDetail | ||||
| import Data.ItemNav exposing (ItemNav) | ||||
| import Data.UiSettings exposing (UiSettings) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Page.ItemDetail.Data exposing (Model, Msg(..)) | ||||
|  | ||||
|  | ||||
| view : ItemNav -> UiSettings -> Model -> Html Msg | ||||
| view inav settings model = | ||||
|     div [ class "ui fluid container item-detail-page" ] | ||||
|         [ Html.map ItemDetailMsg (Comp.ItemDetail.view inav settings model.detail) | ||||
|         ] | ||||
| @@ -1,112 +0,0 @@ | ||||
| module Page.Login.View exposing (view) | ||||
|  | ||||
| import Data.Flags exposing (Flags) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onCheck, onInput, onSubmit) | ||||
| import Page exposing (Page(..)) | ||||
| import Page.Login.Data exposing (..) | ||||
|  | ||||
|  | ||||
| view : Flags -> Model -> Html Msg | ||||
| view flags model = | ||||
|     div [ class "login-page" ] | ||||
|         [ div [ class "ui centered grid" ] | ||||
|             [ div [ class "row" ] | ||||
|                 [ div [ class "sixteen wide mobile twelve wide tablet six wide computer column" ] | ||||
|                     [ div [ class "ui segment login-view" ] | ||||
|                         [ h1 [ class "ui center aligned icon header" ] | ||||
|                             [ img | ||||
|                                 [ class "ui image" | ||||
|                                 , src (flags.config.docspellAssetPath ++ "/img/logo-96.png") | ||||
|                                 ] | ||||
|                                 [] | ||||
|                             , div [ class "content" ] | ||||
|                                 [ text "Sign in to Docspell" | ||||
|                                 ] | ||||
|                             ] | ||||
|                         , Html.form | ||||
|                             [ class "ui large error raised form segment" | ||||
|                             , onSubmit Authenticate | ||||
|                             , autocomplete False | ||||
|                             ] | ||||
|                             [ div [ class "field" ] | ||||
|                                 [ label [] [ text "Username" ] | ||||
|                                 , div [ class "ui left icon input" ] | ||||
|                                     [ input | ||||
|                                         [ type_ "text" | ||||
|                                         , autocomplete False | ||||
|                                         , onInput SetUsername | ||||
|                                         , value model.username | ||||
|                                         , placeholder "Collective / Login" | ||||
|                                         , autofocus True | ||||
|                                         ] | ||||
|                                         [] | ||||
|                                     , i [ class "user icon" ] [] | ||||
|                                     ] | ||||
|                                 ] | ||||
|                             , div [ class "field" ] | ||||
|                                 [ label [] [ text "Password" ] | ||||
|                                 , div [ class "ui left icon input" ] | ||||
|                                     [ input | ||||
|                                         [ type_ "password" | ||||
|                                         , autocomplete False | ||||
|                                         , onInput SetPassword | ||||
|                                         , value model.password | ||||
|                                         , placeholder "Password" | ||||
|                                         ] | ||||
|                                         [] | ||||
|                                     , i [ class "lock icon" ] [] | ||||
|                                     ] | ||||
|                                 ] | ||||
|                             , div [ class "field" ] | ||||
|                                 [ div [ class "ui checkbox" ] | ||||
|                                     [ input | ||||
|                                         [ type_ "checkbox" | ||||
|                                         , onCheck (\_ -> ToggleRememberMe) | ||||
|                                         , checked model.rememberMe | ||||
|                                         ] | ||||
|                                         [] | ||||
|                                     , label [] | ||||
|                                         [ text "Remember Me" | ||||
|                                         ] | ||||
|                                     ] | ||||
|                                 ] | ||||
|                             , button | ||||
|                                 [ class "ui primary fluid button" | ||||
|                                 , type_ "submit" | ||||
|                                 ] | ||||
|                                 [ text "Login" | ||||
|                                 ] | ||||
|                             ] | ||||
|                         , resultMessage model | ||||
|                         , div [ class "ui very basic right aligned segment" ] | ||||
|                             [ text "No account? " | ||||
|                             , a [ class "ui icon link", Page.href RegisterPage ] | ||||
|                                 [ i [ class "user circle outline icon" ] [] | ||||
|                                 , text "Sign up!" | ||||
|                                 ] | ||||
|                             ] | ||||
|                         ] | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| resultMessage : Model -> Html Msg | ||||
| resultMessage model = | ||||
|     case model.result of | ||||
|         Just r -> | ||||
|             if r.success then | ||||
|                 div [ class "ui success message" ] | ||||
|                     [ text "Login successful." | ||||
|                     ] | ||||
|  | ||||
|             else | ||||
|                 div [ class "ui error message" ] | ||||
|                     [ text r.message | ||||
|                     ] | ||||
|  | ||||
|         Nothing -> | ||||
|             span [] [] | ||||
| @@ -1,185 +0,0 @@ | ||||
| module Page.ManageData.View exposing (view) | ||||
|  | ||||
| import Comp.CustomFieldManage | ||||
| import Comp.EquipmentManage | ||||
| import Comp.FolderManage | ||||
| import Comp.OrgManage | ||||
| import Comp.PersonManage | ||||
| import Comp.TagManage | ||||
| import Data.Fields | ||||
| import Data.Flags exposing (Flags) | ||||
| import Data.Icons as Icons | ||||
| import Data.UiSettings exposing (UiSettings) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onClick) | ||||
| import Page.ManageData.Data exposing (..) | ||||
| import Util.Html exposing (classActive) | ||||
|  | ||||
|  | ||||
| view : Flags -> UiSettings -> Model -> Html Msg | ||||
| view flags settings model = | ||||
|     div [ class "managedata-page ui padded grid" ] | ||||
|         [ div [ class "sixteen wide mobile four wide tablet four wide computer column" ] | ||||
|             [ h4 [ class "ui top attached ablue-comp header" ] | ||||
|                 [ text "Manage Data" | ||||
|                 ] | ||||
|             , div [ class "ui attached fluid segment" ] | ||||
|                 [ div [ class "ui fluid vertical secondary menu" ] | ||||
|                     [ div | ||||
|                         [ classActive (model.currentTab == Just TagTab) "link icon item" | ||||
|                         , onClick (SetTab TagTab) | ||||
|                         ] | ||||
|                         [ Icons.tagIcon "" | ||||
|                         , text "Tag" | ||||
|                         ] | ||||
|                     , div | ||||
|                         [ classActive (model.currentTab == Just EquipTab) "link icon item" | ||||
|                         , onClick (SetTab EquipTab) | ||||
|                         ] | ||||
|                         [ Icons.equipmentIcon "" | ||||
|                         , text "Equipment" | ||||
|                         ] | ||||
|                     , div | ||||
|                         [ classActive (model.currentTab == Just OrgTab) "link icon item" | ||||
|                         , onClick (SetTab OrgTab) | ||||
|                         ] | ||||
|                         [ Icons.organizationIcon "" | ||||
|                         , text "Organization" | ||||
|                         ] | ||||
|                     , div | ||||
|                         [ classActive (model.currentTab == Just PersonTab) "link icon item" | ||||
|                         , onClick (SetTab PersonTab) | ||||
|                         ] | ||||
|                         [ Icons.personIcon "" | ||||
|                         , text "Person" | ||||
|                         ] | ||||
|                     , div | ||||
|                         [ classActive (model.currentTab == Just FolderTab) "link icon item" | ||||
|                         , classList | ||||
|                             [ ( "invisible hidden" | ||||
|                               , Data.UiSettings.fieldHidden settings Data.Fields.Folder | ||||
|                               ) | ||||
|                             ] | ||||
|                         , onClick (SetTab FolderTab) | ||||
|                         ] | ||||
|                         [ Icons.folderIcon "" | ||||
|                         , text "Folder" | ||||
|                         ] | ||||
|                     , div | ||||
|                         [ classActive (model.currentTab == Just CustomFieldTab) "link icon item" | ||||
|                         , classList | ||||
|                             [ ( "invisible hidden" | ||||
|                               , Data.UiSettings.fieldHidden settings Data.Fields.CustomFields | ||||
|                               ) | ||||
|                             ] | ||||
|                         , onClick (SetTab CustomFieldTab) | ||||
|                         ] | ||||
|                         [ Icons.customFieldIcon "" | ||||
|                         , text "Custom Fields" | ||||
|                         ] | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "sixteen wide mobile twelve wide tablet twelve wide computer column" ] | ||||
|             [ div [ class "" ] | ||||
|                 (case model.currentTab of | ||||
|                     Just TagTab -> | ||||
|                         viewTags model | ||||
|  | ||||
|                     Just EquipTab -> | ||||
|                         viewEquip model | ||||
|  | ||||
|                     Just OrgTab -> | ||||
|                         viewOrg settings model | ||||
|  | ||||
|                     Just PersonTab -> | ||||
|                         viewPerson settings model | ||||
|  | ||||
|                     Just FolderTab -> | ||||
|                         viewFolder flags settings model | ||||
|  | ||||
|                     Just CustomFieldTab -> | ||||
|                         viewCustomFields flags settings model | ||||
|  | ||||
|                     Nothing -> | ||||
|                         [] | ||||
|                 ) | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewCustomFields : Flags -> UiSettings -> Model -> List (Html Msg) | ||||
| viewCustomFields flags _ model = | ||||
|     [ h2 [ class "ui header" ] | ||||
|         [ Icons.customFieldIcon "" | ||||
|         , div [ class "content" ] | ||||
|             [ text "Custom Fields" | ||||
|             ] | ||||
|         ] | ||||
|     , Html.map CustomFieldMsg (Comp.CustomFieldManage.view flags model.fieldManageModel) | ||||
|     ] | ||||
|  | ||||
|  | ||||
| viewFolder : Flags -> UiSettings -> Model -> List (Html Msg) | ||||
| viewFolder flags _ model = | ||||
|     [ h2 | ||||
|         [ class "ui header" | ||||
|         ] | ||||
|         [ Icons.folderIcon "" | ||||
|         , div | ||||
|             [ class "content" | ||||
|             ] | ||||
|             [ text "Folders" | ||||
|             ] | ||||
|         ] | ||||
|     , Html.map FolderMsg (Comp.FolderManage.view flags model.folderManageModel) | ||||
|     ] | ||||
|  | ||||
|  | ||||
| viewTags : Model -> List (Html Msg) | ||||
| viewTags model = | ||||
|     [ h2 [ class "ui header" ] | ||||
|         [ Icons.tagIcon "" | ||||
|         , div [ class "content" ] | ||||
|             [ text "Tags" | ||||
|             ] | ||||
|         ] | ||||
|     , Html.map TagManageMsg (Comp.TagManage.view model.tagManageModel) | ||||
|     ] | ||||
|  | ||||
|  | ||||
| viewEquip : Model -> List (Html Msg) | ||||
| viewEquip model = | ||||
|     [ h2 [ class "ui header" ] | ||||
|         [ Icons.equipmentIcon "" | ||||
|         , div [ class "content" ] | ||||
|             [ text "Equipment" | ||||
|             ] | ||||
|         ] | ||||
|     , Html.map EquipManageMsg (Comp.EquipmentManage.view model.equipManageModel) | ||||
|     ] | ||||
|  | ||||
|  | ||||
| viewOrg : UiSettings -> Model -> List (Html Msg) | ||||
| viewOrg settings model = | ||||
|     [ h2 [ class "ui header" ] | ||||
|         [ Icons.organizationIcon "" | ||||
|         , div [ class "content" ] | ||||
|             [ text "Organizations" | ||||
|             ] | ||||
|         ] | ||||
|     , Html.map OrgManageMsg (Comp.OrgManage.view settings model.orgManageModel) | ||||
|     ] | ||||
|  | ||||
|  | ||||
| viewPerson : UiSettings -> Model -> List (Html Msg) | ||||
| viewPerson settings model = | ||||
|     [ h2 [ class "ui header" ] | ||||
|         [ Icons.personIcon "" | ||||
|         , div [ class "content" ] | ||||
|             [ text "Person" | ||||
|             ] | ||||
|         ] | ||||
|     , Html.map PersonManageMsg (Comp.PersonManage.view settings model.personManageModel) | ||||
|     ] | ||||
| @@ -1,114 +0,0 @@ | ||||
| module Page.NewInvite.View exposing (view) | ||||
|  | ||||
| import Data.Flags exposing (Flags) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onClick, onInput, onSubmit) | ||||
| import Page.NewInvite.Data exposing (..) | ||||
|  | ||||
|  | ||||
| view : Flags -> Model -> Html Msg | ||||
| view flags model = | ||||
|     div [ class "newinvite-page" ] | ||||
|         [ div [ class "ui centered grid" ] | ||||
|             [ div [ class "row" ] | ||||
|                 [ div [ class "sixteen wide mobile fourteen wide tablet eight wide computer column" ] | ||||
|                     [ h1 [ class "ui cener aligned icon header" ] | ||||
|                         [ text "Create new invitations" | ||||
|                         ] | ||||
|                     , inviteMessage flags | ||||
|                     , Html.form | ||||
|                         [ classList | ||||
|                             [ ( "ui large form raised segment", True ) | ||||
|                             , ( "error", isFailed model.result ) | ||||
|                             , ( "success", isSuccess model.result ) | ||||
|                             ] | ||||
|                         , onSubmit GenerateInvite | ||||
|                         ] | ||||
|                         [ div [ class "required field" ] | ||||
|                             [ label [] [ text "New Invitation Password" ] | ||||
|                             , div [ class "ui left icon input" ] | ||||
|                                 [ input | ||||
|                                     [ type_ "password" | ||||
|                                     , onInput SetPassword | ||||
|                                     , value model.password | ||||
|                                     , autofocus True | ||||
|                                     ] | ||||
|                                     [] | ||||
|                                 , i [ class "key icon" ] [] | ||||
|                                 ] | ||||
|                             ] | ||||
|                         , button | ||||
|                             [ class "ui primary button" | ||||
|                             , type_ "submit" | ||||
|                             ] | ||||
|                             [ text "Submit" | ||||
|                             ] | ||||
|                         , a [ class "ui right floated button", href "#", onClick Reset ] | ||||
|                             [ text "Reset" | ||||
|                             ] | ||||
|                         , resultMessage model | ||||
|                         ] | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| resultMessage : Model -> Html Msg | ||||
| resultMessage model = | ||||
|     div | ||||
|         [ classList | ||||
|             [ ( "ui message", True ) | ||||
|             , ( "error", isFailed model.result ) | ||||
|             , ( "success", isSuccess model.result ) | ||||
|             , ( "hidden", model.result == Empty ) | ||||
|             ] | ||||
|         ] | ||||
|         [ case model.result of | ||||
|             Failed m -> | ||||
|                 div [ class "content" ] | ||||
|                     [ div [ class "header" ] [ text "Error" ] | ||||
|                     , p [] [ text m ] | ||||
|                     ] | ||||
|  | ||||
|             Success r -> | ||||
|                 div [ class "content" ] | ||||
|                     [ div [ class "header" ] [ text "Success" ] | ||||
|                     , p [] [ text r.message ] | ||||
|                     , p [] [ text "Invitation Key:" ] | ||||
|                     , pre [] | ||||
|                         [ Maybe.withDefault "" r.key |> text | ||||
|                         ] | ||||
|                     ] | ||||
|  | ||||
|             Empty -> | ||||
|                 span [] [] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| inviteMessage : Flags -> Html Msg | ||||
| inviteMessage flags = | ||||
|     div | ||||
|         [ classList | ||||
|             [ ( "ui message", True ) | ||||
|             , ( "hidden", flags.config.signupMode /= "invite" ) | ||||
|             ] | ||||
|         ] | ||||
|         [ p [] | ||||
|             [ text | ||||
|                 """Docspell requires an invite when signing up. You can | ||||
|              create these invites here and send them to friends so | ||||
|              they can signup with docspell.""" | ||||
|             ] | ||||
|         , p [] | ||||
|             [ text | ||||
|                 """Each invite can only be used once. You'll need to | ||||
|              create one key for each person you want to invite.""" | ||||
|             ] | ||||
|         , p [] | ||||
|             [ text | ||||
|                 """Creating an invite requires providing the password | ||||
|              from the configuration.""" | ||||
|             ] | ||||
|         ] | ||||
| @@ -1,282 +0,0 @@ | ||||
| module Page.Queue.View exposing (view) | ||||
|  | ||||
| import Api.Model.JobDetail exposing (JobDetail) | ||||
| import Api.Model.JobLogEvent exposing (JobLogEvent) | ||||
| import Comp.Progress | ||||
| import Comp.YesNoDimmer | ||||
| import Data.Priority | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onClick) | ||||
| import Page.Queue.Data exposing (..) | ||||
| import Util.Time exposing (formatDateTime, formatIsoDateTime) | ||||
|  | ||||
|  | ||||
| view : Model -> Html Msg | ||||
| view model = | ||||
|     div [ class "queue-page ui grid container" ] <| | ||||
|         List.concat | ||||
|             [ case model.showLog of | ||||
|                 Just job -> | ||||
|                     [ renderJobLog job ] | ||||
|  | ||||
|                 Nothing -> | ||||
|                     List.map (renderProgressCard model) model.state.progress | ||||
|                         |> List.map (\el -> div [ class "row" ] [ div [ class "column" ] [ el ] ]) | ||||
|             , [ div [ class "two column row" ] | ||||
|                     [ renderWaiting model | ||||
|                     , renderCompleted model | ||||
|                     ] | ||||
|               ] | ||||
|             ] | ||||
|  | ||||
|  | ||||
| renderJobLog : JobDetail -> Html Msg | ||||
| renderJobLog job = | ||||
|     div [ class "ui fluid card" ] | ||||
|         [ div [ class "content" ] | ||||
|             [ i [ class "delete link icon", onClick QuitShowLog ] [] | ||||
|             , text job.name | ||||
|             ] | ||||
|         , div [ class "content" ] | ||||
|             [ div [ class "job-log" ] | ||||
|                 (List.map renderLogLine job.logs) | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| renderWaiting : Model -> Html Msg | ||||
| renderWaiting model = | ||||
|     div [ class "column" ] | ||||
|         [ div [ class "ui center aligned basic segment" ] | ||||
|             [ i [ class "ui large angle double up icon" ] [] | ||||
|             ] | ||||
|         , div [ class "ui centered cards" ] | ||||
|             (List.map (renderInfoCard model) model.state.queued) | ||||
|         ] | ||||
|  | ||||
|  | ||||
| renderCompleted : Model -> Html Msg | ||||
| renderCompleted model = | ||||
|     div [ class "column" ] | ||||
|         [ div [ class "ui center aligned basic segment" ] | ||||
|             [ i [ class "ui large angle double down icon" ] [] | ||||
|             ] | ||||
|         , div [ class "ui centered cards" ] | ||||
|             (List.map (renderInfoCard model) model.state.completed) | ||||
|         ] | ||||
|  | ||||
|  | ||||
| renderProgressCard : Model -> JobDetail -> Html Msg | ||||
| renderProgressCard model job = | ||||
|     div [ class "ui fluid card" ] | ||||
|         [ Comp.Progress.topAttachedIndicating job.progress | ||||
|         , Html.map (DimmerMsg job) (Comp.YesNoDimmer.view2 (model.cancelJobRequest == Just job.id) dimmerSettings model.deleteConfirm) | ||||
|         , div [ class "content" ] | ||||
|             [ div [ class "right floated meta" ] | ||||
|                 [ div [ class "ui label" ] | ||||
|                     [ text job.state | ||||
|                     , div [ class "detail" ] | ||||
|                         [ Maybe.withDefault "" job.worker |> text | ||||
|                         ] | ||||
|                     ] | ||||
|                 , div [ class "ui basic label" ] | ||||
|                     [ i [ class "clock icon" ] [] | ||||
|                     , div [ class "detail" ] | ||||
|                         [ getDuration model job |> Maybe.withDefault "-:-" |> text | ||||
|                         ] | ||||
|                     ] | ||||
|                 ] | ||||
|             , i [ class "asterisk loading icon" ] [] | ||||
|             , text job.name | ||||
|             ] | ||||
|         , div [ class "content" ] | ||||
|             [ div [ class "job-log" ] | ||||
|                 (List.map renderLogLine job.logs) | ||||
|             ] | ||||
|         , div [ class "meta" ] | ||||
|             [ div [ class "right floated" ] | ||||
|                 [ button [ class "ui button", onClick (RequestCancelJob job) ] | ||||
|                     [ text "Cancel" | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| renderLogLine : JobLogEvent -> Html Msg | ||||
| renderLogLine log = | ||||
|     span [ class (String.toLower log.level) ] | ||||
|         [ formatIsoDateTime log.time |> text | ||||
|         , text ": " | ||||
|         , text log.message | ||||
|         , br [] [] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| isFinal : JobDetail -> Bool | ||||
| isFinal job = | ||||
|     case job.state of | ||||
|         "failed" -> | ||||
|             True | ||||
|  | ||||
|         "success" -> | ||||
|             True | ||||
|  | ||||
|         "cancelled" -> | ||||
|             True | ||||
|  | ||||
|         _ -> | ||||
|             False | ||||
|  | ||||
|  | ||||
| dimmerSettings : Comp.YesNoDimmer.Settings | ||||
| dimmerSettings = | ||||
|     let | ||||
|         defaults = | ||||
|             Comp.YesNoDimmer.defaultSettings | ||||
|     in | ||||
|     { defaults | headerClass = "ui inverted header", headerIcon = "", message = "Cancel/Delete this job?" } | ||||
|  | ||||
|  | ||||
| renderInfoCard : Model -> JobDetail -> Html Msg | ||||
| renderInfoCard model job = | ||||
|     let | ||||
|         prio = | ||||
|             Data.Priority.fromString job.priority | ||||
|                 |> Maybe.withDefault Data.Priority.Low | ||||
|     in | ||||
|     div | ||||
|         [ classList | ||||
|             [ ( "ui fluid card", True ) | ||||
|             , ( jobStateColor job, True ) | ||||
|             ] | ||||
|         ] | ||||
|         [ Html.map (DimmerMsg job) (Comp.YesNoDimmer.view2 (model.cancelJobRequest == Just job.id) dimmerSettings model.deleteConfirm) | ||||
|         , div [ class "content" ] | ||||
|             [ div [ class "right floated" ] | ||||
|                 [ if isFinal job || job.state == "stuck" then | ||||
|                     span [ onClick (ShowLog job) ] | ||||
|                         [ i [ class "file link icon", title "Show log" ] [] | ||||
|                         ] | ||||
|  | ||||
|                   else | ||||
|                     span [] [] | ||||
|                 , i [ class "delete link icon", title "Remove", onClick (RequestCancelJob job) ] [] | ||||
|                 ] | ||||
|             , if isFinal job then | ||||
|                 span [ class "invisible" ] [] | ||||
|  | ||||
|               else | ||||
|                 div [ class "right floated" ] | ||||
|                     [ div [ class "meta" ] | ||||
|                         [ getDuration model job |> Maybe.withDefault "-:-" |> text | ||||
|                         ] | ||||
|                     ] | ||||
|             , i | ||||
|                 [ classList | ||||
|                     [ ( "check icon", job.state == "success" ) | ||||
|                     , ( "redo icon", job.state == "stuck" ) | ||||
|                     , ( "bolt icon", job.state == "failed" ) | ||||
|                     , ( "meh outline icon", job.state == "canceled" ) | ||||
|                     , ( "cog icon", not (isFinal job) && job.state /= "stuck" ) | ||||
|                     ] | ||||
|                 ] | ||||
|                 [] | ||||
|             , text job.name | ||||
|             ] | ||||
|         , div [ class "content" ] | ||||
|             [ div [ class "right floated" ] | ||||
|                 [ if isFinal job then | ||||
|                     div [ class ("ui basic label " ++ jobStateColor job) ] | ||||
|                         [ i [ class "clock icon" ] [] | ||||
|                         , div [ class "detail" ] | ||||
|                             [ getDuration model job |> Maybe.withDefault "-:-" |> text | ||||
|                             ] | ||||
|                         ] | ||||
|  | ||||
|                   else | ||||
|                     span [ class "invisible" ] [] | ||||
|                 , div [ class ("ui basic label " ++ jobStateColor job) ] | ||||
|                     [ text "Retries" | ||||
|                     , div [ class "detail" ] | ||||
|                         [ job.retries |> String.fromInt |> text | ||||
|                         ] | ||||
|                     ] | ||||
|                 , case job.state of | ||||
|                     "waiting" -> | ||||
|                         a | ||||
|                             [ class ("ui basic label " ++ jobStateColor job) | ||||
|                             , onClick (ChangePrio job.id (Data.Priority.next prio)) | ||||
|                             , href "#" | ||||
|                             , title "Change priority of this job" | ||||
|                             ] | ||||
|                             [ i [ class "sort numeric up icon" ] [] | ||||
|                             , text "Prio" | ||||
|                             , div [ class "detail" ] | ||||
|                                 [ code [] | ||||
|                                     [ Data.Priority.fromString job.priority | ||||
|                                         |> Maybe.map Data.Priority.toName | ||||
|                                         |> Maybe.withDefault job.priority | ||||
|                                         |> text | ||||
|                                     ] | ||||
|                                 ] | ||||
|                             ] | ||||
|  | ||||
|                     _ -> | ||||
|                         div | ||||
|                             [ class ("ui basic label " ++ jobStateColor job) | ||||
|                             ] | ||||
|                             [ text "Prio" | ||||
|                             , div [ class "detail" ] | ||||
|                                 [ code [] | ||||
|                                     [ Data.Priority.fromString job.priority | ||||
|                                         |> Maybe.map Data.Priority.toName | ||||
|                                         |> Maybe.withDefault job.priority | ||||
|                                         |> text | ||||
|                                     ] | ||||
|                                 ] | ||||
|                             ] | ||||
|                 ] | ||||
|             , jobStateLabel job | ||||
|             , div [ class "ui basic label" ] | ||||
|                 [ Util.Time.formatDateTime job.submitted |> text | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| jobStateColor : JobDetail -> String | ||||
| jobStateColor job = | ||||
|     case job.state of | ||||
|         "success" -> | ||||
|             "green" | ||||
|  | ||||
|         "failed" -> | ||||
|             "red" | ||||
|  | ||||
|         "canceled" -> | ||||
|             "orange" | ||||
|  | ||||
|         "stuck" -> | ||||
|             "purple" | ||||
|  | ||||
|         "scheduled" -> | ||||
|             "blue" | ||||
|  | ||||
|         "waiting" -> | ||||
|             "grey" | ||||
|  | ||||
|         _ -> | ||||
|             "" | ||||
|  | ||||
|  | ||||
| jobStateLabel : JobDetail -> Html Msg | ||||
| jobStateLabel job = | ||||
|     let | ||||
|         col = | ||||
|             jobStateColor job | ||||
|     in | ||||
|     div [ class ("ui label " ++ col) ] | ||||
|         [ text job.state | ||||
|         ] | ||||
| @@ -1,166 +0,0 @@ | ||||
| module Page.Register.View exposing (view) | ||||
|  | ||||
| import Data.Flags exposing (Flags) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onClick, onInput, onSubmit) | ||||
| import Page exposing (Page(..)) | ||||
| import Page.Register.Data exposing (..) | ||||
|  | ||||
|  | ||||
| view : Flags -> Model -> Html Msg | ||||
| view flags model = | ||||
|     div [ class "register-page" ] | ||||
|         [ div [ class "ui centered grid" ] | ||||
|             [ div [ class "row" ] | ||||
|                 [ div [ class "sixteen wide mobile twelve wide tablet six wide computer column" ] | ||||
|                     [ div [ class "ui segment register-view" ] | ||||
|                         [ h1 [ class "ui cener aligned icon header" ] | ||||
|                             [ img | ||||
|                                 [ class "ui image" | ||||
|                                 , src (flags.config.docspellAssetPath ++ "/img/logo-96.png") | ||||
|                                 ] | ||||
|                                 [] | ||||
|                             , div [ class "content" ] | ||||
|                                 [ text "Sign up @ Docspell" | ||||
|                                 ] | ||||
|                             ] | ||||
|                         , Html.form | ||||
|                             [ class "ui large error form raised segment" | ||||
|                             , onSubmit RegisterSubmit | ||||
|                             , autocomplete False | ||||
|                             ] | ||||
|                             [ div [ class "required field" ] | ||||
|                                 [ label [] [ text "Collective ID" ] | ||||
|                                 , div [ class "ui left icon input" ] | ||||
|                                     [ input | ||||
|                                         [ type_ "text" | ||||
|                                         , autocomplete False | ||||
|                                         , onInput SetCollId | ||||
|                                         , value model.collId | ||||
|                                         , autofocus True | ||||
|                                         ] | ||||
|                                         [] | ||||
|                                     , i [ class "users icon" ] [] | ||||
|                                     ] | ||||
|                                 ] | ||||
|                             , div [ class "required field" ] | ||||
|                                 [ label [] [ text "User Login" ] | ||||
|                                 , div [ class "ui left icon input" ] | ||||
|                                     [ input | ||||
|                                         [ type_ "text" | ||||
|                                         , autocomplete False | ||||
|                                         , onInput SetLogin | ||||
|                                         , value model.login | ||||
|                                         ] | ||||
|                                         [] | ||||
|                                     , i [ class "user icon" ] [] | ||||
|                                     ] | ||||
|                                 ] | ||||
|                             , div | ||||
|                                 [ class "required field" | ||||
|                                 ] | ||||
|                                 [ label [] [ text "Password" ] | ||||
|                                 , div [ class "ui left icon action input" ] | ||||
|                                     [ input | ||||
|                                         [ type_ <| | ||||
|                                             if model.showPass1 then | ||||
|                                                 "text" | ||||
|  | ||||
|                                             else | ||||
|                                                 "password" | ||||
|                                         , autocomplete False | ||||
|                                         , onInput SetPass1 | ||||
|                                         , value model.pass1 | ||||
|                                         ] | ||||
|                                         [] | ||||
|                                     , i [ class "lock icon" ] [] | ||||
|                                     , button [ class "ui icon button", onClick ToggleShowPass1 ] | ||||
|                                         [ i [ class "eye icon" ] [] | ||||
|                                         ] | ||||
|                                     ] | ||||
|                                 ] | ||||
|                             , div | ||||
|                                 [ class "required field" | ||||
|                                 ] | ||||
|                                 [ label [] [ text "Password (repeat)" ] | ||||
|                                 , div [ class "ui left icon action input" ] | ||||
|                                     [ input | ||||
|                                         [ type_ <| | ||||
|                                             if model.showPass2 then | ||||
|                                                 "text" | ||||
|  | ||||
|                                             else | ||||
|                                                 "password" | ||||
|                                         , autocomplete False | ||||
|                                         , onInput SetPass2 | ||||
|                                         , value model.pass2 | ||||
|                                         ] | ||||
|                                         [] | ||||
|                                     , i [ class "lock icon" ] [] | ||||
|                                     , button [ class "ui icon button", onClick ToggleShowPass2 ] | ||||
|                                         [ i [ class "eye icon" ] [] | ||||
|                                         ] | ||||
|                                     ] | ||||
|                                 ] | ||||
|                             , div | ||||
|                                 [ classList | ||||
|                                     [ ( "field", True ) | ||||
|                                     , ( "invisible", flags.config.signupMode /= "invite" ) | ||||
|                                     ] | ||||
|                                 ] | ||||
|                                 [ label [] [ text "Invitation Key" ] | ||||
|                                 , div [ class "ui left icon input" ] | ||||
|                                     [ input | ||||
|                                         [ type_ "text" | ||||
|                                         , autocomplete False | ||||
|                                         , onInput SetInvite | ||||
|                                         , model.invite |> Maybe.withDefault "" |> value | ||||
|                                         ] | ||||
|                                         [] | ||||
|                                     , i [ class "key icon" ] [] | ||||
|                                     ] | ||||
|                                 ] | ||||
|                             , button | ||||
|                                 [ class "ui primary button" | ||||
|                                 , type_ "submit" | ||||
|                                 ] | ||||
|                                 [ text "Submit" | ||||
|                                 ] | ||||
|                             ] | ||||
|                         , resultMessage model | ||||
|                         , div [ class "ui very basic right aligned segment" ] | ||||
|                             [ text "Already signed up? " | ||||
|                             , a [ class "ui link", Page.href (LoginPage Nothing) ] | ||||
|                                 [ i [ class "sign in icon" ] [] | ||||
|                                 , text "Sign in" | ||||
|                                 ] | ||||
|                             ] | ||||
|                         ] | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| resultMessage : Model -> Html Msg | ||||
| resultMessage model = | ||||
|     case model.result of | ||||
|         Just r -> | ||||
|             if r.success then | ||||
|                 div [ class "ui success message" ] | ||||
|                     [ text "Registration successful." | ||||
|                     ] | ||||
|  | ||||
|             else | ||||
|                 div [ class "ui error message" ] | ||||
|                     [ text r.message | ||||
|                     ] | ||||
|  | ||||
|         Nothing -> | ||||
|             if List.isEmpty model.errorMsg then | ||||
|                 span [ class "invisible" ] [] | ||||
|  | ||||
|             else | ||||
|                 div [ class "ui error message" ] | ||||
|                     (List.map (\s -> div [] [ text s ]) model.errorMsg) | ||||
| @@ -1,252 +0,0 @@ | ||||
| module Page.Upload.View exposing (view) | ||||
|  | ||||
| import Comp.Dropzone | ||||
| import Comp.FixedDropdown | ||||
| import Comp.Progress | ||||
| import Dict | ||||
| import File exposing (File) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onCheck, onClick) | ||||
| import Page exposing (Page(..)) | ||||
| import Page.Upload.Data exposing (..) | ||||
| import Util.File exposing (makeFileId) | ||||
| import Util.Maybe | ||||
| import Util.Size | ||||
|  | ||||
|  | ||||
| view : Maybe String -> Model -> Html Msg | ||||
| view mid model = | ||||
|     div [ class "upload-page ui grid container" ] | ||||
|         [ div [ class "row" ] | ||||
|             [ div [ class "sixteen wide column" ] | ||||
|                 [ div [ class "ui top attached segment" ] | ||||
|                     [ renderForm model | ||||
|                     ] | ||||
|                 , Html.map DropzoneMsg (Comp.Dropzone.view dropzoneSettings model.dropzone) | ||||
|                 , div [ class "ui bottom attached segment" ] | ||||
|                     [ a [ class "ui primary button", href "#", onClick SubmitUpload ] | ||||
|                         [ text "Submit" | ||||
|                         ] | ||||
|                     , a [ class "ui secondary button", href "#", onClick Clear ] | ||||
|                         [ text "Reset" | ||||
|                         ] | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         , if isDone model && hasErrors model then | ||||
|             renderErrorMsg model | ||||
|  | ||||
|           else | ||||
|             span [ class "invisible" ] [] | ||||
|         , if List.isEmpty model.files then | ||||
|             span [] [] | ||||
|  | ||||
|           else if isSuccessAll model then | ||||
|             renderSuccessMsg (Util.Maybe.nonEmpty mid) model | ||||
|  | ||||
|           else | ||||
|             renderUploads model | ||||
|         ] | ||||
|  | ||||
|  | ||||
| dropzoneSettings : Comp.Dropzone.Settings | ||||
| dropzoneSettings = | ||||
|     let | ||||
|         ds = | ||||
|             Comp.Dropzone.defaultSettings | ||||
|     in | ||||
|     { ds | ||||
|         | classList = | ||||
|             \m -> | ||||
|                 [ ( "ui attached blue placeholder segment dropzone", True ) | ||||
|                 , ( "dragging", m.hover ) | ||||
|                 , ( "disabled", not m.active ) | ||||
|                 ] | ||||
|     } | ||||
|  | ||||
|  | ||||
| renderErrorMsg : Model -> Html Msg | ||||
| renderErrorMsg _ = | ||||
|     div [ class "row" ] | ||||
|         [ div [ class "sixteen wide column" ] | ||||
|             [ div [ class "ui large error message" ] | ||||
|                 [ h3 [ class "ui header" ] | ||||
|                     [ i [ class "meh outline icon" ] [] | ||||
|                     , text "Some files failed to upload" | ||||
|                     ] | ||||
|                 , text "There were errors uploading some files." | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| renderSuccessMsg : Bool -> Model -> Html Msg | ||||
| renderSuccessMsg public _ = | ||||
|     div [ class "row" ] | ||||
|         [ div [ class "sixteen wide column" ] | ||||
|             [ div [ class "ui large success message" ] | ||||
|                 [ h3 [ class "ui header" ] | ||||
|                     [ i [ class "smile outline icon" ] [] | ||||
|                     , text "All files uploaded" | ||||
|                     ] | ||||
|                 , if public then | ||||
|                     p [] [] | ||||
|  | ||||
|                   else | ||||
|                     p [] | ||||
|                         [ text "Your files have been successfully uploaded. They are now being processed. Check the " | ||||
|                         , a [ class "ui link", Page.href HomePage ] | ||||
|                             [ text "Items page" | ||||
|                             ] | ||||
|                         , text " later where the files will arrive eventually. Or go to the " | ||||
|                         , a [ class "ui link", Page.href QueuePage ] | ||||
|                             [ text "Processing Page" | ||||
|                             ] | ||||
|                         , text " to view the current processing state." | ||||
|                         ] | ||||
|                 , p [] | ||||
|                     [ text "Click " | ||||
|                     , a [ class "ui link", href "#", onClick Clear ] | ||||
|                         [ text "Reset" | ||||
|                         ] | ||||
|                     , text " to upload more files." | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| renderUploads : Model -> Html Msg | ||||
| renderUploads model = | ||||
|     div [ class "row" ] | ||||
|         [ div [ class "sixteen wide column" ] | ||||
|             [ div [ class "ui basic segment" ] | ||||
|                 [ h2 [ class "ui header" ] | ||||
|                     [ text "Selected Files" | ||||
|                     ] | ||||
|                 , div [ class "ui items" ] <| | ||||
|                     if model.singleItem then | ||||
|                         List.map (renderFileItem model (Just uploadAllTracker)) model.files | ||||
|  | ||||
|                     else | ||||
|                         List.map (renderFileItem model Nothing) model.files | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| getProgress : Model -> File -> Int | ||||
| getProgress model file = | ||||
|     let | ||||
|         key = | ||||
|             if model.singleItem then | ||||
|                 uploadAllTracker | ||||
|  | ||||
|             else | ||||
|                 makeFileId file | ||||
|     in | ||||
|     Dict.get key model.loading | ||||
|         |> Maybe.withDefault 0 | ||||
|  | ||||
|  | ||||
| renderFileItem : Model -> Maybe String -> File -> Html Msg | ||||
| renderFileItem model mtracker file = | ||||
|     let | ||||
|         name = | ||||
|             File.name file | ||||
|  | ||||
|         size = | ||||
|             File.size file | ||||
|                 |> toFloat | ||||
|                 |> Util.Size.bytesReadable Util.Size.B | ||||
|     in | ||||
|     div [ class "item" ] | ||||
|         [ i | ||||
|             [ classList | ||||
|                 [ ( "large", True ) | ||||
|                 , ( "file outline icon", isIdle model file ) | ||||
|                 , ( "loading spinner icon", isLoading model file ) | ||||
|                 , ( "green check icon", isCompleted model file ) | ||||
|                 , ( "red bolt icon", isError model file ) | ||||
|                 ] | ||||
|             ] | ||||
|             [] | ||||
|         , div [ class "middle aligned content" ] | ||||
|             [ div [ class "header" ] | ||||
|                 [ text name | ||||
|                 ] | ||||
|             , div [ class "right floated meta" ] | ||||
|                 [ text size | ||||
|                 ] | ||||
|             , div [ class "description" ] | ||||
|                 [ Comp.Progress.smallIndicating (getProgress model file) | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| renderForm : Model -> Html Msg | ||||
| renderForm model = | ||||
|     div [ class "row" ] | ||||
|         [ Html.form [ class "ui form" ] | ||||
|             [ div [ class "grouped fields" ] | ||||
|                 [ div [ class "field" ] | ||||
|                     [ div [ class "ui radio checkbox" ] | ||||
|                         [ input | ||||
|                             [ type_ "radio" | ||||
|                             , checked model.incoming | ||||
|                             , onCheck (\_ -> ToggleIncoming) | ||||
|                             ] | ||||
|                             [] | ||||
|                         , label [] [ text "Incoming" ] | ||||
|                         ] | ||||
|                     ] | ||||
|                 , div [ class "field" ] | ||||
|                     [ div [ class "ui radio checkbox" ] | ||||
|                         [ input | ||||
|                             [ type_ "radio" | ||||
|                             , checked (not model.incoming) | ||||
|                             , onCheck (\_ -> ToggleIncoming) | ||||
|                             ] | ||||
|                             [] | ||||
|                         , label [] [ text "Outgoing" ] | ||||
|                         ] | ||||
|                     ] | ||||
|                 ] | ||||
|             , div [ class "inline field" ] | ||||
|                 [ div [ class "ui checkbox" ] | ||||
|                     [ input | ||||
|                         [ type_ "checkbox" | ||||
|                         , checked model.singleItem | ||||
|                         , onCheck (\_ -> ToggleSingleItem) | ||||
|                         ] | ||||
|                         [] | ||||
|                     , label [] [ text "All files are one single item" ] | ||||
|                     ] | ||||
|                 ] | ||||
|             , div [ class "inline field" ] | ||||
|                 [ div [ class "ui checkbox" ] | ||||
|                     [ input | ||||
|                         [ type_ "checkbox" | ||||
|                         , checked model.skipDuplicates | ||||
|                         , onCheck (\_ -> ToggleSkipDuplicates) | ||||
|                         ] | ||||
|                         [] | ||||
|                     , label [] [ text "Skip files already present in docspell" ] | ||||
|                     ] | ||||
|                 ] | ||||
|             , div [ class "inline field" ] | ||||
|                 [ label [] [ text "Language:" ] | ||||
|                 , Html.map LanguageMsg | ||||
|                     (Comp.FixedDropdown.view | ||||
|                         (Maybe.map mkLanguageItem model.language) | ||||
|                         model.languageModel | ||||
|                     ) | ||||
|                 , div [ class "small-info" ] | ||||
|                     [ text "Used for text extraction and analysis. The collective's " | ||||
|                     , text "default language is used if not specified here." | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
| @@ -1,185 +0,0 @@ | ||||
| module Page.UserSettings.View exposing (view) | ||||
|  | ||||
| import Comp.ChangePasswordForm | ||||
| import Comp.EmailSettingsManage | ||||
| import Comp.ImapSettingsManage | ||||
| import Comp.NotificationManage | ||||
| import Comp.ScanMailboxManage | ||||
| import Comp.UiSettingsManage | ||||
| import Data.Flags exposing (Flags) | ||||
| import Data.UiSettings exposing (UiSettings) | ||||
| import Html exposing (..) | ||||
| import Html.Attributes exposing (..) | ||||
| import Html.Events exposing (onClick) | ||||
| import Page.UserSettings.Data exposing (..) | ||||
| import Util.Html exposing (classActive) | ||||
|  | ||||
|  | ||||
| view : Flags -> UiSettings -> Model -> Html Msg | ||||
| view flags settings model = | ||||
|     div [ class "usersetting-page ui padded grid" ] | ||||
|         [ div [ class "sixteen wide mobile four wide tablet four wide computer column" ] | ||||
|             [ h4 [ class "ui top attached ablue-comp header" ] | ||||
|                 [ text "User Settings" | ||||
|                 ] | ||||
|             , div [ class "ui attached fluid segment" ] | ||||
|                 [ div [ class "ui fluid vertical secondary menu" ] | ||||
|                     [ makeTab model ChangePassTab "Change Password" "user secret icon" | ||||
|                     , makeTab model EmailSettingsTab "E-Mail Settings (SMTP)" "mail icon" | ||||
|                     , makeTab model ImapSettingsTab "E-Mail Settings (IMAP)" "mail icon" | ||||
|                     , makeTab model NotificationTab "Notification Task" "bullhorn icon" | ||||
|                     , makeTab model ScanMailboxTab "Scan Mailbox Task" "envelope open outline icon" | ||||
|                     , makeTab model UiSettingsTab "UI Settings" "cog icon" | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         , div [ class "sixteen wide mobile twelve wide tablet twelve wide computer column" ] | ||||
|             [ div [ class "" ] | ||||
|                 (case model.currentTab of | ||||
|                     Just ChangePassTab -> | ||||
|                         viewChangePassword model | ||||
|  | ||||
|                     Just EmailSettingsTab -> | ||||
|                         viewEmailSettings settings model | ||||
|  | ||||
|                     Just NotificationTab -> | ||||
|                         viewNotificationManage settings model | ||||
|  | ||||
|                     Just ImapSettingsTab -> | ||||
|                         viewImapSettings settings model | ||||
|  | ||||
|                     Just ScanMailboxTab -> | ||||
|                         viewScanMailboxManage settings model | ||||
|  | ||||
|                     Just UiSettingsTab -> | ||||
|                         viewUiSettings flags settings model | ||||
|  | ||||
|                     Nothing -> | ||||
|                         [] | ||||
|                 ) | ||||
|             ] | ||||
|         ] | ||||
|  | ||||
|  | ||||
| makeTab : Model -> Tab -> String -> String -> Html Msg | ||||
| makeTab model tab header icon = | ||||
|     a | ||||
|         [ classActive (model.currentTab == Just tab) "link icon item" | ||||
|         , onClick (SetTab tab) | ||||
|         , href "#" | ||||
|         ] | ||||
|         [ i [ class icon ] [] | ||||
|         , text header | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewUiSettings : Flags -> UiSettings -> Model -> List (Html Msg) | ||||
| viewUiSettings flags settings model = | ||||
|     [ h2 [ class "ui header" ] | ||||
|         [ i [ class "cog icon" ] [] | ||||
|         , text "UI Settings" | ||||
|         ] | ||||
|     , p [] | ||||
|         [ text "These settings only affect the web ui. They are stored in the browser, " | ||||
|         , text "so they are separated between browsers and devices." | ||||
|         ] | ||||
|     , Html.map UiSettingsMsg | ||||
|         (Comp.UiSettingsManage.view | ||||
|             flags | ||||
|             settings | ||||
|             "ui segment" | ||||
|             model.uiSettingsModel | ||||
|         ) | ||||
|     ] | ||||
|  | ||||
|  | ||||
| viewEmailSettings : UiSettings -> Model -> List (Html Msg) | ||||
| viewEmailSettings settings model = | ||||
|     [ h2 [ class "ui header" ] | ||||
|         [ i [ class "mail icon" ] [] | ||||
|         , div [ class "content" ] | ||||
|             [ text "E-Mail Settings (Smtp)" | ||||
|             ] | ||||
|         ] | ||||
|     , Html.map EmailSettingsMsg (Comp.EmailSettingsManage.view settings model.emailSettingsModel) | ||||
|     ] | ||||
|  | ||||
|  | ||||
| viewImapSettings : UiSettings -> Model -> List (Html Msg) | ||||
| viewImapSettings settings model = | ||||
|     [ h2 [ class "ui header" ] | ||||
|         [ i [ class "mail icon" ] [] | ||||
|         , div [ class "content" ] | ||||
|             [ text "E-Mail Settings (Imap)" | ||||
|             ] | ||||
|         ] | ||||
|     , Html.map ImapSettingsMsg (Comp.ImapSettingsManage.view settings model.imapSettingsModel) | ||||
|     ] | ||||
|  | ||||
|  | ||||
| viewChangePassword : Model -> List (Html Msg) | ||||
| viewChangePassword model = | ||||
|     [ h2 [ class "ui header" ] | ||||
|         [ i [ class "ui user secret icon" ] [] | ||||
|         , div [ class "content" ] | ||||
|             [ text "Change Password" | ||||
|             ] | ||||
|         ] | ||||
|     , Html.map ChangePassMsg (Comp.ChangePasswordForm.view model.changePassModel) | ||||
|     ] | ||||
|  | ||||
|  | ||||
| viewNotificationManage : UiSettings -> Model -> List (Html Msg) | ||||
| viewNotificationManage settings model = | ||||
|     [ h2 [ class "ui header" ] | ||||
|         [ i [ class "ui bullhorn icon" ] [] | ||||
|         , div [ class "content" ] | ||||
|             [ text "Notification" | ||||
|             ] | ||||
|         ] | ||||
|     , p [] | ||||
|         [ text """ | ||||
|             Docspell can notify you once the due dates of your items | ||||
|             come closer. Notification is done via e-mail. You need to | ||||
|             provide a connection in your e-mail settings.""" | ||||
|         ] | ||||
|     , p [] | ||||
|         [ text "Docspell finds all items that are due in " | ||||
|         , em [] [ text "Remind Days" ] | ||||
|         , text " days and sends this list via e-mail." | ||||
|         ] | ||||
|     , Html.map NotificationMsg | ||||
|         (Comp.NotificationManage.view settings model.notificationModel) | ||||
|     ] | ||||
|  | ||||
|  | ||||
| viewScanMailboxManage : UiSettings -> Model -> List (Html Msg) | ||||
| viewScanMailboxManage settings model = | ||||
|     [ h2 [ class "ui header" ] | ||||
|         [ i [ class "ui envelope open outline icon" ] [] | ||||
|         , div [ class "content" ] | ||||
|             [ text "Scan Mailbox" | ||||
|             ] | ||||
|         ] | ||||
|     , p [] | ||||
|         [ text "Docspell can scan folders of your mailbox to import your mails. " | ||||
|         , text "You need to provide a connection in " | ||||
|         , text "your e-mail (imap) settings." | ||||
|         ] | ||||
|     , p [] | ||||
|         [ text """ | ||||
|             Docspell goes through all configured folders and imports | ||||
|             mails matching the search criteria. Mails are skipped if | ||||
|             they were imported in a previous run and the corresponding | ||||
|             items still exist. After submitting a mail into docspell, | ||||
|             you can choose to move it to another folder, to delete it | ||||
|             or to just leave it there. In the latter case you should | ||||
|             adjust the schedule to avoid reading over the same mails | ||||
|             again.""" | ||||
|         ] | ||||
|     , Html.map ScanMailboxMsg | ||||
|         (Comp.ScanMailboxManage.view | ||||
|             settings | ||||
|             model.scanMailboxModel | ||||
|         ) | ||||
|     ] | ||||
| @@ -40,7 +40,6 @@ object Dependencies { | ||||
|   val TikaVersion             = "1.25" | ||||
|   val YamuscaVersion          = "0.8.0" | ||||
|   val SwaggerUIVersion        = "3.44.0" | ||||
|   val FomanticUIVersion       = "2.8.7-3" | ||||
|   val TwelveMonkeysVersion    = "3.6.4" | ||||
|   val JQueryVersion           = "3.5.1" | ||||
|   val ViewerJSVersion         = "0.5.8" | ||||
| @@ -282,7 +281,6 @@ object Dependencies { | ||||
|  | ||||
|   val webjars = Seq( | ||||
|     "org.webjars"      % "swagger-ui"            % SwaggerUIVersion, | ||||
|     "com.github.eikek" % "fomantic-slim-default" % FomanticUIVersion, | ||||
|     "org.webjars"      % "viewerjs"              % ViewerJSVersion, | ||||
|     "org.webjars"      % "clipboard.js"          % ClipboardJsVersion | ||||
|   ) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user