@@ -1,69 +1,255 @@
11module Index exposing (main)
22
3−import Html exposing (Html)
4−import Json.Decode as Decode
53
6−import Index.Dashboard as Dashboard
7−import Index.Project as Project exposing (Project)
4+import Browser
5+import Dict
6+import Html exposing (..)
7+import Html.Attributes exposing (class, href, src, style, title)
8+import Json.Decode as D
9+
10+import Elm.License as License
11+import Elm.Package as Package
12+import Elm.Project as Project
13+import Elm.Version as Version
14+
15+import Index.Icon as Icon
16+import Index.Navigator as Navigator
17+import Index.Skeleton as Skeleton
818
919
1020
1121-- MAIN
1222
1323
24+main : Program D.Value Model Never
1425main =
15− Html.programWithFlags
16− { init = init
26+ Browser.fullscreen
27+ { init = \env -> (D.decodeValue decoder env.flags, Cmd.none)
28+ , update = \_ model -> (model, Cmd.none)
29+ , subscriptions = \_ -> Sub.none
1730 , view = view
18− , update = update
19− , subscriptions = subscriptions
31+ , onNavigation = Nothing
2032 }
2133
2234
2335
36+-- FLAGS
37+
38+
39+type alias Flags =
40+ { root : String
41+ , pwd : List String
42+ , dirs : List String
43+ , files : List File
44+ , readme : Maybe String
45+ , project : Project.Project
46+ , exactDeps : Dict.Dict String Version.Version
47+ }
48+
49+
50+type alias File =
51+ { name : String
52+ , runnable : Bool
53+ }
54+
55+
56+
57+-- DECODER
58+
59+
60+decoder : D.Decoder Flags
61+decoder =
62+ D.map7 Flags
63+ (D.field "root" D.string)
64+ (D.field "pwd" (D.list D.string))
65+ (D.field "dirs" (D.list D.string))
66+ (D.field "files" (D.list fileDecoder))
67+ (D.field "readme" (D.nullable D.string))
68+ (D.field "project" Project.decoder)
69+ (D.field "exactDeps" (D.dict Version.decoder))
70+
71+
72+fileDecoder : D.Decoder File
73+fileDecoder =
74+ D.map2 File
75+ (D.field "name" D.string)
76+ (D.field "runnable" D.bool)
77+
78+
79+
2480-- MODEL
2581
2682
2783type alias Model =
28− Project
84+ Result D.Error Flags
2985
3086
3187
32−-- INIT
88+-- VIEW
3389
3490
35−init : Decode.Value -> (Model, Cmd msg)
36−init flags =
37− case Project.decode flags of
91+view : Model -> Browser.View msg
92+view model =
93+ case model of
3894 Err _ ->
39− Debug.crash "TODO"
95+ { title = "???"
96+ , body =
97+ [ text "Something went wrong!"
98+ ]
99+ }
40100
41− Ok project ->
42− (project, Cmd.none)
101+ Ok { root, pwd, dirs, files, readme, project, exactDeps } ->
102+ { title = String.join "/" ("~" :: pwd)
103+ , body =
104+ [ header [ class "header" ] []
105+ , div [ class "content" ]
106+ [ Navigator.view root pwd
107+ , section [ class "left-column" ]
108+ [ viewFiles dirs files
109+ , viewReadme readme
110+ ]
111+ , section [ class "right-column" ]
112+ [ viewProjectSummary project
113+ , viewDeps exactDeps project
114+ , viewTestDeps exactDeps project
115+ ]
116+ , div [ style "clear" "both" ] []
117+ ]
118+ ]
119+ }
43120
44121
45122
46−-- UPDATE
123+-- VIEW README
47124
48125
49−update : msg -> Model -> (Model, Cmd msg)
50−update _ model =
51− (model, Cmd.none)
126+viewReadme : Maybe String -> Html msg
127+viewReadme readme =
128+ case readme of
129+ Nothing ->
130+ text ""
52131
132+ Just markdown ->
133+ Skeleton.readmeBox markdown
53134
54135
55−-- SUBSCRIPTIONS
56136
137+-- VIEW FILES
57138
58−subscriptions : Model -> Sub msg
59−subscriptions model =
60− Sub.none
61139
140+viewFiles : List String -> List File -> Html msg
141+viewFiles dirs files =
142+ Skeleton.box
143+ { title = "File Navigation"
144+ , items = List.map viewDir dirs ++ List.map viewFile files
145+ , footer = Nothing
146+ }
62147
63148
64−-- VIEW
149+viewDir : String -> List (Html msg)
150+viewDir dir =
151+ [ a [ href dir ] [ Icon.folder, text dir ]
152+ ]
153+
154+
155+viewFile : File -> List (Html msg)
156+viewFile {name} =
157+ [ a [ href name ] [ Icon.lookup name, text name ]
158+ ]
159+
160+
161+
162+-- VIEW PAGE SUMMARY
163+
164+
165+viewProjectSummary : Project.Project -> Html msg
166+viewProjectSummary project =
167+ case project of
168+ Project.Application info ->
169+ Skeleton.box
170+ { title = "Source Directories"
171+ , items = List.map (\dir -> [text dir]) info.dirs
172+ , footer = Nothing
173+ }
174+ -- TODO show estimated bundle size here
175+
176+ Project.Package info ->
177+ Skeleton.box
178+ { title = "Package Info"
179+ , items =
180+ [ [ text ("Name: " ++ Package.toString info.name) ]
181+ , [ text ("Version: " ++ Version.toString info.version) ]
182+ , [ text ("License: " ++ License.toString info.license) ]
183+ ]
184+ , footer = Nothing
185+ }
186+
187+
188+
189+-- VIEW DEPENDENCIES
190+
191+
192+type alias ExactDeps =
193+ Dict.Dict String Version.Version
194+
195+
196+viewDeps : ExactDeps -> Project.Project -> Html msg
197+viewDeps exactDeps project =
198+ let
199+ dependencies =
200+ case project of
201+ Project.Application info ->
202+ List.map (viewDependency exactDeps) info.deps
203+
204+ Project.Package info ->
205+ List.map (viewDependency exactDeps) info.deps
206+ in
207+ Skeleton.box
208+ { title = "Dependencies"
209+ , items = dependencies
210+ , footer = Nothing -- TODO Just ("/_elm/dependencies", "Add more dependencies?")
211+ }
212+
213+
214+viewTestDeps : ExactDeps -> Project.Project -> Html msg
215+viewTestDeps exactDeps project =
216+ let
217+ dependencies =
218+ case project of
219+ Project.Application info ->
220+ List.map (viewDependency exactDeps) info.testDeps
221+
222+ Project.Package info ->
223+ List.map (viewDependency exactDeps) info.testDeps
224+ in
225+ Skeleton.box
226+ { title = "Test Dependencies"
227+ , items = dependencies
228+ , footer = Nothing -- TODO Just ("/_elm/test-dependencies", "Add more test dependencies?")
229+ }
65230
66231
67−view : Model -> Html msg
68−view =
69− Dashboard.view
232+viewDependency : ExactDeps -> (Package.Name, vsn) -> List (Html msg)
233+viewDependency exactDeps (pkg, _) =
234+ case Dict.get (Package.toString pkg) exactDeps of
235+ Nothing ->
236+ [ div [ style "float" "left" ]
237+ [ Icon.package
238+ , text (Package.toString pkg)
239+ ]
240+ , div [ style "float" "right" ] [ text "???" ]
241+ ]
242+
243+ Just version ->
244+ [ div [ style "float" "left" ]
245+ [ Icon.package
246+ , a [ href (toPackageUrl pkg version) ] [ text (Package.toString pkg) ]
247+ ]
248+ , div [ style "float" "right" ] [ text (Version.toString version) ]
249+ ]
250+
251+
252+toPackageUrl : Package.Name -> Version.Version -> String
253+toPackageUrl name version =
254+ "http://package.elm-lang.org/packages/"
255+ ++ Package.toString name ++ "/" ++ Version.toString version