52 | Can I get an update on the latest version of the proposal to working group?
53 |
54 |
55 |
56 | The meeting is on Thursday and I think it's important that we all be on the same page coming into the meeting. If everyone has had a chance to vet the document in advance, I think that we have a better chance of moving the proposal to the next stage.
57 |
58 |
59 |
60 | This proposal has wide implications for the way we do business and it would be a shame for it to get held up at this stage because nobody had eyes on it before the meeting.
61 |
62 |
63 |
64 | I appreciate your attention to this!
65 |
66 |
67 |
68 | Thanks,
69 | Josie
70 |
71 |
72 | ---
73 | Josie Packard
74 | SVP for Financial Products
75 | Great Northern Company
76 |
77 | """
78 | , emailDelivery = Immediate
79 | , options =
80 | Dict.fromList
81 | [ ( 1, EmailOption "Respond to Josie explaining that the proposal is on track to be delivered tomorrow, at least 24 hours in advance of the meeting" 10 Nothing )
82 | , ( 2, EmailOption "Respond to Josie explaining that there is not enough time to complete the draft before the meeting and that she should dedicate the first 10 minutes of the meeting to reviewing the document." 50 Nothing )
83 | , ( 3, EmailOption "Respond to Josie's email after you have completed the draft." 100 Nothing )
84 | ]
85 | }
86 | )
87 | , ( "Vacation"
88 | , { from = "Dale Cooper"
89 | , email = ""
90 | , subject = "Corporate Vacation Policy"
91 | , teaser = " Hi Everyone, It's come to our attention that"
92 | , body =
93 | """
94 |
95 | Hi Everyone,
96 |
97 |
98 |
99 | It has come to our attention that the updated guidance on the corporate vacation policy contained an error. Please note that employees do not have unlimited vacation days as part of the revised policy.
100 |
101 |
102 |
103 | This email notification serves as an effective update of the corporate vacation policy until a new policy statement can be drafted. Please reply immediately to this email to acknowledge receipt of this communication and acceptance of the update.
104 |
105 |
106 |
107 | Sincerely,
108 | Dale Cooper
109 |
110 |
111 |
112 | ---
113 | Dale Cooper
114 | Human Resources Director
115 | Great Northern Company
116 |
117 | """
118 | , emailDelivery = Immediate
119 | , options =
120 | Dict.fromList
121 | [ ( 1, EmailOption "Respond immediately acknowledging that you have received the correspondence and accept the policy." 15 Nothing )
122 | , ( 2, EmailOption "Reply to all requesting clarification if vacation days taken since the policy update will count toward allowed vacation time." 75 Nothing )
123 | , ( 3, EmailOption "Move on to another email, respond later." 55 <| Just "VacationIgnoreResponse" )
124 | ]
125 | }
126 | )
127 | , ( "London"
128 | , { from = "Leo Johnson"
129 | , email = ""
130 | , subject = "Instructions to our office in London"
131 | , teaser = " Dear Mr. Smith, I just wanted to point out that in the instructions"
132 | , body =
133 | """
134 |
135 | Dear Mr. Smith,
136 |
137 |
138 |
139 | I just wanted to point out that in the instructions you sent to out global network, you failed to mention that for our London office, disclosure documentation needs to be delivered in hard and electronic format as is the custom here. This is a part of our workflow that is crucial to maintaining client confidence.
140 |
141 |
142 |
143 | As I'm sure you understand, it is important to take into account local customs and business practice when circulating procedural documentation to our network of 53 offices worldwide. It's a daunting task, but one that is of the utmost importance.
144 |
145 |
146 |
147 | Thank you for your attention to this matter. I kindly request that you reissue the instructions with correction to this matter.
148 |
149 |
150 |
151 | Kindly Yours,
152 | Leo Johnson
153 |
154 |
155 |
156 | ---
157 | Leo Johnson
158 | General Director, London Office
159 | Great Northern Company
160 |
161 | """
162 | , emailDelivery = Immediate
163 | , options =
164 | Dict.fromList
165 | [ ( 1, EmailOption "Respond immediately indicating that you will review and revise the instructions." 15 Nothing )
166 | , ( 2, EmailOption "Respond immediately indicating that you understand the concern, but accommodations like this cannot be made for each of the global offices." 75 Nothing )
167 | , ( 3, EmailOption "Move on to another email, respond later." 55 <| Just "LondonIgnoreResponse" )
168 | ]
169 | }
170 | )
171 | , ( "VacationIgnoreResponse"
172 | , { from = "Dale Cooper"
173 | , email = ""
174 | , subject = "Important: Response Required"
175 | , teaser = "It is important that you respond immediately to the previous"
176 | , body =
177 | """
178 |
179 | It is important that you respond immediately to the previous correspondence regarding the corporate vacation policy. Failure to do so may result in immediate suspension of employee benefits.
180 |
181 |
182 |
183 | Thank you for your attention.
184 |
185 |
186 |
187 | Sincerely,
188 | Dale Cooper
189 |
190 |
191 |
192 | ---
193 | Dale Cooper
194 | Human Resources Director
195 | Great Northern Company
196 |
197 | """
198 | , emailDelivery = Delayed
199 | , options =
200 | Dict.fromList
201 | [ ( 1, EmailOption "Respond immediately to this email acknowledging that you have received the correspondence and accept the policy." 15 Nothing )
202 | , ( 2, EmailOption "Respond immediately to the prior email acknowledging that you have received the correspondence and accept the policy." 25 Nothing )
203 | , ( 3, EmailOption "Move on to another email, respond later." 25 Nothing )
204 | ]
205 | }
206 | )
207 | , ( "LondonIgnoreResponse"
208 | , { from = "Leo Johnson"
209 | , email = ""
210 | , subject = "Re: Instructions to our office in London"
211 | , teaser = " Dear Mr. Smith, I just wanted to point out that in the instructions"
212 | , body =
213 | """
214 |
215 | Dear Mr. Smith,
216 |
217 |
218 |
219 | Just following up on the previous issue. Please acknowledge.
220 |
221 |
222 |
223 | Yours,
224 | Leo Johnson
225 |
226 |
227 |
228 | ---
229 | Leo Johnson
230 | General Director, London Office
231 | Great Northern Company
232 |
233 | """
234 | , emailDelivery = Delayed
235 | , options =
236 | Dict.fromList
237 | [ ( 1, EmailOption "Respond immediately indicating that you will review and revise the instructions." 15 Nothing )
238 | , ( 2, EmailOption "Respond immediately indicating that you understand the concern, but accommodations like this cannot be made for each of the global offices." 75 Nothing )
239 | , ( 3, EmailOption "Move on to another email, respond later." 25 Nothing )
240 | ]
241 | }
242 | )
243 | ]
244 |
--------------------------------------------------------------------------------
/src/elm/Pages/Inbox/Test.elm:
--------------------------------------------------------------------------------
1 | module Pages.Inbox.Test exposing (..)
2 |
3 | import ElmTest exposing (..)
4 | import Pages.Inbox.Model as Inbox exposing (emptyModel, Model)
5 | import Pages.Inbox.Update as Inbox exposing (..)
6 |
7 |
8 | setActiveEmail : Test
9 | setActiveEmail =
10 | suite "setActiveEmail action"
11 | [ test "no active email" (assertEqual Nothing (.selectedEmail <| updateInbox <| Inbox.SetSelectedEmail Nothing))
12 | , test "active email" (assertEqual (Just "Vacation") (.selectedEmail <| updateInbox <| Inbox.SetSelectedEmail <| Just "Vacation"))
13 | ]
14 |
15 |
16 | updateInbox : Inbox.Msg -> Inbox.Model
17 | updateInbox action =
18 | fst <| Inbox.update action emptyModel
19 |
20 |
21 | all : Test
22 | all =
23 | suite "Inbox tests"
24 | [ setActiveEmail
25 | ]
26 |
--------------------------------------------------------------------------------
/src/elm/Pages/Inbox/Update.elm:
--------------------------------------------------------------------------------
1 | module Pages.Inbox.Update exposing (update, Msg(..))
2 |
3 | import Dict exposing (..)
4 | import Dom.Scroll as Dom exposing (..)
5 | import Email.Model exposing (..)
6 | import Pages.Inbox.Model as Inbox exposing (..)
7 | import Process exposing (sleep)
8 | import Task
9 |
10 |
11 | init : ( Model, Cmd Msg )
12 | init =
13 | emptyModel ! []
14 |
15 |
16 | type Msg
17 | = DeliverEmail EmailType
18 | | NoOp
19 | | SetEmailStatus EmailType Int
20 | | SetSelectedEmail (Maybe EmailType)
21 |
22 |
23 | update : Msg -> Model -> ( Model, Cmd Msg )
24 | update action model =
25 | case action of
26 | DeliverEmail emailType ->
27 | -- Rebuild the dict, by appending the new email to the list.
28 | let
29 | shownEmails =
30 | if (List.any (\type' -> emailType == type') model.shownEmails) then
31 | -- Email type is already in the shown emails list.
32 | model.shownEmails
33 | else
34 | -- Append the new email type to the shown list.
35 | emailType :: model.shownEmails
36 | in
37 | { model | shownEmails = shownEmails } ! []
38 |
39 | NoOp ->
40 | model ! []
41 |
42 | SetEmailStatus emailType keyOption ->
43 | let
44 | emailsStatus =
45 | Dict.insert emailType keyOption model.emailsStatus
46 |
47 | cmd =
48 | case Dict.get emailType model.emails of
49 | Nothing ->
50 | []
51 |
52 | Just email ->
53 | case Dict.get keyOption email.options of
54 | Nothing ->
55 | []
56 |
57 | Just option ->
58 | case option.triggerEmail of
59 | Nothing ->
60 | []
61 |
62 | Just emailType' ->
63 | -- Sleep for 2 seconds, and send the triggered email.
64 | [ Process.sleep (2 * 1000) |> Task.perform (always <| DeliverEmail emailType') (always <| DeliverEmail emailType') ]
65 | in
66 | { model | emailsStatus = emailsStatus } ! cmd
67 |
68 | SetSelectedEmail emailType ->
69 | let
70 | -- Set email status
71 | emailsStatus =
72 | case emailType of
73 | Nothing ->
74 | model.emailsStatus
75 |
76 | Just val ->
77 | case (Dict.get val model.emailsStatus) of
78 | Nothing ->
79 | let
80 | model' =
81 | fst <| update (SetEmailStatus val 0) model
82 | in
83 | model'.emailsStatus
84 |
85 | Just _ ->
86 | model.emailsStatus
87 |
88 | scrollTo =
89 | Dom.toTop "selected-email"
90 | in
91 | { model
92 | | selectedEmail = emailType
93 | , emailsStatus = emailsStatus
94 | }
95 | ! [ Task.perform (\_ -> NoOp) (\_ -> NoOp) scrollTo ]
96 |
--------------------------------------------------------------------------------
/src/elm/Pages/Inbox/Utils.elm:
--------------------------------------------------------------------------------
1 | module Pages.Inbox.Utils exposing (getScore)
2 |
3 | import Pages.Inbox.Model as Inbox exposing (..)
4 | import Dict exposing (..)
5 |
6 |
7 | getScore : Model -> Int
8 | getScore model =
9 | let
10 | calculate emailType optionKey total =
11 | case (Dict.get emailType model.emails) of
12 | Nothing ->
13 | 0
14 |
15 | Just email ->
16 | case (Dict.get optionKey email.options) of
17 | Nothing ->
18 | 0
19 |
20 | Just option ->
21 | option.score + total
22 | in
23 | Dict.foldl calculate 0 model.emailsStatus
24 |
--------------------------------------------------------------------------------
/src/elm/Pages/Inbox/View.elm:
--------------------------------------------------------------------------------
1 | module Pages.Inbox.View exposing (view)
2 |
3 | import Dict exposing (..)
4 | import Html exposing (..)
5 | import Html.Attributes exposing (..)
6 | import Html.Events exposing (onClick)
7 | import Json.Encode as JSON exposing (string)
8 | import Pages.Inbox.Model exposing (..)
9 | import Pages.Inbox.Update exposing (..)
10 | import Email.Model exposing (..)
11 |
12 |
13 | view : Model -> Html Msg
14 | view model =
15 | div [ class "ui container" ]
16 | [ viewNavbar model
17 | , viewMain model
18 | ]
19 |
20 |
21 | viewNavbar : Model -> Html Msg
22 | viewNavbar model =
23 | div [ class "container" ]
24 | [ div [ class "ui inverted menu top__menu" ]
25 | [ a [ class "ui item microsoft_logo" ]
26 | [ i [ class "grid layout icon" ]
27 | []
28 | ]
29 | , div [ class "header item" ]
30 | [ text "Outlook Mail" ]
31 | , div [ class "right menu" ]
32 | [ a [ class "ui item" ]
33 | [ i [ class "skype icon" ]
34 | []
35 | ]
36 | , a [ class "ui item" ]
37 | [ i [ class "alarm icon" ]
38 | []
39 | ]
40 | , a [ class "ui item" ]
41 | [ i [ class "setting icon" ]
42 | []
43 | ]
44 | , a [ class "ui item" ]
45 | [ i [ class "help icon" ]
46 | []
47 | ]
48 | ]
49 | ]
50 | ]
51 |
52 |
53 | viewMain : Model -> Html Msg
54 | viewMain model =
55 | div [ class "ui container" ]
56 | [ div [ class "main" ]
57 | [ div [ class "sidebar_left" ]
58 | [ div [ class "sidebar_left__search" ]
59 | [ span [ class "sidebar_left__search__text" ]
60 | [ text "Search Mail and People" ]
61 | , span [ class "sidebar_left__search__icon" ]
62 | [ i [ class "search icon" ]
63 | []
64 | ]
65 | ]
66 | , div [ class "sidebar_left__folders" ]
67 | [ div [ class "ui vertical secondary menu" ]
68 | [ div [ class "item" ]
69 | [ div [ class "header" ]
70 | [ text "Folders" ]
71 | , div [ class "menu" ]
72 | [ a [ class "item" ]
73 | [ text "Inbox" ]
74 | , a [ class "item" ]
75 | [ text "Junk Mail" ]
76 | , a [ class "item" ]
77 | [ text "Drafts" ]
78 | , a [ class "item" ]
79 | [ text "Sent Items" ]
80 | , a [ class "item" ]
81 | [ text "Deleted Items" ]
82 | ]
83 | ]
84 | ]
85 | ]
86 | ]
87 | , div [ class "content" ]
88 | [ div [ class "content__toolbar" ]
89 | [ div [ class "ui secondary menu" ]
90 | [ a [ class "ui item" ]
91 | [ i [ class "plus square outline icon" ]
92 | []
93 | , text "New"
94 | ]
95 | , a [ class "ui item" ]
96 | [ i [ class "trash outline icon" ]
97 | []
98 | , text "Delete"
99 | ]
100 | , a [ class "ui item" ]
101 | [ i [ class "archive icon" ]
102 | []
103 | , text "Archive"
104 | ]
105 | , a [ class "ui item" ]
106 | [ text "Junk"
107 | , i [ class "angle down icon" ]
108 | []
109 | ]
110 | , a [ class "ui item" ]
111 | [ text "Sweep" ]
112 | , a [ class "ui item" ]
113 | [ text "Move to"
114 | , i [ class "angle down icon" ]
115 | []
116 | ]
117 | , a [ class "ui item" ]
118 | [ text "Categories"
119 | , i [ class "angle down icon" ]
120 | []
121 | ]
122 | , div [ class "ui right secondary menu" ]
123 | [ a [ class "ui item" ]
124 | [ i [ class "undo icon" ]
125 | []
126 | , text "Undo"
127 | ]
128 | ]
129 | ]
130 | ]
131 | , div [ class "content__messages" ]
132 | [ div [ class "content__messages__list" ]
133 | [ div [ class "ui relaxed divided list" ]
134 | (List.map (viewMailItem model.emails model.emailsStatus) model.shownEmails)
135 | ]
136 | , (viewSelectedEmail model)
137 | ]
138 | ]
139 | ]
140 | ]
141 |
142 |
143 | viewMailItem : Dict EmailType Email -> EmailsStatus -> EmailType -> Html Msg
144 | viewMailItem emails emailsStatus emailType =
145 | case Dict.get emailType emails of
146 | Nothing ->
147 | -- This shouldn't ever happen.
148 | div [] []
149 |
150 | Just email ->
151 | let
152 | notOpened =
153 | case Dict.get emailType emailsStatus of
154 | Nothing ->
155 | True
156 |
157 | Just _ ->
158 | False
159 | in
160 | div [ class "item" ]
161 | [ div [ class "content__messages__list__checkbox" ]
162 | [ input [ type' "checkbox" ]
163 | []
164 | ]
165 | , div
166 | [ classList
167 | [ ( "content__messages__list__item", True )
168 | , ( "not-opened", notOpened )
169 | ]
170 | ]
171 | [ a
172 | [ class "content__messages__list__item__from"
173 | , (onClick <| SetSelectedEmail <| Just emailType)
174 | ]
175 | [ text email.from ]
176 | , div [ class "content__messages__list__item__subject" ]
177 | [ text email.subject ]
178 | , div [ class "content__messages__list__item__content" ]
179 | [ text email.teaser ]
180 | ]
181 | ]
182 |
183 |
184 | viewSelectedEmail : Model -> Html Msg
185 | viewSelectedEmail model =
186 | case model.selectedEmail of
187 | Nothing ->
188 | div [] []
189 |
190 | Just name ->
191 | let
192 | memail =
193 | Dict.get name model.emails
194 | in
195 | case memail of
196 | Nothing ->
197 | div [] []
198 |
199 | Just email ->
200 | div
201 | [ class "content__messages__selected"
202 | , id "selected-email"
203 | ]
204 | [ div [ class "content__messages__selected__header" ]
205 | [ div [ class "content__messages__selected__header_title" ]
206 | [ text email.subject ]
207 | , div [ class "content__messages__selected__header_sender" ]
208 | [ text email.from ]
209 | , div [ class "content__messages__selected__header__reply" ]
210 | [ div [ class "content__messages__selected__header__reply_all" ]
211 | [ i [ class "reply all icon" ]
212 | []
213 | , text "Reply All"
214 | , i [ class "angle down icon" ]
215 | []
216 | ]
217 | ]
218 | , div [ class "content__messages__selected__header_date" ]
219 | [ text "Tue 9/13/2016 10:26 AM" ]
220 | ]
221 | , div
222 | [ class "content__messages__selected__content"
223 | -- Treat the email body as HTML.
224 | , property "innerHTML" <| JSON.string email.body
225 | ]
226 | []
227 | , div [ class "ui form icon message content__messages__action" ]
228 | [ i [ class "inbox icon" ]
229 | []
230 | , div [ class "grouped fields" ]
231 | [ label [] [ text "Action:" ]
232 | , div [] (List.map (viewShowOption name model.emailsStatus) <| Dict.toList email.options)
233 | ]
234 | ]
235 | ]
236 |
237 |
238 | viewShowOption : EmailType -> EmailsStatus -> ( Int, EmailOption ) -> Html Msg
239 | viewShowOption emailType emailsStatus ( optionKey, option ) =
240 | let
241 | ( isChecked, optionSelected ) =
242 | case (Dict.get emailType emailsStatus) of
243 | Nothing ->
244 | ( False, False )
245 |
246 | Just index ->
247 | ( optionKey == index, index > 0 )
248 | in
249 | div [ class "field" ]
250 | [ div [ class "ui radio checkbox" ]
251 | [ input
252 | [ type' "radio"
253 | , name "radio"
254 | , checked isChecked
255 | , onClick <| SetEmailStatus emailType optionKey
256 | , disabled optionSelected
257 | ]
258 | []
259 | , label []
260 | [ text option.label ]
261 | ]
262 | ]
263 |
--------------------------------------------------------------------------------
/src/elm/Pages/PageNotFound/View.elm:
--------------------------------------------------------------------------------
1 | module Pages.PageNotFound.View exposing (view)
2 |
3 | import Html exposing (a, div, h2, text, Html)
4 | import Html.Attributes exposing (class, href)
5 |
6 |
7 | -- VIEW
8 |
9 |
10 | view : Html a
11 | view =
12 | div [ class "ui segment center aligned" ]
13 | [ h2 [] [ text "This is a 404 page!" ]
14 | ]
15 |
--------------------------------------------------------------------------------
/src/elm/Pages/ScoreDashboard/View.elm:
--------------------------------------------------------------------------------
1 | module Pages.ScoreDashboard.View exposing (view)
2 |
3 | import Json.Encode as Json
4 | import Html exposing (..)
5 | import Html.Attributes exposing (..)
6 | import Pages.Inbox.Model exposing (..)
7 | import Pages.Inbox.Utils exposing (..)
8 |
9 |
10 | -- VIEW
11 |
12 |
13 | view : Model -> Html a
14 | view model =
15 | div [ class "ui container" ]
16 | [ div [ class "ui segment stacked" ]
17 | [ table [ class "ui very basic collapsing celled table" ]
18 | [ thead []
19 | [ tr []
20 | [ th [ rowspan 2 ]
21 | [ text "Employee" ]
22 | , th [ rowspan 2 ]
23 | [ text "Overall Progress" ]
24 | , th [ colspan 2 ]
25 | [ text "Inbox Simulation" ]
26 | , th [ colspan 2 ]
27 | [ text "Leadership Assessment" ]
28 | , th [ rowspan 2 ]
29 | [ text "Overall Score" ]
30 | ]
31 | , tr []
32 | [ th []
33 | [ text "Time to Complete" ]
34 | , th []
35 | [ text "Score" ]
36 | , th []
37 | [ text "Time to Complete" ]
38 | , th []
39 | [ text "Score" ]
40 | ]
41 | ]
42 | , tbody [] (List.map (hardcodedRows model) dummyScores)
43 | ]
44 | ]
45 | ]
46 |
47 |
48 | type alias ScoreAndTime =
49 | { score :
50 | Int
51 | -- @todo: Change to Time
52 | , time : String
53 | }
54 |
55 |
56 | type alias Score =
57 | { name : String
58 | , position : String
59 | , progress : Int
60 | , inboxSimulation : ScoreAndTime
61 | , leadershipAssessment : ScoreAndTime
62 | , overallScore : Int
63 | }
64 |
65 |
66 | dummyScores : List Score
67 | dummyScores =
68 | [ { name = "John Q. Smith"
69 | , position = "Human Resources"
70 | , progress = 96
71 | , inboxSimulation = ScoreAndTime 22 "10:22"
72 | , leadershipAssessment = ScoreAndTime 45 "12:10"
73 | , overallScore = 0
74 | }
75 | , { name = "Laura Palmer"
76 | , position = "Financial Services"
77 | , progress = 50
78 | , inboxSimulation = ScoreAndTime 66 "15:22"
79 | , leadershipAssessment = ScoreAndTime 25 "20:09"
80 | , overallScore = 91
81 | }
82 | , { name = "Josie Packard"
83 | , position = "Financial Services"
84 | , progress = 22
85 | , inboxSimulation = ScoreAndTime 38 "14:22"
86 | , leadershipAssessment = ScoreAndTime 22 "24:10"
87 | , overallScore = 60
88 | }
89 | , { name = "Dale Cooper"
90 | , position = "Human Resources"
91 | , progress = 78
92 | , inboxSimulation = ScoreAndTime 25 "15:18"
93 | , leadershipAssessment = ScoreAndTime 36 "20:10"
94 | , overallScore = 61
95 | }
96 | , { name = "Leo Johnson"
97 | , position = "Human Resources"
98 | , progress = 34
99 | , inboxSimulation = ScoreAndTime 62 "14:21"
100 | , leadershipAssessment = ScoreAndTime 23 "18:04"
101 | , overallScore = 85
102 | }
103 | , { name = "Audrey Horne"
104 | , position = "Financial Services"
105 | , progress = 58
106 | , inboxSimulation = ScoreAndTime 62 "13:28"
107 | , leadershipAssessment = ScoreAndTime 25 "19:18"
108 | , overallScore = 87
109 | }
110 | ]
111 |
112 |
113 | hardcodedRows : Model -> Score -> Html msg
114 | hardcodedRows model scoreData =
115 | let
116 | -- For the first user in the row, we use the calculated overall score.
117 | overallScore =
118 | if scoreData.name == "John Q. Smith" then
119 | getScore model
120 | else
121 | scoreData.overallScore
122 | in
123 | tr []
124 | [ td []
125 | [ h4 [ class "ui image header" ]
126 | [ i [ class "user icon" ]
127 | []
128 | , div [ class "content" ]
129 | [ text scoreData.name
130 | , div [ class "sub header" ]
131 | [ text scoreData.position ]
132 | ]
133 | ]
134 | ]
135 | , td []
136 | -- Progress bar
137 | [ (node "progress")
138 | [ value <| toString scoreData.progress
139 | , Html.Attributes.max "100"
140 | ]
141 | []
142 | ]
143 | , td []
144 | [ text scoreData.inboxSimulation.time ]
145 | , td []
146 | [ text <| toString scoreData.inboxSimulation.score ]
147 | , td []
148 | [ text scoreData.leadershipAssessment.time ]
149 | , td []
150 | [ text <| toString scoreData.leadershipAssessment.score ]
151 | , td []
152 | [ text <| toString overallScore ]
153 | ]
154 |
--------------------------------------------------------------------------------
/src/elm/TestRunner.elm:
--------------------------------------------------------------------------------
1 | module Main exposing (..)
2 |
3 | import ElmTest exposing (..)
4 | import Pages.Inbox.Test as Inbox exposing (all)
5 |
6 |
7 | allTests : Test
8 | allTests =
9 | suite "All tests"
10 | [ Inbox.all
11 | ]
12 |
13 |
14 | main : Program Never
15 | main =
16 | runSuiteHtml allTests
17 |
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Elm
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/js/README.md:
--------------------------------------------------------------------------------
1 | Place JS, and JS-inerop files in this folder.
2 |
--------------------------------------------------------------------------------
/static/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled source #
2 | ###################
3 | *.com
4 | *.class
5 | *.dll
6 | *.exe
7 | *.o
8 | *.so
9 |
10 | # Packages #
11 | ############
12 | # it's better to unpack these files and commit the raw source
13 | # git has its own built in compression methods
14 | *.7z
15 | *.dmg
16 | *.gz
17 | *.iso
18 | *.jar
19 | *.rar
20 | *.tar
21 | *.zip
22 |
23 | # Logs and databases #
24 | ######################
25 | *.log
26 | *.sql
27 | *.sqlite
28 |
29 | # OS generated files #
30 | ######################
31 | .DS_Store
32 | .DS_Store?
33 | ._*
34 | .Spotlight-V100
35 | .Trashes
36 | Icon?
37 | ehthumbs.db
38 | Thumbs.db
39 |
40 | # IDE #
41 | ##########
42 | .project
43 | .settings/
44 | .idea
45 |
46 | node_modules
47 | .tmp
48 |
49 | # Jekyll compiled stylesheet
50 | src/assets/stylesheets/style.css
51 | site/assets/stylesheets/style.css
52 |
53 | # Jekyll related folders
54 | serve
55 | site
56 |
--------------------------------------------------------------------------------
/static/Gemfile:
--------------------------------------------------------------------------------
1 | source "http://rubygems.org"
2 |
3 | gem 'jekyll'
4 | gem 'redcarpet'
5 | gem 'classifier-reborn'
6 | gem 'fast-stemmer'
7 | gem 'scss_lint'
8 |
--------------------------------------------------------------------------------
/static/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: http://rubygems.org/
3 | specs:
4 | classifier-reborn (2.0.4)
5 | fast-stemmer (~> 1.0)
6 | colorator (0.1)
7 | fast-stemmer (1.0.2)
8 | ffi (1.9.10)
9 | jekyll (3.1.6)
10 | colorator (~> 0.1)
11 | jekyll-sass-converter (~> 1.0)
12 | jekyll-watch (~> 1.1)
13 | kramdown (~> 1.3)
14 | liquid (~> 3.0)
15 | mercenary (~> 0.3.3)
16 | rouge (~> 1.7)
17 | safe_yaml (~> 1.0)
18 | jekyll-sass-converter (1.4.0)
19 | sass (~> 3.4)
20 | jekyll-watch (1.4.0)
21 | listen (~> 3.0, < 3.1)
22 | kramdown (1.11.1)
23 | liquid (3.0.6)
24 | listen (3.0.8)
25 | rb-fsevent (~> 0.9, >= 0.9.4)
26 | rb-inotify (~> 0.9, >= 0.9.7)
27 | mercenary (0.3.6)
28 | rake (11.2.2)
29 | rb-fsevent (0.9.7)
30 | rb-inotify (0.9.7)
31 | ffi (>= 0.5.0)
32 | redcarpet (3.3.4)
33 | rouge (1.11.1)
34 | safe_yaml (1.0.4)
35 | sass (3.4.22)
36 | scss_lint (0.48.0)
37 | rake (>= 0.9, < 12)
38 | sass (~> 3.4.15)
39 |
40 | PLATFORMS
41 | ruby
42 |
43 | DEPENDENCIES
44 | classifier-reborn
45 | fast-stemmer
46 | jekyll
47 | redcarpet
48 | scss_lint
49 |
--------------------------------------------------------------------------------
/static/README.md:
--------------------------------------------------------------------------------
1 | ## Installation
2 |
3 | ```bash
4 | npm install
5 | bundle install
6 | ```
7 |
8 | Then run `gulp` to start the local server with BrowserSync.
9 |
10 | ## Deploying to `gh-pages`
11 | In order to publish your work run `gulp publish && gulp deploy` while on the master branch.
12 |
--------------------------------------------------------------------------------
/static/_config.build.yml:
--------------------------------------------------------------------------------
1 | # Run during the 'gulp build' command
2 | # Overrides these options in _config.yml
3 |
4 | # Hides your drafts and future posts
5 | future: false
6 | show_drafts: false
7 | # Gives you more accurate related posts
8 | lsi: true
9 | # Removes the upper limit for posts generated
10 | limit_posts: 0
11 |
12 | source: 'src'
13 | destination: 'serve'
14 |
--------------------------------------------------------------------------------
/static/_config.yml:
--------------------------------------------------------------------------------
1 | # Title, decription, tagline and URL for your site
2 | # Can be used in your theme by calling 'site.title' and so on
3 | title: Jekyll-base
4 | description:
5 | tagline:
6 | url: localhost:4000
7 |
8 | source: src
9 | destination: serve
10 |
--------------------------------------------------------------------------------
/static/gulpfile.js:
--------------------------------------------------------------------------------
1 | // Generated on 2015-05-04 using generator-jekyllized 0.7.3
2 | "use strict";
3 |
4 | var gulp = require("gulp");
5 | // Loads the plugins without having to list all of them, but you need
6 | // to call them as $.pluginname
7 | var $ = require("gulp-load-plugins")();
8 | // "del" is used to clean out directories and such
9 | var del = require("del");
10 | // BrowserSync isn"t a gulp package, and needs to be loaded manually
11 | var browserSync = require("browser-sync");
12 | // merge is used to merge the output from two different streams into the same stream
13 | var merge = require("merge-stream");
14 | // Need a command for reloading webpages using BrowserSync
15 | var reload = browserSync.reload;
16 | // And define a variable that BrowserSync uses in it"s function
17 | var bs;
18 |
19 | var util = require("gulp-util");
20 | var source = require("vinyl-source-stream");
21 | var svgstore = require('gulp-svgstore');
22 | var svgmin = require('gulp-svgmin');
23 |
24 | // Deletes the directory that is used to serve the site during development
25 | gulp.task("clean:dev", del.bind(null, ["serve"]));
26 |
27 | // Deletes the directory that the optimized site is output to
28 | gulp.task("clean:prod", del.bind(null, ["site"]));
29 |
30 | // Runs the build command for Jekyll to compile the site locally
31 | // This will build the site with the production settings
32 | gulp.task("jekyll:dev", $.shell.task("jekyll build"));
33 | gulp.task("jekyll-rebuild", ["jekyll:dev", "js"], function () {
34 | reload;
35 | });
36 |
37 | // Almost identical to the above task, but instead we load in the build configuration
38 | // that overwrites some of the settings in the regular configuration so that you
39 | // don"t end up publishing your drafts or future posts
40 | gulp.task("jekyll:prod", $.shell.task("jekyll build --config _config.yml,_config.build.yml"));
41 |
42 | // Compiles the SASS files and moves them into the "assets/stylesheets" directory
43 | gulp.task("styles", function () {
44 | // Looks at the style.scss file for what to include and creates a style.css file
45 | return gulp.src("src/assets/scss/style.scss")
46 | .pipe($.sass())
47 | // AutoPrefix your CSS so it works between browsers
48 | .pipe($.autoprefixer("last 1 version", { cascade: true }))
49 | // Directory your CSS file goes to
50 | .pipe(gulp.dest("src/assets/stylesheets/"))
51 | .pipe(gulp.dest("serve/assets/stylesheets/"))
52 | .pipe(gulp.dest("site/assets/stylesheets/"))
53 | // Outputs the size of the CSS file
54 | .pipe($.size({title: "styles"}))
55 | // Injects the CSS changes to your browser since Jekyll doesn"t rebuild the CSS
56 | .pipe(reload({stream: true}));
57 | });
58 |
59 | gulp.task("js", function() {
60 | gulp.src('./src/assets/javascript/*.js')
61 | .pipe(gulp.dest('./src/assets/javascript'))
62 | .pipe(gulp.dest("site/assets/javascript/"));
63 | });
64 |
65 | // Optimizes the images that exists
66 | gulp.task("images", function () {
67 | return gulp.src("src/images/**")
68 | .pipe($.changed("site/images"))
69 | .pipe($.imagemin({
70 | // Lossless conversion to progressive JPGs
71 | progressive: true,
72 | // Interlace GIFs for progressive rendering
73 | interlaced: true
74 | }))
75 | .pipe(gulp.dest("site/images"))
76 | .pipe($.size({title: "images"}));
77 | });
78 |
79 | // Copy over fonts to the "site" directory
80 | gulp.task("fonts", function () {
81 | return gulp.src("src/assets/fonts/**")
82 | .pipe(gulp.dest("site/assets/fonts"))
83 | .pipe($.size({ title: "fonts" }));
84 | });
85 |
86 | // Copy over vendors to the "site" directory
87 | gulp.task("vendors", function () {
88 | return gulp.src("src/assets/javascript/vendors/**")
89 | .pipe(gulp.dest("site/assets/javascript/vendors"))
90 | .pipe($.size({ title: "vendors" }));
91 | });
92 |
93 | // Copy xml and txt files to the "site" directory
94 | gulp.task("copy", function () {
95 | return gulp.src(["serve/*.txt", "serve/*.xml", "serve/shoovify.sh"])
96 | .pipe(gulp.dest("site"))
97 | .pipe($.size({ title: "xml & txt & shoovify.sh" }))
98 | });
99 |
100 | gulp.task("cname", function () {
101 | return gulp.src(["serve/CNAME"])
102 | .pipe(gulp.dest("site"))
103 | .pipe($.size({ title: "CNAMe" }))
104 | });
105 |
106 |
107 | // Optimizes all the CSS, HTML and concats the JS etc
108 | gulp.task("html", ["styles"], function () {
109 | var assets = $.useref.assets({searchPath: "serve"});
110 |
111 | return gulp.src("serve/**/*.html")
112 | .pipe(assets)
113 | // Concatenate JavaScript files and preserve important comments
114 | .pipe($.if("*.js", $.uglify({preserveComments: "some"})))
115 | // Minify CSS
116 | .pipe($.if("*.css", $.minifyCss()))
117 | // Start cache busting the files
118 | .pipe($.revAll({ ignore: [".eot", ".svg", ".ttf", ".woff"] }))
119 | .pipe(assets.restore())
120 | // Conctenate your files based on what you specified in _layout/header.html
121 | .pipe($.useref())
122 | // Replace the asset names with their cache busted names
123 | .pipe($.revReplace())
124 | // Minify HTML
125 | .pipe($.if("*.html", $.htmlmin({
126 | removeComments: true,
127 | removeCommentsFromCDATA: true,
128 | removeCDATASectionsFromCDATA: true,
129 | collapseWhitespace: true,
130 | collapseBooleanAttributes: true,
131 | removeAttributeQuotes: true,
132 | removeRedundantAttributes: true,
133 | keepClosingSlash: true
134 | })))
135 | // Send the output to the correct folder
136 | .pipe(gulp.dest("site"))
137 | .pipe($.size({title: "optimizations"}));
138 | });
139 |
140 |
141 | // Task to upload your site to your personal GH Pages repo
142 | gulp.task("deploy", function () {
143 | // Deploys your optimized site, you can change the settings in the html task if you want to
144 | return gulp.src("./site/**/*")
145 | .pipe($.ghPages({
146 | // Currently only personal GitHub Pages are supported so it will upload to the master
147 | // branch and automatically overwrite anything that is in the directory
148 | cacheDir: "./.tmp"
149 | }));
150 | });
151 |
152 | // Run JS Lint against your JS
153 | gulp.task("jslint", function () {
154 | gulp.src("./serve/assets/javascript/*.js")
155 | // Checks your JS code quality against your .jshintrc file
156 | .pipe($.jshint(".jshintrc"))
157 | .pipe($.jshint.reporter());
158 | });
159 |
160 | // Runs "jekyll doctor" on your site to check for errors with your configuration
161 | // and will check for URL errors a well
162 | gulp.task("doctor", $.shell.task("jekyll doctor"));
163 |
164 | // BrowserSync will serve our site on a local server for us and other devices to use
165 | // It will also autoreload across all devices as well as keep the viewport synchronized
166 | // between them.
167 | gulp.task("serve:dev", ["styles", "jekyll:dev", "js"], function () {
168 | bs = browserSync({
169 | notify: true,
170 | open: true,
171 | // tunnel: "",
172 | server: {
173 | baseDir: "serve"
174 | }
175 | });
176 | });
177 |
178 | // These tasks will look for files that change while serving and will auto-regenerate or
179 | // reload the website accordingly. Update or add other files you need to be watched.
180 | gulp.task("watch", function () {
181 | gulp.watch(["src/**/*.md", "src/**/*.html", "src/**/*.xml", "src/**/*.txt", "src/**/*.js"], ["jekyll-rebuild", reload]);
182 | gulp.watch(["serve/assets/stylesheets/*.css"], reload({stream: true}));
183 | gulp.watch(["src/assets/scss/**/*.scss"], ["styles", reload]);
184 | });
185 |
186 | // Serve the site after optimizations to see that everything looks fine
187 | gulp.task("serve:prod", function () {
188 | bs = browserSync({
189 | notify: false,
190 | // tunnel: true,
191 | server: {
192 | baseDir: "site"
193 | }
194 | });
195 | });
196 |
197 | // Default task, run when just writing "gulp" in the terminal
198 | gulp.task("default", ["serve:dev", "watch"]);
199 |
200 | // Checks your CSS, JS and Jekyll for errors
201 | gulp.task("check", ["jslint", "doctor"], function () {
202 | // Better hope nothing is wrong.
203 | });
204 |
205 | // Builds the site but doesn"t serve it to you
206 | gulp.task("build", ["jekyll:prod", "styles", "js"], function () {});
207 |
208 | // Copies favicon to the site folder
209 | gulp.task("copy-favicon", function() {
210 | return gulp.src("src/assets/favicon.png")
211 | .pipe(gulp.dest("site/assets"));
212 | });
213 |
214 | // Builds your site with the "build" command and then runs all the optimizations on
215 | // it and outputs it to "./site"
216 | gulp.task("publish", ["build"], function () {
217 | gulp.start("html", "copy", "cname", "images", "fonts", "vendors", "js", "copy-favicon");
218 | });
219 |
220 |
221 |
222 | gulp.task('svgstore', function () {
223 | return gulp
224 | .src('src/images/elements/*.svg')
225 | .pipe(svgmin(function (file) {
226 | return {
227 | plugins: [{
228 | removeTitle: true
229 | }, {
230 | cleanupNumericValues: {
231 | floatPrecision: 1
232 | }
233 | }
234 | ]
235 | }
236 | }))
237 | .pipe(svgstore())
238 | .pipe(gulp.dest('src/_includes/'));
239 | });
240 |
--------------------------------------------------------------------------------
/static/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Jekyll-base",
3 | "private": true,
4 | "version": "0.0.0",
5 | "description": "Yeoman workflow for Ifat News",
6 | "dependencies": {},
7 | "devDependencies": {
8 | "browser-sync": "^1.5.7",
9 | "del": "^1.1.1",
10 | "gulp": "^3.8.8",
11 | "gulp-autoprefixer": "^2.0.0",
12 | "gulp-cache": "~0.2.2",
13 | "gulp-cached": "^1.0.1",
14 | "gulp-changed": "^1.0.0",
15 | "gulp-filter": "^2.0.0",
16 | "gulp-gh-pages": "0.5.4",
17 | "gulp-gzip": "0.0.8",
18 | "gulp-htmlmin": "^0.2.0",
19 | "gulp-if": "^1.2.4",
20 | "gulp-imagemin": "^2.1.0",
21 | "gulp-jshint": "^1.8.5",
22 | "gulp-load-plugins": "^0.8.0",
23 | "gulp-minify-css": "^0.3.10",
24 | "gulp-rev-all": "^0.7.5",
25 | "gulp-rev-replace": "^0.3.1",
26 | "gulp-sass": "^2.0.4",
27 | "gulp-shell": "^0.2.9",
28 | "gulp-size": "^1.1.0",
29 | "gulp-svgmin": "^1.2.2",
30 | "gulp-svgstore": "^6.0.0",
31 | "gulp-uglify": "^1.0.1",
32 | "gulp-uncss": "^0.5.0",
33 | "gulp-useref": "^1.0.2",
34 | "gulp-util": "^3.0.7",
35 | "install": "^0.7.3",
36 | "jshint-stylish": "^1.0.0",
37 | "merge-stream": "^0.1.6",
38 | "npm": "^3.9.0",
39 | "vinyl-source-stream": "^1.1.0"
40 | },
41 | "engines": {
42 | "node": ">0.10.0"
43 | },
44 | "scripts": {}
45 | }
46 |
--------------------------------------------------------------------------------
/static/src/_includes/footer.html:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/static/src/_includes/header.html:
--------------------------------------------------------------------------------
1 |
2 |