1port module Views.SilenceForm.Updates exposing (update) 2 3import Alerts.Api 4import Browser.Navigation as Navigation 5import Silences.Api 6import Task 7import Time 8import Types exposing (Msg(..)) 9import Utils.Date exposing (timeFromString) 10import Utils.Filter exposing (silencePreviewFilter) 11import Utils.FormValidation exposing (fromResult, stringNotEmpty, updateValue, validate) 12import Utils.List 13import Utils.Types exposing (ApiData(..)) 14import Views.SilenceForm.Types 15 exposing 16 ( Model 17 , SilenceForm 18 , SilenceFormFieldMsg(..) 19 , SilenceFormMsg(..) 20 , emptyMatcher 21 , fromMatchersAndCommentAndTime 22 , fromSilence 23 , parseEndsAt 24 , toSilence 25 , validateForm 26 ) 27 28 29updateForm : SilenceFormFieldMsg -> SilenceForm -> SilenceForm 30updateForm msg form = 31 case msg of 32 AddMatcher -> 33 { form | matchers = form.matchers ++ [ emptyMatcher ] } 34 35 UpdateStartsAt time -> 36 let 37 startsAt = 38 Utils.Date.timeFromString time 39 40 endsAt = 41 Utils.Date.timeFromString form.endsAt.value 42 43 durationValue = 44 case Result.map2 Utils.Date.timeDifference startsAt endsAt of 45 Ok duration -> 46 case Utils.Date.durationFormat duration of 47 Just value -> 48 value 49 50 Nothing -> 51 form.duration.value 52 53 Err _ -> 54 form.duration.value 55 in 56 { form 57 | startsAt = updateValue time form.startsAt 58 , duration = updateValue durationValue form.duration 59 } 60 61 UpdateEndsAt time -> 62 let 63 endsAt = 64 Utils.Date.timeFromString time 65 66 startsAt = 67 Utils.Date.timeFromString form.startsAt.value 68 69 durationValue = 70 case Result.map2 Utils.Date.timeDifference startsAt endsAt of 71 Ok duration -> 72 case Utils.Date.durationFormat duration of 73 Just value -> 74 value 75 76 Nothing -> 77 form.duration.value 78 79 Err _ -> 80 form.duration.value 81 in 82 { form 83 | endsAt = updateValue time form.endsAt 84 , duration = updateValue durationValue form.duration 85 } 86 87 UpdateDuration time -> 88 let 89 duration = 90 Utils.Date.parseDuration time 91 92 startsAt = 93 Utils.Date.timeFromString form.startsAt.value 94 95 endsAtValue = 96 case Result.map2 Utils.Date.addDuration duration startsAt of 97 Ok endsAt -> 98 Utils.Date.timeToString endsAt 99 100 Err _ -> 101 form.endsAt.value 102 in 103 { form 104 | endsAt = updateValue endsAtValue form.endsAt 105 , duration = updateValue time form.duration 106 } 107 108 ValidateTime -> 109 { form 110 | startsAt = validate Utils.Date.timeFromString form.startsAt 111 , endsAt = validate (parseEndsAt form.startsAt.value) form.endsAt 112 , duration = validate Utils.Date.parseDuration form.duration 113 } 114 115 UpdateCreatedBy createdBy -> 116 { form | createdBy = updateValue createdBy form.createdBy } 117 118 ValidateCreatedBy -> 119 { form | createdBy = validate stringNotEmpty form.createdBy } 120 121 UpdateComment comment -> 122 { form | comment = updateValue comment form.comment } 123 124 ValidateComment -> 125 { form | comment = validate stringNotEmpty form.comment } 126 127 DeleteMatcher index -> 128 { form | matchers = List.take index form.matchers ++ List.drop (index + 1) form.matchers } 129 130 UpdateMatcherName index name -> 131 let 132 matchers = 133 Utils.List.replaceIndex index 134 (\matcher -> { matcher | name = updateValue name matcher.name }) 135 form.matchers 136 in 137 { form | matchers = matchers } 138 139 ValidateMatcherName index -> 140 let 141 matchers = 142 Utils.List.replaceIndex index 143 (\matcher -> { matcher | name = validate stringNotEmpty matcher.name }) 144 form.matchers 145 in 146 { form | matchers = matchers } 147 148 UpdateMatcherValue index value -> 149 let 150 matchers = 151 Utils.List.replaceIndex index 152 (\matcher -> { matcher | value = updateValue value matcher.value }) 153 form.matchers 154 in 155 { form | matchers = matchers } 156 157 ValidateMatcherValue index -> 158 let 159 matchers = 160 Utils.List.replaceIndex index 161 (\matcher -> { matcher | value = matcher.value }) 162 form.matchers 163 in 164 { form | matchers = matchers } 165 166 UpdateMatcherRegex index isRegex -> 167 let 168 matchers = 169 Utils.List.replaceIndex index 170 (\matcher -> { matcher | isRegex = isRegex }) 171 form.matchers 172 in 173 { form | matchers = matchers } 174 175 176update : SilenceFormMsg -> Model -> String -> String -> ( Model, Cmd Msg ) 177update msg model basePath apiUrl = 178 case msg of 179 CreateSilence -> 180 case toSilence model.form of 181 Just silence -> 182 ( { model | silenceId = Loading } 183 , Cmd.batch 184 [ Silences.Api.create apiUrl silence |> Cmd.map (SilenceCreate >> MsgForSilenceForm) 185 , persistDefaultCreator silence.createdBy 186 , Task.succeed silence.createdBy |> Task.perform SetDefaultCreator 187 ] 188 ) 189 190 Nothing -> 191 ( { model 192 | silenceId = Failure "Could not submit the form, Silence is not yet valid." 193 , form = validateForm model.form 194 } 195 , Cmd.none 196 ) 197 198 SilenceCreate silenceId -> 199 let 200 cmd = 201 case silenceId of 202 Success id -> 203 Navigation.pushUrl model.key (basePath ++ "#/silences/" ++ id) 204 205 _ -> 206 Cmd.none 207 in 208 ( { model | silenceId = silenceId }, cmd ) 209 210 NewSilenceFromMatchersAndComment defaultCreator params -> 211 ( model, Task.perform (NewSilenceFromMatchersAndCommentAndTime defaultCreator params.matchers params.comment >> MsgForSilenceForm) Time.now ) 212 213 NewSilenceFromMatchersAndCommentAndTime defaultCreator matchers comment time -> 214 ( { form = fromMatchersAndCommentAndTime defaultCreator matchers comment time 215 , alerts = Initial 216 , activeAlertId = Nothing 217 , silenceId = Initial 218 , key = model.key 219 } 220 , Cmd.none 221 ) 222 223 FetchSilence silenceId -> 224 ( model, Silences.Api.getSilence apiUrl silenceId (SilenceFetch >> MsgForSilenceForm) ) 225 226 SilenceFetch (Success silence) -> 227 ( { model | form = fromSilence silence } 228 , Task.perform identity (Task.succeed (MsgForSilenceForm PreviewSilence)) 229 ) 230 231 SilenceFetch _ -> 232 ( model, Cmd.none ) 233 234 PreviewSilence -> 235 case toSilence model.form of 236 Just silence -> 237 ( { model | alerts = Loading } 238 , Alerts.Api.fetchAlerts 239 apiUrl 240 (silencePreviewFilter silence.matchers) 241 |> Cmd.map (AlertGroupsPreview >> MsgForSilenceForm) 242 ) 243 244 Nothing -> 245 ( { model 246 | alerts = Failure "Can not display affected Alerts, Silence is not yet valid." 247 , form = validateForm model.form 248 } 249 , Cmd.none 250 ) 251 252 AlertGroupsPreview alerts -> 253 ( { model | alerts = alerts } 254 , Cmd.none 255 ) 256 257 SetActiveAlert maybeAlertId -> 258 ( { model | activeAlertId = maybeAlertId } 259 , Cmd.none 260 ) 261 262 UpdateField fieldMsg -> 263 ( { form = updateForm fieldMsg model.form 264 , alerts = Initial 265 , silenceId = Initial 266 , key = model.key 267 , activeAlertId = model.activeAlertId 268 } 269 , Cmd.none 270 ) 271 272 273port persistDefaultCreator : String -> Cmd msg 274