mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-03-28 17:55:06 +00:00
Improve item detail view
- Separate page (permalink) for item details - Use available space and hide search menu - Disable item navigation links if there is nothing to go to - Show notes more prominently and allow to hide them
This commit is contained in:
parent
36a6fdd746
commit
c73cdd82ab
@ -15,6 +15,7 @@ import Http
|
|||||||
import Page exposing (Page(..))
|
import Page exposing (Page(..))
|
||||||
import Page.CollectiveSettings.Data
|
import Page.CollectiveSettings.Data
|
||||||
import Page.Home.Data
|
import Page.Home.Data
|
||||||
|
import Page.ItemDetail.Data
|
||||||
import Page.Login.Data
|
import Page.Login.Data
|
||||||
import Page.ManageData.Data
|
import Page.ManageData.Data
|
||||||
import Page.NewInvite.Data
|
import Page.NewInvite.Data
|
||||||
@ -39,6 +40,7 @@ type alias Model =
|
|||||||
, registerModel : Page.Register.Data.Model
|
, registerModel : Page.Register.Data.Model
|
||||||
, uploadModel : Page.Upload.Data.Model
|
, uploadModel : Page.Upload.Data.Model
|
||||||
, newInviteModel : Page.NewInvite.Data.Model
|
, newInviteModel : Page.NewInvite.Data.Model
|
||||||
|
, itemDetailModel : Page.ItemDetail.Data.Model
|
||||||
, navMenuOpen : Bool
|
, navMenuOpen : Bool
|
||||||
, subs : Sub Msg
|
, subs : Sub Msg
|
||||||
}
|
}
|
||||||
@ -64,6 +66,7 @@ init key url flags =
|
|||||||
, registerModel = Page.Register.Data.emptyModel
|
, registerModel = Page.Register.Data.emptyModel
|
||||||
, uploadModel = Page.Upload.Data.emptyModel
|
, uploadModel = Page.Upload.Data.emptyModel
|
||||||
, newInviteModel = Page.NewInvite.Data.emptyModel
|
, newInviteModel = Page.NewInvite.Data.emptyModel
|
||||||
|
, itemDetailModel = Page.ItemDetail.Data.emptyModel
|
||||||
, navMenuOpen = False
|
, navMenuOpen = False
|
||||||
, subs = Sub.none
|
, subs = Sub.none
|
||||||
}
|
}
|
||||||
@ -82,6 +85,7 @@ type Msg
|
|||||||
| RegisterMsg Page.Register.Data.Msg
|
| RegisterMsg Page.Register.Data.Msg
|
||||||
| UploadMsg Page.Upload.Data.Msg
|
| UploadMsg Page.Upload.Data.Msg
|
||||||
| NewInviteMsg Page.NewInvite.Data.Msg
|
| NewInviteMsg Page.NewInvite.Data.Msg
|
||||||
|
| ItemDetailMsg Page.ItemDetail.Data.Msg
|
||||||
| Logout
|
| Logout
|
||||||
| LogoutResp (Result Http.Error ())
|
| LogoutResp (Result Http.Error ())
|
||||||
| SessionCheckResp (Result Http.Error AuthResult)
|
| SessionCheckResp (Result Http.Error AuthResult)
|
||||||
|
@ -13,6 +13,8 @@ import Page.CollectiveSettings.Data
|
|||||||
import Page.CollectiveSettings.Update
|
import Page.CollectiveSettings.Update
|
||||||
import Page.Home.Data
|
import Page.Home.Data
|
||||||
import Page.Home.Update
|
import Page.Home.Update
|
||||||
|
import Page.ItemDetail.Data
|
||||||
|
import Page.ItemDetail.Update
|
||||||
import Page.Login.Data
|
import Page.Login.Data
|
||||||
import Page.Login.Update
|
import Page.Login.Update
|
||||||
import Page.ManageData.Data
|
import Page.ManageData.Data
|
||||||
@ -71,6 +73,9 @@ updateWithSub msg model =
|
|||||||
NewInviteMsg m ->
|
NewInviteMsg m ->
|
||||||
updateNewInvite m model |> noSub
|
updateNewInvite m model |> noSub
|
||||||
|
|
||||||
|
ItemDetailMsg m ->
|
||||||
|
updateItemDetail m model |> noSub
|
||||||
|
|
||||||
VersionResp (Ok info) ->
|
VersionResp (Ok info) ->
|
||||||
( { model | version = info }, Cmd.none ) |> noSub
|
( { model | version = info }, Cmd.none ) |> noSub
|
||||||
|
|
||||||
@ -170,6 +175,20 @@ updateWithSub msg model =
|
|||||||
( { model | navMenuOpen = not model.navMenuOpen }, Cmd.none, Sub.none )
|
( { model | navMenuOpen = not model.navMenuOpen }, Cmd.none, Sub.none )
|
||||||
|
|
||||||
|
|
||||||
|
updateItemDetail : Page.ItemDetail.Data.Msg -> Model -> ( Model, Cmd Msg )
|
||||||
|
updateItemDetail lmsg model =
|
||||||
|
let
|
||||||
|
inav =
|
||||||
|
Page.Home.Data.itemNav model.itemDetailModel.detail.item.id model.homeModel
|
||||||
|
|
||||||
|
( lm, lc ) =
|
||||||
|
Page.ItemDetail.Update.update model.key model.flags inav.next lmsg model.itemDetailModel
|
||||||
|
in
|
||||||
|
( { model | itemDetailModel = lm }
|
||||||
|
, Cmd.map ItemDetailMsg lc
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
updateNewInvite : Page.NewInvite.Data.Msg -> Model -> ( Model, Cmd Msg )
|
updateNewInvite : Page.NewInvite.Data.Msg -> Model -> ( Model, Cmd Msg )
|
||||||
updateNewInvite lmsg model =
|
updateNewInvite lmsg model =
|
||||||
let
|
let
|
||||||
@ -265,7 +284,7 @@ updateHome : Page.Home.Data.Msg -> Model -> ( Model, Cmd Msg )
|
|||||||
updateHome lmsg model =
|
updateHome lmsg model =
|
||||||
let
|
let
|
||||||
( lm, lc ) =
|
( lm, lc ) =
|
||||||
Page.Home.Update.update model.flags lmsg model.homeModel
|
Page.Home.Update.update model.key model.flags lmsg model.homeModel
|
||||||
in
|
in
|
||||||
( { model | homeModel = lm }
|
( { model | homeModel = lm }
|
||||||
, Cmd.map HomeMsg lc
|
, Cmd.map HomeMsg lc
|
||||||
@ -321,6 +340,9 @@ initPage model page =
|
|||||||
NewInvitePage ->
|
NewInvitePage ->
|
||||||
updateQueue Page.Queue.Data.StopRefresh model
|
updateQueue Page.Queue.Data.StopRefresh model
|
||||||
|
|
||||||
|
ItemDetailPage id ->
|
||||||
|
updateItemDetail (Page.ItemDetail.Data.Init id) model
|
||||||
|
|
||||||
|
|
||||||
noSub : ( Model, Cmd Msg ) -> ( Model, Cmd Msg, Sub Msg )
|
noSub : ( Model, Cmd Msg ) -> ( Model, Cmd Msg, Sub Msg )
|
||||||
noSub ( m, c ) =
|
noSub ( m, c ) =
|
||||||
|
@ -6,7 +6,9 @@ import Html.Attributes exposing (..)
|
|||||||
import Html.Events exposing (onClick)
|
import Html.Events exposing (onClick)
|
||||||
import Page exposing (Page(..))
|
import Page exposing (Page(..))
|
||||||
import Page.CollectiveSettings.View
|
import Page.CollectiveSettings.View
|
||||||
|
import Page.Home.Data
|
||||||
import Page.Home.View
|
import Page.Home.View
|
||||||
|
import Page.ItemDetail.View
|
||||||
import Page.Login.View
|
import Page.Login.View
|
||||||
import Page.ManageData.View
|
import Page.ManageData.View
|
||||||
import Page.NewInvite.View
|
import Page.NewInvite.View
|
||||||
@ -105,11 +107,23 @@ defaultLayout model =
|
|||||||
|
|
||||||
NewInvitePage ->
|
NewInvitePage ->
|
||||||
viewNewInvite model
|
viewNewInvite model
|
||||||
|
|
||||||
|
ItemDetailPage id ->
|
||||||
|
viewItemDetail id model
|
||||||
]
|
]
|
||||||
, footer 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.itemDetailModel)
|
||||||
|
|
||||||
|
|
||||||
viewNewInvite : Model -> Html Msg
|
viewNewInvite : Model -> Html Msg
|
||||||
viewNewInvite model =
|
viewNewInvite model =
|
||||||
Html.map NewInviteMsg (Page.NewInvite.View.view model.flags model.newInviteModel)
|
Html.map NewInviteMsg (Page.NewInvite.View.view model.flags model.newInviteModel)
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
module Comp.ItemDetail exposing
|
module Comp.ItemDetail exposing
|
||||||
( Model
|
( Model
|
||||||
, Msg(..)
|
, Msg(..)
|
||||||
, UserNav(..)
|
|
||||||
, emptyModel
|
, emptyModel
|
||||||
, update
|
, update
|
||||||
, view
|
, view
|
||||||
@ -20,6 +19,7 @@ import Api.Model.OptionalText exposing (OptionalText)
|
|||||||
import Api.Model.ReferenceList exposing (ReferenceList)
|
import Api.Model.ReferenceList exposing (ReferenceList)
|
||||||
import Api.Model.Tag exposing (Tag)
|
import Api.Model.Tag exposing (Tag)
|
||||||
import Api.Model.TagList exposing (TagList)
|
import Api.Model.TagList exposing (TagList)
|
||||||
|
import Browser.Navigation as Nav
|
||||||
import Comp.DatePicker
|
import Comp.DatePicker
|
||||||
import Comp.Dropdown exposing (isDropdownChangeMsg)
|
import Comp.Dropdown exposing (isDropdownChangeMsg)
|
||||||
import Comp.YesNoDimmer
|
import Comp.YesNoDimmer
|
||||||
@ -31,6 +31,7 @@ import Html.Attributes exposing (..)
|
|||||||
import Html.Events exposing (onClick, onInput)
|
import Html.Events exposing (onClick, onInput)
|
||||||
import Http
|
import Http
|
||||||
import Markdown
|
import Markdown
|
||||||
|
import Page exposing (Page(..))
|
||||||
import Util.Maybe
|
import Util.Maybe
|
||||||
import Util.Size
|
import Util.Size
|
||||||
import Util.String
|
import Util.String
|
||||||
@ -49,6 +50,7 @@ type alias Model =
|
|||||||
, concEquipModel : Comp.Dropdown.Model IdName
|
, concEquipModel : Comp.Dropdown.Model IdName
|
||||||
, nameModel : String
|
, nameModel : String
|
||||||
, notesModel : Maybe String
|
, notesModel : Maybe String
|
||||||
|
, notesHidden : Bool
|
||||||
, deleteConfirm : Comp.YesNoDimmer.Model
|
, deleteConfirm : Comp.YesNoDimmer.Model
|
||||||
, itemDatePicker : DatePicker
|
, itemDatePicker : DatePicker
|
||||||
, itemDate : Maybe Int
|
, itemDate : Maybe Int
|
||||||
@ -76,7 +78,11 @@ emptyModel =
|
|||||||
}
|
}
|
||||||
, directionModel =
|
, directionModel =
|
||||||
Comp.Dropdown.makeSingleList
|
Comp.Dropdown.makeSingleList
|
||||||
{ makeOption = \entry -> { value = Data.Direction.toString entry, text = Data.Direction.toString entry }
|
{ makeOption =
|
||||||
|
\entry ->
|
||||||
|
{ value = Data.Direction.toString entry
|
||||||
|
, text = Data.Direction.toString entry
|
||||||
|
}
|
||||||
, options = Data.Direction.all
|
, options = Data.Direction.all
|
||||||
, placeholder = "Choose a direction…"
|
, placeholder = "Choose a direction…"
|
||||||
, selected = Nothing
|
, selected = Nothing
|
||||||
@ -103,6 +109,7 @@ emptyModel =
|
|||||||
}
|
}
|
||||||
, nameModel = ""
|
, nameModel = ""
|
||||||
, notesModel = Nothing
|
, notesModel = Nothing
|
||||||
|
, notesHidden = False
|
||||||
, deleteConfirm = Comp.YesNoDimmer.emptyModel
|
, deleteConfirm = Comp.YesNoDimmer.emptyModel
|
||||||
, itemDatePicker = Comp.DatePicker.emptyModel
|
, itemDatePicker = Comp.DatePicker.emptyModel
|
||||||
, itemDate = Nothing
|
, itemDate = Nothing
|
||||||
@ -112,26 +119,12 @@ emptyModel =
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type UserNav
|
|
||||||
= NavBack
|
|
||||||
| NavPrev
|
|
||||||
| NavNext
|
|
||||||
| NavNone
|
|
||||||
| NavNextOrBack
|
|
||||||
|
|
||||||
|
|
||||||
noNav : ( Model, Cmd Msg ) -> ( Model, Cmd Msg, UserNav )
|
|
||||||
noNav ( model, cmd ) =
|
|
||||||
( model, cmd, NavNone )
|
|
||||||
|
|
||||||
|
|
||||||
type Msg
|
type Msg
|
||||||
= ToggleMenu
|
= ToggleMenu
|
||||||
| ReloadItem
|
| ReloadItem
|
||||||
| Init
|
| Init
|
||||||
| SetItem ItemDetail
|
| SetItem ItemDetail
|
||||||
| SetActiveAttachment Int
|
| SetActiveAttachment Int
|
||||||
| NavClick UserNav
|
|
||||||
| TagDropdownMsg (Comp.Dropdown.Msg Tag)
|
| TagDropdownMsg (Comp.Dropdown.Msg Tag)
|
||||||
| DirDropdownMsg (Comp.Dropdown.Msg Direction)
|
| DirDropdownMsg (Comp.Dropdown.Msg Direction)
|
||||||
| OrgDropdownMsg (Comp.Dropdown.Msg IdName)
|
| OrgDropdownMsg (Comp.Dropdown.Msg IdName)
|
||||||
@ -145,6 +138,7 @@ type Msg
|
|||||||
| SetName String
|
| SetName String
|
||||||
| SaveName
|
| SaveName
|
||||||
| SetNotes String
|
| SetNotes String
|
||||||
|
| ToggleNotes
|
||||||
| SaveNotes
|
| SaveNotes
|
||||||
| ConfirmItem
|
| ConfirmItem
|
||||||
| UnconfirmItem
|
| UnconfirmItem
|
||||||
@ -281,8 +275,8 @@ setDueDate flags model date =
|
|||||||
Api.setItemDueDate flags model.item.id (OptionalDate date) SaveResp
|
Api.setItemDueDate flags model.item.id (OptionalDate date) SaveResp
|
||||||
|
|
||||||
|
|
||||||
update : Flags -> Msg -> Model -> ( Model, Cmd Msg, UserNav )
|
update : Nav.Key -> Flags -> Maybe String -> Msg -> Model -> ( Model, Cmd Msg )
|
||||||
update flags msg model =
|
update key flags next msg model =
|
||||||
case msg of
|
case msg of
|
||||||
Init ->
|
Init ->
|
||||||
let
|
let
|
||||||
@ -295,16 +289,17 @@ update flags msg model =
|
|||||||
, Cmd.map ItemDatePickerMsg dpc
|
, Cmd.map ItemDatePickerMsg dpc
|
||||||
, Cmd.map DueDatePickerMsg dpc
|
, Cmd.map DueDatePickerMsg dpc
|
||||||
]
|
]
|
||||||
, NavNone
|
|
||||||
)
|
)
|
||||||
|
|
||||||
SetItem item ->
|
SetItem item ->
|
||||||
let
|
let
|
||||||
( m1, c1, _ ) =
|
( m1, c1 ) =
|
||||||
update flags (TagDropdownMsg (Comp.Dropdown.SetSelection item.tags)) model
|
update key flags next (TagDropdownMsg (Comp.Dropdown.SetSelection item.tags)) model
|
||||||
|
|
||||||
( m2, c2, _ ) =
|
( m2, c2 ) =
|
||||||
update flags
|
update key
|
||||||
|
flags
|
||||||
|
next
|
||||||
(DirDropdownMsg
|
(DirDropdownMsg
|
||||||
(Comp.Dropdown.SetSelection
|
(Comp.Dropdown.SetSelection
|
||||||
(Data.Direction.fromString item.direction
|
(Data.Direction.fromString item.direction
|
||||||
@ -315,8 +310,10 @@ update flags msg model =
|
|||||||
)
|
)
|
||||||
m1
|
m1
|
||||||
|
|
||||||
( m3, c3, _ ) =
|
( m3, c3 ) =
|
||||||
update flags
|
update key
|
||||||
|
flags
|
||||||
|
next
|
||||||
(OrgDropdownMsg
|
(OrgDropdownMsg
|
||||||
(Comp.Dropdown.SetSelection
|
(Comp.Dropdown.SetSelection
|
||||||
(item.corrOrg
|
(item.corrOrg
|
||||||
@ -327,8 +324,10 @@ update flags msg model =
|
|||||||
)
|
)
|
||||||
m2
|
m2
|
||||||
|
|
||||||
( m4, c4, _ ) =
|
( m4, c4 ) =
|
||||||
update flags
|
update key
|
||||||
|
flags
|
||||||
|
next
|
||||||
(CorrPersonMsg
|
(CorrPersonMsg
|
||||||
(Comp.Dropdown.SetSelection
|
(Comp.Dropdown.SetSelection
|
||||||
(item.corrPerson
|
(item.corrPerson
|
||||||
@ -339,8 +338,10 @@ update flags msg model =
|
|||||||
)
|
)
|
||||||
m3
|
m3
|
||||||
|
|
||||||
( m5, c5, _ ) =
|
( m5, c5 ) =
|
||||||
update flags
|
update key
|
||||||
|
flags
|
||||||
|
next
|
||||||
(ConcPersonMsg
|
(ConcPersonMsg
|
||||||
(Comp.Dropdown.SetSelection
|
(Comp.Dropdown.SetSelection
|
||||||
(item.concPerson
|
(item.concPerson
|
||||||
@ -358,26 +359,28 @@ update flags msg model =
|
|||||||
else
|
else
|
||||||
Cmd.none
|
Cmd.none
|
||||||
in
|
in
|
||||||
( { m5 | item = item, nameModel = item.name, notesModel = item.notes, itemDate = item.itemDate, dueDate = item.dueDate }
|
( { m5
|
||||||
|
| item = item
|
||||||
|
, nameModel = item.name
|
||||||
|
, notesModel = item.notes
|
||||||
|
, itemDate = item.itemDate
|
||||||
|
, dueDate = item.dueDate
|
||||||
|
}
|
||||||
, Cmd.batch [ c1, c2, c3, c4, c5, getOptions flags, proposalCmd ]
|
, Cmd.batch [ c1, c2, c3, c4, c5, getOptions flags, proposalCmd ]
|
||||||
)
|
)
|
||||||
|> noNav
|
|
||||||
|
|
||||||
SetActiveAttachment pos ->
|
SetActiveAttachment pos ->
|
||||||
( { model | visibleAttach = pos }, Cmd.none, NavNone )
|
( { model | visibleAttach = pos }, Cmd.none )
|
||||||
|
|
||||||
NavClick nav ->
|
|
||||||
( model, Cmd.none, nav )
|
|
||||||
|
|
||||||
ToggleMenu ->
|
ToggleMenu ->
|
||||||
( { model | menuOpen = not model.menuOpen }, Cmd.none, NavNone )
|
( { model | menuOpen = not model.menuOpen }, Cmd.none )
|
||||||
|
|
||||||
ReloadItem ->
|
ReloadItem ->
|
||||||
if model.item.id == "" then
|
if model.item.id == "" then
|
||||||
( model, Cmd.none, NavNone )
|
( model, Cmd.none )
|
||||||
|
|
||||||
else
|
else
|
||||||
( model, Api.itemDetail flags model.item.id GetItemResp, NavNone )
|
( model, Api.itemDetail flags model.item.id GetItemResp )
|
||||||
|
|
||||||
TagDropdownMsg m ->
|
TagDropdownMsg m ->
|
||||||
let
|
let
|
||||||
@ -394,7 +397,7 @@ update flags msg model =
|
|||||||
else
|
else
|
||||||
Cmd.none
|
Cmd.none
|
||||||
in
|
in
|
||||||
( newModel, Cmd.batch [ save, Cmd.map TagDropdownMsg c2 ], NavNone )
|
( newModel, Cmd.batch [ save, Cmd.map TagDropdownMsg c2 ] )
|
||||||
|
|
||||||
DirDropdownMsg m ->
|
DirDropdownMsg m ->
|
||||||
let
|
let
|
||||||
@ -411,7 +414,7 @@ update flags msg model =
|
|||||||
else
|
else
|
||||||
Cmd.none
|
Cmd.none
|
||||||
in
|
in
|
||||||
( newModel, Cmd.batch [ save, Cmd.map DirDropdownMsg c2 ] ) |> noNav
|
( newModel, Cmd.batch [ save, Cmd.map DirDropdownMsg c2 ] )
|
||||||
|
|
||||||
OrgDropdownMsg m ->
|
OrgDropdownMsg m ->
|
||||||
let
|
let
|
||||||
@ -431,7 +434,7 @@ update flags msg model =
|
|||||||
else
|
else
|
||||||
Cmd.none
|
Cmd.none
|
||||||
in
|
in
|
||||||
( newModel, Cmd.batch [ save, Cmd.map OrgDropdownMsg c2 ] ) |> noNav
|
( newModel, Cmd.batch [ save, Cmd.map OrgDropdownMsg c2 ] )
|
||||||
|
|
||||||
CorrPersonMsg m ->
|
CorrPersonMsg m ->
|
||||||
let
|
let
|
||||||
@ -451,7 +454,7 @@ update flags msg model =
|
|||||||
else
|
else
|
||||||
Cmd.none
|
Cmd.none
|
||||||
in
|
in
|
||||||
( newModel, Cmd.batch [ save, Cmd.map CorrPersonMsg c2 ] ) |> noNav
|
( newModel, Cmd.batch [ save, Cmd.map CorrPersonMsg c2 ] )
|
||||||
|
|
||||||
ConcPersonMsg m ->
|
ConcPersonMsg m ->
|
||||||
let
|
let
|
||||||
@ -471,7 +474,7 @@ update flags msg model =
|
|||||||
else
|
else
|
||||||
Cmd.none
|
Cmd.none
|
||||||
in
|
in
|
||||||
( newModel, Cmd.batch [ save, Cmd.map ConcPersonMsg c2 ] ) |> noNav
|
( newModel, Cmd.batch [ save, Cmd.map ConcPersonMsg c2 ] )
|
||||||
|
|
||||||
ConcEquipMsg m ->
|
ConcEquipMsg m ->
|
||||||
let
|
let
|
||||||
@ -491,13 +494,13 @@ update flags msg model =
|
|||||||
else
|
else
|
||||||
Cmd.none
|
Cmd.none
|
||||||
in
|
in
|
||||||
( newModel, Cmd.batch [ save, Cmd.map ConcEquipMsg c2 ] ) |> noNav
|
( newModel, Cmd.batch [ save, Cmd.map ConcEquipMsg c2 ] )
|
||||||
|
|
||||||
SetName str ->
|
SetName str ->
|
||||||
( { model | nameModel = str }, Cmd.none ) |> noNav
|
( { model | nameModel = str }, Cmd.none )
|
||||||
|
|
||||||
SaveName ->
|
SaveName ->
|
||||||
( model, setName flags model ) |> noNav
|
( model, setName flags model )
|
||||||
|
|
||||||
SetNotes str ->
|
SetNotes str ->
|
||||||
( { model
|
( { model
|
||||||
@ -510,16 +513,20 @@ update flags msg model =
|
|||||||
}
|
}
|
||||||
, Cmd.none
|
, Cmd.none
|
||||||
)
|
)
|
||||||
|> noNav
|
|
||||||
|
ToggleNotes ->
|
||||||
|
( { model | notesHidden = not model.notesHidden }
|
||||||
|
, Cmd.none
|
||||||
|
)
|
||||||
|
|
||||||
SaveNotes ->
|
SaveNotes ->
|
||||||
( model, setNotes flags model ) |> noNav
|
( model, setNotes flags model )
|
||||||
|
|
||||||
ConfirmItem ->
|
ConfirmItem ->
|
||||||
( model, Api.setConfirmed flags model.item.id SaveResp ) |> noNav
|
( model, Api.setConfirmed flags model.item.id SaveResp )
|
||||||
|
|
||||||
UnconfirmItem ->
|
UnconfirmItem ->
|
||||||
( model, Api.setUnconfirmed flags model.item.id SaveResp ) |> noNav
|
( model, Api.setUnconfirmed flags model.item.id SaveResp )
|
||||||
|
|
||||||
ItemDatePickerMsg m ->
|
ItemDatePickerMsg m ->
|
||||||
let
|
let
|
||||||
@ -532,13 +539,13 @@ update flags msg model =
|
|||||||
newModel =
|
newModel =
|
||||||
{ model | itemDatePicker = dp, itemDate = Just (Comp.DatePicker.midOfDay date) }
|
{ model | itemDatePicker = dp, itemDate = Just (Comp.DatePicker.midOfDay date) }
|
||||||
in
|
in
|
||||||
( newModel, setDate flags newModel newModel.itemDate ) |> noNav
|
( newModel, setDate flags newModel newModel.itemDate )
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
( { model | itemDatePicker = dp }, Cmd.none ) |> noNav
|
( { model | itemDatePicker = dp }, Cmd.none )
|
||||||
|
|
||||||
RemoveDate ->
|
RemoveDate ->
|
||||||
( { model | itemDate = Nothing }, setDate flags model Nothing ) |> noNav
|
( { model | itemDate = Nothing }, setDate flags model Nothing )
|
||||||
|
|
||||||
DueDatePickerMsg m ->
|
DueDatePickerMsg m ->
|
||||||
let
|
let
|
||||||
@ -551,13 +558,13 @@ update flags msg model =
|
|||||||
newModel =
|
newModel =
|
||||||
{ model | dueDatePicker = dp, dueDate = Just (Comp.DatePicker.midOfDay date) }
|
{ model | dueDatePicker = dp, dueDate = Just (Comp.DatePicker.midOfDay date) }
|
||||||
in
|
in
|
||||||
( newModel, setDueDate flags newModel newModel.dueDate ) |> noNav
|
( newModel, setDueDate flags newModel newModel.dueDate )
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
( { model | dueDatePicker = dp }, Cmd.none ) |> noNav
|
( { model | dueDatePicker = dp }, Cmd.none )
|
||||||
|
|
||||||
RemoveDueDate ->
|
RemoveDueDate ->
|
||||||
( { model | dueDate = Nothing }, setDueDate flags model Nothing ) |> noNav
|
( { model | dueDate = Nothing }, setDueDate flags model Nothing )
|
||||||
|
|
||||||
YesNoMsg m ->
|
YesNoMsg m ->
|
||||||
let
|
let
|
||||||
@ -571,67 +578,67 @@ update flags msg model =
|
|||||||
else
|
else
|
||||||
Cmd.none
|
Cmd.none
|
||||||
in
|
in
|
||||||
( { model | deleteConfirm = cm }, cmd ) |> noNav
|
( { model | deleteConfirm = cm }, cmd )
|
||||||
|
|
||||||
RequestDelete ->
|
RequestDelete ->
|
||||||
update flags (YesNoMsg Comp.YesNoDimmer.activate) model
|
update key flags next (YesNoMsg Comp.YesNoDimmer.activate) model
|
||||||
|
|
||||||
SetCorrOrgSuggestion idname ->
|
SetCorrOrgSuggestion idname ->
|
||||||
( model, setCorrOrg flags model (Just idname) ) |> noNav
|
( model, setCorrOrg flags model (Just idname) )
|
||||||
|
|
||||||
SetCorrPersonSuggestion idname ->
|
SetCorrPersonSuggestion idname ->
|
||||||
( model, setCorrPerson flags model (Just idname) ) |> noNav
|
( model, setCorrPerson flags model (Just idname) )
|
||||||
|
|
||||||
SetConcPersonSuggestion idname ->
|
SetConcPersonSuggestion idname ->
|
||||||
( model, setConcPerson flags model (Just idname) ) |> noNav
|
( model, setConcPerson flags model (Just idname) )
|
||||||
|
|
||||||
SetConcEquipSuggestion idname ->
|
SetConcEquipSuggestion idname ->
|
||||||
( model, setConcEquip flags model (Just idname) ) |> noNav
|
( model, setConcEquip flags model (Just idname) )
|
||||||
|
|
||||||
SetItemDateSuggestion date ->
|
SetItemDateSuggestion date ->
|
||||||
( model, setDate flags model (Just date) ) |> noNav
|
( model, setDate flags model (Just date) )
|
||||||
|
|
||||||
SetDueDateSuggestion date ->
|
SetDueDateSuggestion date ->
|
||||||
( model, setDueDate flags model (Just date) ) |> noNav
|
( model, setDueDate flags model (Just date) )
|
||||||
|
|
||||||
GetTagsResp (Ok tags) ->
|
GetTagsResp (Ok tags) ->
|
||||||
let
|
let
|
||||||
tagList =
|
tagList =
|
||||||
Comp.Dropdown.SetOptions tags.items
|
Comp.Dropdown.SetOptions tags.items
|
||||||
|
|
||||||
( m1, c1, _ ) =
|
( m1, c1 ) =
|
||||||
update flags (TagDropdownMsg tagList) model
|
update key flags next (TagDropdownMsg tagList) model
|
||||||
in
|
in
|
||||||
( m1, c1 ) |> noNav
|
( m1, c1 )
|
||||||
|
|
||||||
GetTagsResp (Err _) ->
|
GetTagsResp (Err _) ->
|
||||||
( model, Cmd.none ) |> noNav
|
( model, Cmd.none )
|
||||||
|
|
||||||
GetOrgResp (Ok orgs) ->
|
GetOrgResp (Ok orgs) ->
|
||||||
let
|
let
|
||||||
opts =
|
opts =
|
||||||
Comp.Dropdown.SetOptions orgs.items
|
Comp.Dropdown.SetOptions orgs.items
|
||||||
in
|
in
|
||||||
update flags (OrgDropdownMsg opts) model
|
update key flags next (OrgDropdownMsg opts) model
|
||||||
|
|
||||||
GetOrgResp (Err _) ->
|
GetOrgResp (Err _) ->
|
||||||
( model, Cmd.none ) |> noNav
|
( model, Cmd.none )
|
||||||
|
|
||||||
GetPersonResp (Ok ps) ->
|
GetPersonResp (Ok ps) ->
|
||||||
let
|
let
|
||||||
opts =
|
opts =
|
||||||
Comp.Dropdown.SetOptions ps.items
|
Comp.Dropdown.SetOptions ps.items
|
||||||
|
|
||||||
( m1, c1, _ ) =
|
( m1, c1 ) =
|
||||||
update flags (CorrPersonMsg opts) model
|
update key flags next (CorrPersonMsg opts) model
|
||||||
|
|
||||||
( m2, c2, _ ) =
|
( m2, c2 ) =
|
||||||
update flags (ConcPersonMsg opts) m1
|
update key flags next (ConcPersonMsg opts) m1
|
||||||
in
|
in
|
||||||
( m2, Cmd.batch [ c1, c2 ] ) |> noNav
|
( m2, Cmd.batch [ c1, c2 ] )
|
||||||
|
|
||||||
GetPersonResp (Err _) ->
|
GetPersonResp (Err _) ->
|
||||||
( model, Cmd.none ) |> noNav
|
( model, Cmd.none )
|
||||||
|
|
||||||
GetEquipResp (Ok equips) ->
|
GetEquipResp (Ok equips) ->
|
||||||
let
|
let
|
||||||
@ -641,42 +648,47 @@ update flags msg model =
|
|||||||
equips.items
|
equips.items
|
||||||
)
|
)
|
||||||
in
|
in
|
||||||
update flags (ConcEquipMsg opts) model
|
update key flags next (ConcEquipMsg opts) model
|
||||||
|
|
||||||
GetEquipResp (Err _) ->
|
GetEquipResp (Err _) ->
|
||||||
( model, Cmd.none ) |> noNav
|
( model, Cmd.none )
|
||||||
|
|
||||||
SaveResp (Ok res) ->
|
SaveResp (Ok res) ->
|
||||||
if res.success then
|
if res.success then
|
||||||
( model, Api.itemDetail flags model.item.id GetItemResp ) |> noNav
|
( model, Api.itemDetail flags model.item.id GetItemResp )
|
||||||
|
|
||||||
else
|
else
|
||||||
( model, Cmd.none ) |> noNav
|
( model, Cmd.none )
|
||||||
|
|
||||||
SaveResp (Err _) ->
|
SaveResp (Err _) ->
|
||||||
( model, Cmd.none ) |> noNav
|
( model, Cmd.none )
|
||||||
|
|
||||||
DeleteResp (Ok res) ->
|
DeleteResp (Ok res) ->
|
||||||
if res.success then
|
if res.success then
|
||||||
( model, Cmd.none, NavNextOrBack )
|
case next of
|
||||||
|
Just id ->
|
||||||
|
( model, Page.set key (ItemDetailPage id) )
|
||||||
|
|
||||||
|
Nothing ->
|
||||||
|
( model, Page.set key HomePage )
|
||||||
|
|
||||||
else
|
else
|
||||||
( model, Cmd.none ) |> noNav
|
( model, Cmd.none )
|
||||||
|
|
||||||
DeleteResp (Err _) ->
|
DeleteResp (Err _) ->
|
||||||
( model, Cmd.none ) |> noNav
|
( model, Cmd.none )
|
||||||
|
|
||||||
GetItemResp (Ok item) ->
|
GetItemResp (Ok item) ->
|
||||||
update flags (SetItem item) model
|
update key flags next (SetItem item) model
|
||||||
|
|
||||||
GetItemResp (Err _) ->
|
GetItemResp (Err _) ->
|
||||||
( model, Cmd.none ) |> noNav
|
( model, Cmd.none )
|
||||||
|
|
||||||
GetProposalResp (Ok ip) ->
|
GetProposalResp (Ok ip) ->
|
||||||
( { model | itemProposals = ip }, Cmd.none ) |> noNav
|
( { model | itemProposals = ip }, Cmd.none )
|
||||||
|
|
||||||
GetProposalResp (Err _) ->
|
GetProposalResp (Err _) ->
|
||||||
( model, Cmd.none ) |> noNav
|
( model, Cmd.none )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -692,21 +704,38 @@ actionInputDatePicker =
|
|||||||
{ ds | containerClassList = [ ( "ui action input", True ) ] }
|
{ ds | containerClassList = [ ( "ui action input", True ) ] }
|
||||||
|
|
||||||
|
|
||||||
view : Model -> Html Msg
|
view : { prev : Maybe String, next : Maybe String } -> Model -> Html Msg
|
||||||
view model =
|
view inav model =
|
||||||
div []
|
div []
|
||||||
[ div
|
[ renderItemInfo model
|
||||||
|
, div
|
||||||
[ classList
|
[ classList
|
||||||
[ ( "ui ablue-comp menu", True )
|
[ ( "ui ablue-comp menu", True )
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
[ a [ class "item", href "", onClick (NavClick NavBack) ]
|
[ a [ class "item", Page.href HomePage ]
|
||||||
[ i [ class "arrow left icon" ] []
|
[ i [ class "arrow left icon" ] []
|
||||||
]
|
]
|
||||||
, a [ class "item", href "", onClick (NavClick NavPrev) ]
|
, a
|
||||||
|
[ classList
|
||||||
|
[ ( "item", True )
|
||||||
|
, ( "disabled", inav.prev == Nothing )
|
||||||
|
]
|
||||||
|
, Maybe.map ItemDetailPage inav.prev
|
||||||
|
|> Maybe.map Page.href
|
||||||
|
|> Maybe.withDefault (href "#")
|
||||||
|
]
|
||||||
[ i [ class "caret square left outline icon" ] []
|
[ i [ class "caret square left outline icon" ] []
|
||||||
]
|
]
|
||||||
, a [ class "item", href "", onClick (NavClick NavNext) ]
|
, a
|
||||||
|
[ classList
|
||||||
|
[ ( "item", True )
|
||||||
|
, ( "disabled", inav.next == Nothing )
|
||||||
|
]
|
||||||
|
, Maybe.map ItemDetailPage inav.next
|
||||||
|
|> Maybe.map Page.href
|
||||||
|
|> Maybe.withDefault (href "#")
|
||||||
|
]
|
||||||
[ i [ class "caret square right outline icon" ] []
|
[ i [ class "caret square right outline icon" ] []
|
||||||
]
|
]
|
||||||
, a
|
, a
|
||||||
@ -722,9 +751,10 @@ view model =
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div [ class "ui grid" ]
|
, div [ class "ui grid" ]
|
||||||
[ div
|
[ Html.map YesNoMsg (Comp.YesNoDimmer.view model.deleteConfirm)
|
||||||
|
, div
|
||||||
[ classList
|
[ classList
|
||||||
[ ( "six wide column", True )
|
[ ( "four wide column", True )
|
||||||
, ( "invisible", not model.menuOpen )
|
, ( "invisible", not model.menuOpen )
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -736,17 +766,17 @@ view model =
|
|||||||
)
|
)
|
||||||
, div
|
, div
|
||||||
[ classList
|
[ classList
|
||||||
[ ( "ten", model.menuOpen )
|
[ ( "twelve", model.menuOpen )
|
||||||
, ( "sixteen", not model.menuOpen )
|
, ( "sixteen", not model.menuOpen )
|
||||||
, ( "wide column", True )
|
, ( "wide column", True )
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
<|
|
<|
|
||||||
List.concat
|
List.concat
|
||||||
[ [ renderItemInfo model ]
|
[ renderNotes model
|
||||||
, [ renderAttachmentsTabMenu model ]
|
, [ renderAttachmentsTabMenu model
|
||||||
|
]
|
||||||
, renderAttachmentsTabBody model
|
, renderAttachmentsTabBody model
|
||||||
, renderNotes model
|
|
||||||
, renderIdInfo model
|
, renderIdInfo model
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -776,11 +806,31 @@ renderNotes model =
|
|||||||
[]
|
[]
|
||||||
|
|
||||||
Just str ->
|
Just str ->
|
||||||
[ h3 [ class "ui header" ]
|
if model.notesHidden then
|
||||||
[ text "Notes"
|
[ div [ class "ui segment" ]
|
||||||
|
[ a
|
||||||
|
[ class "ui top left attached label"
|
||||||
|
, onClick ToggleNotes
|
||||||
|
, href "#"
|
||||||
|
]
|
||||||
|
[ i [ class "eye icon" ] []
|
||||||
|
, text "Show notes…"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
else
|
||||||
|
[ div [ class "ui segment" ]
|
||||||
|
[ Markdown.toHtml [ class "item-notes" ] str
|
||||||
|
, a
|
||||||
|
[ class "ui right corner label"
|
||||||
|
, onClick ToggleNotes
|
||||||
|
, href "#"
|
||||||
|
]
|
||||||
|
[ i [ class "delete icon" ] []
|
||||||
|
]
|
||||||
|
]
|
||||||
]
|
]
|
||||||
, Markdown.toHtml [ class "item-notes" ] str
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
renderAttachmentsTabMenu : Model -> Html Msg
|
renderAttachmentsTabMenu : Model -> Html Msg
|
||||||
@ -829,12 +879,6 @@ renderAttachmentsTabBody model =
|
|||||||
renderItemInfo : Model -> Html Msg
|
renderItemInfo : Model -> Html Msg
|
||||||
renderItemInfo model =
|
renderItemInfo model =
|
||||||
let
|
let
|
||||||
name =
|
|
||||||
div [ class "item" ]
|
|
||||||
[ i [ class (Data.Direction.iconFromString model.item.direction) ] []
|
|
||||||
, text model.item.name
|
|
||||||
]
|
|
||||||
|
|
||||||
date =
|
date =
|
||||||
div [ class "item" ]
|
div [ class "item" ]
|
||||||
[ Maybe.withDefault model.item.created model.item.itemDate
|
[ Maybe.withDefault model.item.created model.item.itemDate
|
||||||
@ -876,7 +920,7 @@ renderItemInfo model =
|
|||||||
]
|
]
|
||||||
in
|
in
|
||||||
div [ class "ui fluid container" ]
|
div [ class "ui fluid container" ]
|
||||||
([ h2 [ class "ui header" ]
|
(h2 [ class "ui header" ]
|
||||||
[ i [ class (Data.Direction.iconFromString model.item.direction) ] []
|
[ i [ class (Data.Direction.iconFromString model.item.direction) ] []
|
||||||
, div [ class "content" ]
|
, div [ class "content" ]
|
||||||
[ text model.item.name
|
[ text model.item.name
|
||||||
@ -905,8 +949,7 @@ renderItemInfo model =
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
:: renderTags model
|
||||||
++ renderTags model
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -973,8 +1016,7 @@ renderEditButtons model =
|
|||||||
renderEditForm : Model -> Html Msg
|
renderEditForm : Model -> Html Msg
|
||||||
renderEditForm model =
|
renderEditForm model =
|
||||||
div [ class "ui attached segment" ]
|
div [ class "ui attached segment" ]
|
||||||
[ Html.map YesNoMsg (Comp.YesNoDimmer.view model.deleteConfirm)
|
[ div [ class "ui form" ]
|
||||||
, div [ class "ui form" ]
|
|
||||||
[ div [ class "field" ]
|
[ div [ class "field" ]
|
||||||
[ label []
|
[ label []
|
||||||
[ i [ class "tags icon" ] []
|
[ i [ class "tags icon" ] []
|
||||||
@ -986,7 +1028,12 @@ renderEditForm model =
|
|||||||
[ label [] [ text "Name" ]
|
[ label [] [ text "Name" ]
|
||||||
, div [ class "ui action input" ]
|
, div [ class "ui action input" ]
|
||||||
[ input [ type_ "text", value model.nameModel, onInput SetName ] []
|
[ input [ type_ "text", value model.nameModel, onInput SetName ] []
|
||||||
, button [ class "ui icon button", onClick SaveName ] [ i [ class "save outline icon" ] [] ]
|
, button
|
||||||
|
[ class "ui icon button"
|
||||||
|
, onClick SaveName
|
||||||
|
]
|
||||||
|
[ i [ class "save outline icon" ] []
|
||||||
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div [ class "field" ]
|
, div [ class "field" ]
|
||||||
@ -996,7 +1043,12 @@ renderEditForm model =
|
|||||||
, div [ class " field" ]
|
, div [ class " field" ]
|
||||||
[ label [] [ text "Date" ]
|
[ label [] [ text "Date" ]
|
||||||
, div [ class "ui action input" ]
|
, div [ class "ui action input" ]
|
||||||
[ Html.map ItemDatePickerMsg (Comp.DatePicker.viewTime model.itemDate actionInputDatePicker model.itemDatePicker)
|
[ Html.map ItemDatePickerMsg
|
||||||
|
(Comp.DatePicker.viewTime
|
||||||
|
model.itemDate
|
||||||
|
actionInputDatePicker
|
||||||
|
model.itemDatePicker
|
||||||
|
)
|
||||||
, a [ class "ui icon button", href "", onClick RemoveDate ]
|
, a [ class "ui icon button", href "", onClick RemoveDate ]
|
||||||
[ i [ class "trash alternate outline icon" ] []
|
[ i [ class "trash alternate outline icon" ] []
|
||||||
]
|
]
|
||||||
@ -1006,7 +1058,12 @@ renderEditForm model =
|
|||||||
, div [ class " field" ]
|
, div [ class " field" ]
|
||||||
[ label [] [ text "Due Date" ]
|
[ label [] [ text "Due Date" ]
|
||||||
, div [ class "ui action input" ]
|
, div [ class "ui action input" ]
|
||||||
[ Html.map DueDatePickerMsg (Comp.DatePicker.viewTime model.dueDate actionInputDatePicker model.dueDatePicker)
|
[ Html.map DueDatePickerMsg
|
||||||
|
(Comp.DatePicker.viewTime
|
||||||
|
model.dueDate
|
||||||
|
actionInputDatePicker
|
||||||
|
model.dueDatePicker
|
||||||
|
)
|
||||||
, a [ class "ui icon button", href "", onClick RemoveDueDate ]
|
, a [ class "ui icon button", href "", onClick RemoveDueDate ]
|
||||||
[ i [ class "trash alternate outline icon" ] [] ]
|
[ i [ class "trash alternate outline icon" ] [] ]
|
||||||
]
|
]
|
||||||
|
@ -10,6 +10,7 @@ module Page exposing
|
|||||||
, pageFromString
|
, pageFromString
|
||||||
, pageName
|
, pageName
|
||||||
, pageToString
|
, pageToString
|
||||||
|
, set
|
||||||
, uploadId
|
, uploadId
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -31,6 +32,7 @@ type Page
|
|||||||
| RegisterPage
|
| RegisterPage
|
||||||
| UploadPage (Maybe String)
|
| UploadPage (Maybe String)
|
||||||
| NewInvitePage
|
| NewInvitePage
|
||||||
|
| ItemDetailPage String
|
||||||
|
|
||||||
|
|
||||||
isSecured : Page -> Bool
|
isSecured : Page -> Bool
|
||||||
@ -63,6 +65,9 @@ isSecured page =
|
|||||||
UploadPage arg ->
|
UploadPage arg ->
|
||||||
Util.Maybe.isEmpty arg
|
Util.Maybe.isEmpty arg
|
||||||
|
|
||||||
|
ItemDetailPage _ ->
|
||||||
|
True
|
||||||
|
|
||||||
|
|
||||||
isOpen : Page -> Bool
|
isOpen : Page -> Bool
|
||||||
isOpen page =
|
isOpen page =
|
||||||
@ -114,6 +119,9 @@ pageName page =
|
|||||||
Nothing ->
|
Nothing ->
|
||||||
"Upload"
|
"Upload"
|
||||||
|
|
||||||
|
ItemDetailPage _ ->
|
||||||
|
"Item"
|
||||||
|
|
||||||
|
|
||||||
loginPageReferrer : Page -> Maybe Page
|
loginPageReferrer : Page -> Maybe Page
|
||||||
loginPageReferrer page =
|
loginPageReferrer page =
|
||||||
@ -169,6 +177,9 @@ pageToString page =
|
|||||||
NewInvitePage ->
|
NewInvitePage ->
|
||||||
"/app/newinvite"
|
"/app/newinvite"
|
||||||
|
|
||||||
|
ItemDetailPage id ->
|
||||||
|
"/app/item/" ++ id
|
||||||
|
|
||||||
|
|
||||||
pageFromString : String -> Maybe Page
|
pageFromString : String -> Maybe Page
|
||||||
pageFromString str =
|
pageFromString str =
|
||||||
@ -191,6 +202,11 @@ href page =
|
|||||||
Attr.href (pageToString page)
|
Attr.href (pageToString page)
|
||||||
|
|
||||||
|
|
||||||
|
set : Nav.Key -> Page -> Cmd msg
|
||||||
|
set key page =
|
||||||
|
Nav.pushUrl key (pageToString page)
|
||||||
|
|
||||||
|
|
||||||
goto : Page -> Cmd msg
|
goto : Page -> Cmd msg
|
||||||
goto page =
|
goto page =
|
||||||
Nav.load (pageToString page)
|
Nav.load (pageToString page)
|
||||||
@ -215,6 +231,7 @@ parser =
|
|||||||
, Parser.map (\s -> UploadPage (Just s)) (s pathPrefix </> s "upload" </> string)
|
, Parser.map (\s -> UploadPage (Just s)) (s pathPrefix </> s "upload" </> string)
|
||||||
, Parser.map (UploadPage Nothing) (s pathPrefix </> s "upload")
|
, Parser.map (UploadPage Nothing) (s pathPrefix </> s "upload")
|
||||||
, Parser.map NewInvitePage (s pathPrefix </> s "newinvite")
|
, Parser.map NewInvitePage (s pathPrefix </> s "newinvite")
|
||||||
|
, Parser.map ItemDetailPage (s pathPrefix </> s "item" </> string)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,11 +3,11 @@ module Page.Home.Data exposing
|
|||||||
, Msg(..)
|
, Msg(..)
|
||||||
, ViewMode(..)
|
, ViewMode(..)
|
||||||
, emptyModel
|
, emptyModel
|
||||||
|
, itemNav
|
||||||
)
|
)
|
||||||
|
|
||||||
import Api.Model.ItemDetail exposing (ItemDetail)
|
import Api.Model.ItemDetail exposing (ItemDetail)
|
||||||
import Api.Model.ItemLightList exposing (ItemLightList)
|
import Api.Model.ItemLightList exposing (ItemLightList)
|
||||||
import Comp.ItemDetail
|
|
||||||
import Comp.ItemList
|
import Comp.ItemList
|
||||||
import Comp.SearchMenu
|
import Comp.SearchMenu
|
||||||
import Http
|
import Http
|
||||||
@ -17,7 +17,6 @@ type alias Model =
|
|||||||
{ searchMenuModel : Comp.SearchMenu.Model
|
{ searchMenuModel : Comp.SearchMenu.Model
|
||||||
, itemListModel : Comp.ItemList.Model
|
, itemListModel : Comp.ItemList.Model
|
||||||
, searchInProgress : Bool
|
, searchInProgress : Bool
|
||||||
, itemDetailModel : Comp.ItemDetail.Model
|
|
||||||
, viewMode : ViewMode
|
, viewMode : ViewMode
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,7 +25,6 @@ emptyModel : Model
|
|||||||
emptyModel =
|
emptyModel =
|
||||||
{ searchMenuModel = Comp.SearchMenu.emptyModel
|
{ searchMenuModel = Comp.SearchMenu.emptyModel
|
||||||
, itemListModel = Comp.ItemList.emptyModel
|
, itemListModel = Comp.ItemList.emptyModel
|
||||||
, itemDetailModel = Comp.ItemDetail.emptyModel
|
|
||||||
, searchInProgress = False
|
, searchInProgress = False
|
||||||
, viewMode = Listing
|
, viewMode = Listing
|
||||||
}
|
}
|
||||||
@ -38,10 +36,22 @@ type Msg
|
|||||||
| ItemListMsg Comp.ItemList.Msg
|
| ItemListMsg Comp.ItemList.Msg
|
||||||
| ItemSearchResp (Result Http.Error ItemLightList)
|
| ItemSearchResp (Result Http.Error ItemLightList)
|
||||||
| DoSearch
|
| DoSearch
|
||||||
| ItemDetailMsg Comp.ItemDetail.Msg
|
|
||||||
| ItemDetailResp (Result Http.Error ItemDetail)
|
|
||||||
|
|
||||||
|
|
||||||
type ViewMode
|
type ViewMode
|
||||||
= Listing
|
= Listing
|
||||||
| Detail
|
| Detail
|
||||||
|
|
||||||
|
|
||||||
|
itemNav : String -> Model -> { prev : Maybe String, next : Maybe String }
|
||||||
|
itemNav id model =
|
||||||
|
let
|
||||||
|
prev =
|
||||||
|
Comp.ItemList.prevItem model.itemListModel id
|
||||||
|
|
||||||
|
next =
|
||||||
|
Comp.ItemList.nextItem model.itemListModel id
|
||||||
|
in
|
||||||
|
{ prev = Maybe.map .id prev
|
||||||
|
, next = Maybe.map .id next
|
||||||
|
}
|
||||||
|
@ -1,21 +1,22 @@
|
|||||||
module Page.Home.Update exposing (update)
|
module Page.Home.Update exposing (update)
|
||||||
|
|
||||||
import Api
|
import Api
|
||||||
|
import Browser.Navigation as Nav
|
||||||
import Comp.ItemDetail
|
import Comp.ItemDetail
|
||||||
import Comp.ItemList
|
import Comp.ItemList
|
||||||
import Comp.SearchMenu
|
import Comp.SearchMenu
|
||||||
import Data.Flags exposing (Flags)
|
import Data.Flags exposing (Flags)
|
||||||
|
import Page exposing (Page(..))
|
||||||
import Page.Home.Data exposing (..)
|
import Page.Home.Data exposing (..)
|
||||||
import Util.Update
|
import Util.Update
|
||||||
|
|
||||||
|
|
||||||
update : Flags -> Msg -> Model -> ( Model, Cmd Msg )
|
update : Nav.Key -> Flags -> Msg -> Model -> ( Model, Cmd Msg )
|
||||||
update flags msg model =
|
update key flags msg model =
|
||||||
case msg of
|
case msg of
|
||||||
Init ->
|
Init ->
|
||||||
Util.Update.andThen1
|
Util.Update.andThen1
|
||||||
[ update flags (SearchMenuMsg Comp.SearchMenu.Init)
|
[ update key flags (SearchMenuMsg Comp.SearchMenu.Init)
|
||||||
, update flags (ItemDetailMsg Comp.ItemDetail.Init)
|
|
||||||
, doSearch flags
|
, doSearch flags
|
||||||
]
|
]
|
||||||
model
|
model
|
||||||
@ -45,7 +46,7 @@ update flags msg model =
|
|||||||
cmd =
|
cmd =
|
||||||
case mitem of
|
case mitem of
|
||||||
Just item ->
|
Just item ->
|
||||||
Api.itemDetail flags item.id ItemDetailResp
|
Page.set key (ItemDetailPage item.id)
|
||||||
|
|
||||||
Nothing ->
|
Nothing ->
|
||||||
Cmd.none
|
Cmd.none
|
||||||
@ -57,7 +58,7 @@ update flags msg model =
|
|||||||
m =
|
m =
|
||||||
{ model | searchInProgress = False, viewMode = Listing }
|
{ model | searchInProgress = False, viewMode = Listing }
|
||||||
in
|
in
|
||||||
update flags (ItemListMsg (Comp.ItemList.SetResults list)) m
|
update key flags (ItemListMsg (Comp.ItemList.SetResults list)) m
|
||||||
|
|
||||||
ItemSearchResp (Err _) ->
|
ItemSearchResp (Err _) ->
|
||||||
( { model | searchInProgress = False }, Cmd.none )
|
( { model | searchInProgress = False }, Cmd.none )
|
||||||
@ -65,58 +66,6 @@ update flags msg model =
|
|||||||
DoSearch ->
|
DoSearch ->
|
||||||
doSearch flags model
|
doSearch flags model
|
||||||
|
|
||||||
ItemDetailMsg m ->
|
|
||||||
let
|
|
||||||
( m2, c2, nav ) =
|
|
||||||
Comp.ItemDetail.update flags m model.itemDetailModel
|
|
||||||
|
|
||||||
newModel =
|
|
||||||
{ model | itemDetailModel = m2 }
|
|
||||||
|
|
||||||
newCmd =
|
|
||||||
Cmd.map ItemDetailMsg c2
|
|
||||||
in
|
|
||||||
case nav of
|
|
||||||
Comp.ItemDetail.NavBack ->
|
|
||||||
doSearch flags newModel
|
|
||||||
|
|
||||||
Comp.ItemDetail.NavPrev ->
|
|
||||||
case Comp.ItemList.prevItem model.itemListModel m2.item.id of
|
|
||||||
Just n ->
|
|
||||||
( newModel, Cmd.batch [ newCmd, Api.itemDetail flags n.id ItemDetailResp ] )
|
|
||||||
|
|
||||||
Nothing ->
|
|
||||||
( newModel, newCmd )
|
|
||||||
|
|
||||||
Comp.ItemDetail.NavNext ->
|
|
||||||
case Comp.ItemList.nextItem model.itemListModel m2.item.id of
|
|
||||||
Just n ->
|
|
||||||
( newModel, Cmd.batch [ newCmd, Api.itemDetail flags n.id ItemDetailResp ] )
|
|
||||||
|
|
||||||
Nothing ->
|
|
||||||
( newModel, newCmd )
|
|
||||||
|
|
||||||
Comp.ItemDetail.NavNextOrBack ->
|
|
||||||
case Comp.ItemList.nextItem model.itemListModel m2.item.id of
|
|
||||||
Just n ->
|
|
||||||
( newModel, Cmd.batch [ newCmd, Api.itemDetail flags n.id ItemDetailResp ] )
|
|
||||||
|
|
||||||
Nothing ->
|
|
||||||
doSearch flags newModel
|
|
||||||
|
|
||||||
Comp.ItemDetail.NavNone ->
|
|
||||||
( newModel, newCmd )
|
|
||||||
|
|
||||||
ItemDetailResp (Ok item) ->
|
|
||||||
let
|
|
||||||
m =
|
|
||||||
{ model | viewMode = Detail }
|
|
||||||
in
|
|
||||||
update flags (ItemDetailMsg (Comp.ItemDetail.SetItem item)) m
|
|
||||||
|
|
||||||
ItemDetailResp (Err _) ->
|
|
||||||
( model, Cmd.none )
|
|
||||||
|
|
||||||
|
|
||||||
doSearch : Flags -> Model -> ( Model, Cmd Msg )
|
doSearch : Flags -> Model -> ( Model, Cmd Msg )
|
||||||
doSearch flags model =
|
doSearch flags model =
|
||||||
|
@ -42,7 +42,7 @@ view model =
|
|||||||
Html.map ItemListMsg (Comp.ItemList.view model.itemListModel)
|
Html.map ItemListMsg (Comp.ItemList.view model.itemListModel)
|
||||||
|
|
||||||
Detail ->
|
Detail ->
|
||||||
Html.map ItemDetailMsg (Comp.ItemDetail.view model.itemDetailModel)
|
div [] []
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
22
modules/webapp/src/main/elm/Page/ItemDetail/Data.elm
Normal file
22
modules/webapp/src/main/elm/Page/ItemDetail/Data.elm
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
module Page.ItemDetail.Data exposing (Model, Msg(..), emptyModel)
|
||||||
|
|
||||||
|
import Api.Model.ItemDetail exposing (ItemDetail)
|
||||||
|
import Comp.ItemDetail
|
||||||
|
import Http
|
||||||
|
|
||||||
|
|
||||||
|
type alias Model =
|
||||||
|
{ detail : Comp.ItemDetail.Model
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
emptyModel : Model
|
||||||
|
emptyModel =
|
||||||
|
{ detail = Comp.ItemDetail.emptyModel
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type Msg
|
||||||
|
= Init String
|
||||||
|
| ItemDetailMsg Comp.ItemDetail.Msg
|
||||||
|
| ItemResp (Result Http.Error ItemDetail)
|
39
modules/webapp/src/main/elm/Page/ItemDetail/Update.elm
Normal file
39
modules/webapp/src/main/elm/Page/ItemDetail/Update.elm
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
module Page.ItemDetail.Update exposing (update)
|
||||||
|
|
||||||
|
import Api
|
||||||
|
import Browser.Navigation as Nav
|
||||||
|
import Comp.ItemDetail
|
||||||
|
import Data.Flags exposing (Flags)
|
||||||
|
import Page.ItemDetail.Data exposing (Model, Msg(..))
|
||||||
|
|
||||||
|
|
||||||
|
update : Nav.Key -> Flags -> Maybe String -> Msg -> Model -> ( Model, Cmd Msg )
|
||||||
|
update key flags next msg model =
|
||||||
|
case msg of
|
||||||
|
Init id ->
|
||||||
|
let
|
||||||
|
( lm, lc ) =
|
||||||
|
Comp.ItemDetail.update key flags next Comp.ItemDetail.Init model.detail
|
||||||
|
in
|
||||||
|
( { model | detail = lm }
|
||||||
|
, Cmd.batch [ Api.itemDetail flags id ItemResp, Cmd.map ItemDetailMsg lc ]
|
||||||
|
)
|
||||||
|
|
||||||
|
ItemDetailMsg lmsg ->
|
||||||
|
let
|
||||||
|
( lm, lc ) =
|
||||||
|
Comp.ItemDetail.update key flags next lmsg model.detail
|
||||||
|
in
|
||||||
|
( { model | detail = lm }
|
||||||
|
, Cmd.map ItemDetailMsg lc
|
||||||
|
)
|
||||||
|
|
||||||
|
ItemResp (Ok item) ->
|
||||||
|
let
|
||||||
|
lmsg =
|
||||||
|
Comp.ItemDetail.SetItem item
|
||||||
|
in
|
||||||
|
update key flags next (ItemDetailMsg lmsg) model
|
||||||
|
|
||||||
|
ItemResp (Err err) ->
|
||||||
|
( model, Cmd.none )
|
19
modules/webapp/src/main/elm/Page/ItemDetail/View.elm
Normal file
19
modules/webapp/src/main/elm/Page/ItemDetail/View.elm
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
module Page.ItemDetail.View exposing (view)
|
||||||
|
|
||||||
|
import Comp.ItemDetail
|
||||||
|
import Html exposing (..)
|
||||||
|
import Html.Attributes exposing (..)
|
||||||
|
import Page.ItemDetail.Data exposing (Model, Msg(..))
|
||||||
|
|
||||||
|
|
||||||
|
type alias ItemNav =
|
||||||
|
{ prev : Maybe String
|
||||||
|
, next : Maybe String
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
view : ItemNav -> Model -> Html Msg
|
||||||
|
view inav model =
|
||||||
|
div [ class "ui fluid container item-detail-page" ]
|
||||||
|
[ Html.map ItemDetailMsg (Comp.ItemDetail.view inav model.detail)
|
||||||
|
]
|
@ -59,6 +59,12 @@
|
|||||||
background: aliceblue;
|
background: aliceblue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.default-layout .ui.fluid.container.item-detail-page {
|
||||||
|
padding-top: 1em;
|
||||||
|
padding-left: 1em;
|
||||||
|
padding-right: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
.ui.search.dropdown.open {
|
.ui.search.dropdown.open {
|
||||||
z-index: 20;
|
z-index: 20;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user