From 0e8c9b1819b673f651bb533246d7212399ebdde7 Mon Sep 17 00:00:00 2001 From: Eike Kettner Date: Sun, 5 Jul 2020 00:37:27 +0200 Subject: [PATCH] Initial outline for managing spaces --- modules/webapp/src/main/elm/Api.elm | 15 ++ modules/webapp/src/main/elm/App/Data.elm | 10 +- .../webapp/src/main/elm/Comp/SpaceDetail.elm | 154 ++++++++++++++++++ .../webapp/src/main/elm/Comp/SpaceManage.elm | 118 ++++++++++++++ .../webapp/src/main/elm/Comp/SpaceTable.elm | 89 ++++++++++ modules/webapp/src/main/elm/Data/Icons.elm | 12 ++ .../src/main/elm/Page/ManageData/Data.elm | 26 ++- .../src/main/elm/Page/ManageData/Update.elm | 17 ++ .../src/main/elm/Page/ManageData/View.elm | 27 +++ 9 files changed, 457 insertions(+), 11 deletions(-) create mode 100644 modules/webapp/src/main/elm/Comp/SpaceDetail.elm create mode 100644 modules/webapp/src/main/elm/Comp/SpaceManage.elm create mode 100644 modules/webapp/src/main/elm/Comp/SpaceTable.elm diff --git a/modules/webapp/src/main/elm/Api.elm b/modules/webapp/src/main/elm/Api.elm index b84880b0..f09d3a0c 100644 --- a/modules/webapp/src/main/elm/Api.elm +++ b/modules/webapp/src/main/elm/Api.elm @@ -42,6 +42,7 @@ module Api exposing , getScanMailbox , getSentMails , getSources + , getSpaces , getTags , getUsers , itemDetail @@ -132,6 +133,7 @@ import Api.Model.SentMails exposing (SentMails) import Api.Model.SimpleMail exposing (SimpleMail) import Api.Model.Source exposing (Source) import Api.Model.SourceList exposing (SourceList) +import Api.Model.SpaceList exposing (SpaceList) import Api.Model.Tag exposing (Tag) import Api.Model.TagList exposing (TagList) import Api.Model.User exposing (User) @@ -150,6 +152,19 @@ import Util.Http as Http2 +--- Spaces + + +getSpaces : Flags -> (Result Http.Error SpaceList -> msg) -> Cmd msg +getSpaces flags receive = + Http2.authGet + { url = flags.config.baseUrl ++ "/api/v1/sec/space" + , account = getAccount flags + , expect = Http.expectJson receive Api.Model.SpaceList.decoder + } + + + --- Full-Text diff --git a/modules/webapp/src/main/elm/App/Data.elm b/modules/webapp/src/main/elm/App/Data.elm index f8574248..58660587 100644 --- a/modules/webapp/src/main/elm/App/Data.elm +++ b/modules/webapp/src/main/elm/App/Data.elm @@ -57,6 +57,9 @@ init key url flags settings = ( um, uc ) = Page.UserSettings.Data.init flags settings + + ( mdm, mdc ) = + Page.ManageData.Data.init flags in ( { flags = flags , key = key @@ -64,7 +67,7 @@ init key url flags settings = , version = Api.Model.VersionInfo.empty , homeModel = Page.Home.Data.init flags , loginModel = Page.Login.Data.emptyModel - , manageDataModel = Page.ManageData.Data.emptyModel + , manageDataModel = mdm , collSettingsModel = Page.CollectiveSettings.Data.emptyModel , userSettingsModel = um , queueModel = Page.Queue.Data.emptyModel @@ -76,7 +79,10 @@ init key url flags settings = , subs = Sub.none , uiSettings = settings } - , Cmd.map UserSettingsMsg uc + , Cmd.batch + [ Cmd.map UserSettingsMsg uc + , Cmd.map ManageDataMsg mdc + ] ) diff --git a/modules/webapp/src/main/elm/Comp/SpaceDetail.elm b/modules/webapp/src/main/elm/Comp/SpaceDetail.elm new file mode 100644 index 00000000..3df6c4cf --- /dev/null +++ b/modules/webapp/src/main/elm/Comp/SpaceDetail.elm @@ -0,0 +1,154 @@ +module Comp.SpaceDetail exposing + ( Model + , Msg + , init + , update + , view + ) + +import Api +import Api.Model.BasicResult exposing (BasicResult) +import Api.Model.IdName exposing (IdName) +import Api.Model.SpaceDetail exposing (SpaceDetail) +import Api.Model.User exposing (User) +import Api.Model.UserList exposing (UserList) +import Comp.FixedDropdown +import Data.Flags exposing (Flags) +import Html exposing (..) +import Html.Attributes exposing (..) +import Html.Events exposing (onClick, onInput) +import Http +import Util.Http +import Util.Maybe + + +type alias Model = + { result : Maybe BasicResult + , name : Maybe String + , members : List IdName + , users : List User + , memberDropdown : Comp.FixedDropdown.Model IdName + , selectedMember : Maybe IdName + } + + +type Msg + = SetName String + | MemberDropdownMsg (Comp.FixedDropdown.Msg IdName) + + +init : List User -> SpaceDetail -> Model +init users space = + { result = Nothing + , name = Util.Maybe.fromString space.name + , members = space.members + , users = users + , memberDropdown = + Comp.FixedDropdown.initMap .name + (makeOptions users space.members) + , selectedMember = Nothing + } + + +makeOptions : List User -> List IdName -> List IdName +makeOptions users members = + let + toIdName u = + IdName u.id u.login + + notMember idn = + List.member idn members |> not + in + List.map toIdName users + |> List.filter notMember + + + +--- Update + + +update : Flags -> Msg -> Model -> ( Model, Cmd Msg ) +update flags msg model = + case msg of + SetName str -> + ( { model | name = Util.Maybe.fromString str } + , Cmd.none + ) + + MemberDropdownMsg lmsg -> + let + ( mm, sel ) = + Comp.FixedDropdown.update lmsg model.memberDropdown + in + ( { model + | memberDropdown = mm + , selectedMember = sel + } + , Cmd.none + ) + + + +--- View + + +view : Model -> Html Msg +view model = + div [] + [ 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" + ] + [ i [ class "save icon" ] [] + ] + ] + , 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" + ] + [ text "Add" + ] + ] + ] + , div + [ class "ui list" + ] + (List.map viewMember model.members) + ] + + +makeItem : IdName -> Comp.FixedDropdown.Item IdName +makeItem idn = + Comp.FixedDropdown.Item idn idn.name + + +viewMember : IdName -> Html Msg +viewMember member = + div + [ class "item" + ] + [ button + [ class "ui primary icon button" + ] + [ i [ class "delete icon" ] [] + ] + ] diff --git a/modules/webapp/src/main/elm/Comp/SpaceManage.elm b/modules/webapp/src/main/elm/Comp/SpaceManage.elm new file mode 100644 index 00000000..a2af0fda --- /dev/null +++ b/modules/webapp/src/main/elm/Comp/SpaceManage.elm @@ -0,0 +1,118 @@ +module Comp.SpaceManage exposing + ( Model + , Msg + , empty + , init + , update + , view + ) + +import Api +import Api.Model.SpaceDetail exposing (SpaceDetail) +import Api.Model.SpaceItem exposing (SpaceItem) +import Api.Model.SpaceList exposing (SpaceList) +import Api.Model.User exposing (User) +import Api.Model.UserList exposing (UserList) +import Comp.SpaceDetail +import Comp.SpaceTable +import Data.Flags exposing (Flags) +import Html exposing (..) +import Html.Attributes exposing (..) +import Html.Events exposing (onClick, onInput) +import Http + + +type alias Model = + { tableModel : Comp.SpaceTable.Model + , detailModel : Maybe Comp.SpaceDetail.Model + , spaces : List SpaceItem + , users : List User + , query : String + , loading : Bool + } + + +type Msg + = TableMsg Comp.SpaceTable.Msg + | DetailMsg Comp.SpaceDetail.Msg + | UserListResp (Result Http.Error UserList) + | SpaceListResp (Result Http.Error SpaceList) + | SpaceDetailResp (Result Http.Error SpaceDetail) + | SetQuery String + | InitNewSpace + + +empty : Model +empty = + { tableModel = Comp.SpaceTable.init + , detailModel = Nothing + , spaces = [] + , users = [] + , query = "" + , loading = False + } + + +init : Flags -> ( Model, Cmd Msg ) +init flags = + ( empty + , Cmd.batch + [ Api.getUsers flags UserListResp + , Api.getSpaces flags SpaceListResp + ] + ) + + + +--- Update + + +update : Flags -> Msg -> Model -> ( Model, Cmd Msg ) +update flags msg model = + ( model, Cmd.none ) + + + +--- View + + +view : Model -> Html Msg +view 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 InitNewSpace + ] + [ i [ class "plus icon" ] [] + , text "New Space" + ] + ] + ] + ] + , Html.map TableMsg (Comp.SpaceTable.view model.tableModel model.spaces) + , div + [ classList + [ ( "ui dimmer", True ) + , ( "active", model.loading ) + ] + ] + [ div [ class "ui loader" ] [] + ] + ] diff --git a/modules/webapp/src/main/elm/Comp/SpaceTable.elm b/modules/webapp/src/main/elm/Comp/SpaceTable.elm new file mode 100644 index 00000000..6d707c06 --- /dev/null +++ b/modules/webapp/src/main/elm/Comp/SpaceTable.elm @@ -0,0 +1,89 @@ +module Comp.SpaceTable exposing + ( Action(..) + , Model + , Msg + , init + , update + , view + ) + +import Api.Model.SpaceItem exposing (SpaceItem) +import Api.Model.SpaceList exposing (SpaceList) +import Html exposing (..) +import Html.Attributes exposing (..) +import Html.Events exposing (onClick) +import Util.Time + + +type alias Model = + {} + + +type Msg + = EditItem SpaceItem + + +type Action + = NoAction + | EditAction SpaceItem + + +init : Model +init = + {} + + +update : Msg -> Model -> ( Model, Action ) +update msg model = + case msg of + EditItem item -> + ( model, EditAction item ) + + +view : Model -> List SpaceItem -> Html Msg +view _ items = + div [] + [ table [ class "ui very basic center aligned table" ] + [ thead [] + [ th [ class "collapsing" ] [] + , th [] [ text "Name" ] + , th [] [ text "Owner" ] + , th [] [ text "Members" ] + , th [] [ text "Created" ] + ] + , tbody [] + (List.map viewItem items) + ] + ] + + +viewItem : SpaceItem -> 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 [] + [ code [] + [ text item.name + ] + ] + , td [] + [ text item.owner.name + ] + , td [] + [ String.fromInt item.members + |> text + ] + , td [] + [ Util.Time.formatDateShort item.created + |> text + ] + ] diff --git a/modules/webapp/src/main/elm/Data/Icons.elm b/modules/webapp/src/main/elm/Data/Icons.elm index 8d891221..77badc14 100644 --- a/modules/webapp/src/main/elm/Data/Icons.elm +++ b/modules/webapp/src/main/elm/Data/Icons.elm @@ -19,6 +19,8 @@ module Data.Icons exposing , organizationIcon , person , personIcon + , space + , spaceIcon , tag , tagIcon , tags @@ -29,6 +31,16 @@ import Html exposing (Html, i) import Html.Attributes exposing (class) +space : String +space = + "folder outline icon" + + +spaceIcon : String -> Html msg +spaceIcon classes = + i [ class (space ++ " " ++ classes) ] [] + + concerned : String concerned = "crosshairs icon" diff --git a/modules/webapp/src/main/elm/Page/ManageData/Data.elm b/modules/webapp/src/main/elm/Page/ManageData/Data.elm index 35b92d79..8ab230a4 100644 --- a/modules/webapp/src/main/elm/Page/ManageData/Data.elm +++ b/modules/webapp/src/main/elm/Page/ManageData/Data.elm @@ -2,13 +2,15 @@ module Page.ManageData.Data exposing ( Model , Msg(..) , Tab(..) - , emptyModel + , init ) import Comp.EquipmentManage import Comp.OrgManage import Comp.PersonManage +import Comp.SpaceManage import Comp.TagManage +import Data.Flags exposing (Flags) type alias Model = @@ -17,17 +19,21 @@ type alias Model = , equipManageModel : Comp.EquipmentManage.Model , orgManageModel : Comp.OrgManage.Model , personManageModel : Comp.PersonManage.Model + , spaceManageModel : Comp.SpaceManage.Model } -emptyModel : Model -emptyModel = - { currentTab = Nothing - , tagManageModel = Comp.TagManage.emptyModel - , equipManageModel = Comp.EquipmentManage.emptyModel - , orgManageModel = Comp.OrgManage.emptyModel - , personManageModel = Comp.PersonManage.emptyModel - } +init : Flags -> ( Model, Cmd Msg ) +init _ = + ( { currentTab = Nothing + , tagManageModel = Comp.TagManage.emptyModel + , equipManageModel = Comp.EquipmentManage.emptyModel + , orgManageModel = Comp.OrgManage.emptyModel + , personManageModel = Comp.PersonManage.emptyModel + , spaceManageModel = Comp.SpaceManage.empty + } + , Cmd.none + ) type Tab @@ -35,6 +41,7 @@ type Tab | EquipTab | OrgTab | PersonTab + | SpaceTab type Msg @@ -43,3 +50,4 @@ type Msg | EquipManageMsg Comp.EquipmentManage.Msg | OrgManageMsg Comp.OrgManage.Msg | PersonManageMsg Comp.PersonManage.Msg + | SpaceMsg Comp.SpaceManage.Msg diff --git a/modules/webapp/src/main/elm/Page/ManageData/Update.elm b/modules/webapp/src/main/elm/Page/ManageData/Update.elm index a7239ab2..d50f0042 100644 --- a/modules/webapp/src/main/elm/Page/ManageData/Update.elm +++ b/modules/webapp/src/main/elm/Page/ManageData/Update.elm @@ -3,6 +3,7 @@ module Page.ManageData.Update exposing (update) import Comp.EquipmentManage import Comp.OrgManage import Comp.PersonManage +import Comp.SpaceManage import Comp.TagManage import Data.Flags exposing (Flags) import Page.ManageData.Data exposing (..) @@ -29,6 +30,13 @@ update flags msg model = PersonTab -> update flags (PersonManageMsg Comp.PersonManage.LoadPersons) m + SpaceTab -> + let + ( sm, sc ) = + Comp.SpaceManage.init flags + in + ( { m | spaceManageModel = sm }, Cmd.map SpaceMsg sc ) + TagManageMsg m -> let ( m2, c2 ) = @@ -56,3 +64,12 @@ update flags msg model = Comp.PersonManage.update flags m model.personManageModel in ( { model | personManageModel = m2 }, Cmd.map PersonManageMsg c2 ) + + SpaceMsg lm -> + let + ( m2, c2 ) = + Comp.SpaceManage.update flags lm model.spaceManageModel + in + ( { model | spaceManageModel = m2 } + , Cmd.map SpaceMsg c2 + ) diff --git a/modules/webapp/src/main/elm/Page/ManageData/View.elm b/modules/webapp/src/main/elm/Page/ManageData/View.elm index 9d048d2a..ae3fa852 100644 --- a/modules/webapp/src/main/elm/Page/ManageData/View.elm +++ b/modules/webapp/src/main/elm/Page/ManageData/View.elm @@ -3,6 +3,7 @@ module Page.ManageData.View exposing (view) import Comp.EquipmentManage import Comp.OrgManage import Comp.PersonManage +import Comp.SpaceManage import Comp.TagManage import Data.Icons as Icons import Data.UiSettings exposing (UiSettings) @@ -50,6 +51,13 @@ view settings model = [ Icons.personIcon "" , text "Person" ] + , div + [ classActive (model.currentTab == Just SpaceTab) "link icon item" + , onClick (SetTab SpaceTab) + ] + [ Icons.spaceIcon "" + , text "Space" + ] ] ] ] @@ -68,6 +76,9 @@ view settings model = Just PersonTab -> viewPerson settings model + Just SpaceTab -> + viewSpace settings model + Nothing -> [] ) @@ -75,6 +86,22 @@ view settings model = ] +viewSpace : UiSettings -> Model -> List (Html Msg) +viewSpace _ model = + [ h2 + [ class "ui header" + ] + [ Icons.spaceIcon "" + , div + [ class "content" + ] + [ text "Spaces" + ] + ] + , Html.map SpaceMsg (Comp.SpaceManage.view model.spaceManageModel) + ] + + viewTags : Model -> List (Html Msg) viewTags model = [ h2 [ class "ui header" ]