@@ -0,0 +1,256 @@
1+module Index.Dashboard exposing
2+ ( view
3+ )
4+
5+
6+import Html exposing (..)
7+import Html.Attributes exposing (class, href, style, title)
8+
9+import Elm.Config as Config exposing (Config)
10+import Elm.License as License
11+import Elm.Repo as Repo exposing (Repo)
12+import Elm.Version as Version exposing (Version)
13+import Index.Icon as Icon
14+import Index.Navigator as Navigator exposing ((</>))
15+import Index.Project as Project exposing (Project, File(..))
16+import Index.Skeleton as Skeleton
17+
18+
19+
20+-- MODEL
21+
22+
23+type alias Model =
24+ { path : String
25+ , status : ProjectStatus
26+ , directory : Status Directory
27+ }
28+
29+
30+type ProjectStatus
31+ = ProjectIsNew
32+ | ProjectIsInvalid
33+ | ProjectIsValid
34+ { root : String
35+ , project : Project.Project
36+ , exactDeps : List (Package.Name, Version.Version)
37+ }
38+
39+
40+type DirectoryStatus
41+ = NotFound
42+ | Waiting
43+ | Found Directory
44+
45+
46+
47+-- DIRECTORY
48+
49+
50+type alias Directory =
51+ { dirs : List String
52+ , files : List File
53+ , readme : Maybe String
54+ }
55+
56+
57+type alias File =
58+ { name : String
59+ , runnable : Bool
60+ }
61+
62+
63+
64+-- DECODER
65+
66+
67+decoder : D.Decoder Directory
68+decoder =
69+ D.map4 Directory
70+ (D.field "path" (D.list D.string))
71+ (D.field "dirs" (D.list D.string))
72+ (D.field "files" (D.list fileDecoder))
73+ (D.field "readme" (D.nullable D.string))
74+
75+
76+fileDecoder : D.Decoder File
77+fileDecoder =
78+ D.map2 File
79+ (D.field "name" D.string)
80+ (D.field "runnable" D.bool)
81+
82+
83+
84+-- NOT FOUND
85+
86+
87+notFound : Html msg
88+notFound =
89+ div [ class "not-found" ]
90+ [ div [ style "font-size" "12em" ] [ text "404" ]
91+ , div [ style "font-size" "3em" ] [ text "Page not found" ]
92+ ]
93+
94+
95+
96+-- WAITING
97+
98+
99+waiting : Html msg
100+waiting =
101+ div [ class "waiting" ]
102+ [ img [ src "/_elm/waiting.gif" ] []
103+ ]
104+
105+
106+
107+-- VIEW DIRECTORY
108+
109+
110+viewDirectory : Project -> Directory -> Html msg
111+viewDirectory project directory =
112+ Skeleton.view
113+ [ Navigator.view pwd
114+ , section [ class "left-column" ]
115+ [ viewFiles directory.dirs directory.files
116+ , viewReadme directory.readme
117+ ]
118+ , section [ class "right-column" ]
119+ [ viewProjectSummary project
120+ , viewDeps project
121+ , viewTestDeps project
122+ ]
123+ , div [ style "clear" "both" ] []
124+ ]
125+
126+
127+
128+-- VIEW README
129+
130+
131+viewReadme : Maybe String -> Html msg
132+viewReadme readme =
133+ case readme of
134+ Nothing ->
135+ text ""
136+
137+ Just markdown ->
138+ Skeleton.readmeBox markdown
139+
140+
141+
142+-- VIEW FILES
143+
144+
145+viewFiles : List String -> List File -> Html msg
146+viewFiles dirs files =
147+ Skeleton.box
148+ { title = "File Navigation"
149+ , items = List.map viewDir dirs ++ List.map viewFile files
150+ , footer = Nothing
151+ }
152+
153+
154+viewDir : String -> List (Html msg)
155+viewDir dir =
156+ [ a [ href dir ] [ Icon.folder, text dir ]
157+ ]
158+
159+
160+viewFile : File -> List (Html msg)
161+viewFile {name} =
162+ [ a [ href name ] [ Icon.lookup name, text name ]
163+ ]
164+
165+
166+
167+-- VIEW PAGE SUMMARY
168+
169+
170+viewProjectSummary : Project.Project -> Html msg
171+viewProjectSummary project =
172+ case project of
173+ Project.Browser info ->
174+ Skeleton.box
175+ { title = "Source Directories"
176+ , items = List.map (\dir -> [text dir]) info.dirs
177+ , footer = Nothing
178+ }
179+ -- TODO show estimated bundle size here
180+
181+ Project.Package info ->
182+ Skeleton.box
183+ { title = "Package Info"
184+ , items =
185+ [ [ text ("Name: " ++ info.name) ]
186+ , [ text ("Version: " ++ Version.toString info.version) ]
187+ , [ text ("License: " ++ License.toString info.license) ]
188+ ]
189+ , footer = Nothing
190+ }
191+
192+
193+
194+-- VIEW DEPENDENCIES
195+
196+
197+viewDeps : ExactDeps -> Project.Project -> Html msg
198+viewDeps exactDeps project =
199+ let
200+ dependencies =
201+ case project of
202+ Project.Browser info ->
203+ List.map (viewDependency exactDeps) info.deps
204+
205+ Project.Package info ->
206+ List.map (viewDependency exactDeps) info.deps
207+ in
208+ Skeleton.box
209+ { title = "Dependencies"
210+ , items = dependencies
211+ , footer = Nothing -- TODO Just ("/_elm/dependencies", "Add more dependencies?")
212+ }
213+
214+
215+viewTestDeps : ExactDeps -> Project.Project -> Html msg
216+viewTestDeps exactDeps project =
217+ let
218+ dependencies =
219+ case project of
220+ Project.Browser info ->
221+ List.map (viewDependency exactDeps) info.testDeps
222+
223+ Project.Package info ->
224+ List.map (viewDependency exactDeps) info.testDeps
225+ in
226+ Skeleton.box
227+ { title = "Test Dependencies"
228+ , items = dependencies
229+ , footer = Nothing -- TODO Just ("/_elm/test-dependencies", "Add more test dependencies?")
230+ }
231+
232+
233+viewDependency : ExactDeps -> (Package.Name, vsn) -> List (Html msg)
234+viewDependency exactDeps (pkg, _) =
235+ case Dict.get (Package.toString pkg) exactDeps of
236+ Nothing ->
237+ [ div [ style "float" "left" ]
238+ [ Icon.package
239+ , text (Package.toString pkg)
240+ ]
241+ , div [ style "float" "right" ] [ text "???" ]
242+ ]
243+
244+ Just version ->
245+ [ div [ style "float" "left" ]
246+ [ Icon.package
247+ , a [ href (toPackageUrl pkg version) ] [ text (Package.toString pkg) ]
248+ ]
249+ , div [ style "float" "right" ] [ text (Version.toString version) ]
250+ ]
251+
252+
253+toPackageUrl : Package.Name -> Version.Version -> String
254+toPackageUrl name version =
255+ "http://package.elm-lang.org/packages/"
256+ ++ Package.toString name ++ "/" ++ Version.toString version