Skip to content

Commit 7f170ba

Browse files
committedMar 16, 2018
Added UI changes
Validation for frontend for Numeric types
1 parent 68ecdf3 commit 7f170ba

File tree

5 files changed

+213
-117
lines changed

5 files changed

+213
-117
lines changed
 

‎.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
target/
2+
.idea/
23

34
# Artifacts from building docker distributions
45
/docker/test/cluster-broccoli-dist/

‎server/src/main/scala/de/frosner/broccoli/models/ParameterType.scala

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import scala.collection.immutable
77
sealed trait ParameterType extends EnumEntry with EnumEntry.Lowercase
88

99
object ParameterType extends Enum[ParameterType] with PlayJsonEnum[ParameterType] {
10-
val a: Boolean = true
1110
val values: immutable.IndexedSeq[ParameterType] = findValues
1211
case object Raw extends ParameterType
1312
case object String extends ParameterType

‎webui/.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,6 @@
44
# Webpack build artifacts
55
/dist/
66

7+
*.log
8+
79
/node_modules/

‎webui/src/Models/Resources/Template.elm

+18-1
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,17 @@ type alias Template =
1616
, parameterInfos : Dict String ParameterInfo
1717
}
1818

19+
-- We add Param at the end to avoid conflict with traditional data types
20+
type DataType = StringParam | NumericParam | RawParam
21+
1922

2023
type alias ParameterInfo =
2124
{ id : String
2225
, name : Maybe String
2326
, default : Maybe String
2427
, secret : Maybe Bool
2528
, orderIndex : Maybe Float
29+
, dataType: Maybe DataType
2630
}
2731

2832

@@ -40,9 +44,22 @@ decoder =
4044

4145

4246
parameterInfoDecoder =
43-
Decode.map5 ParameterInfo
47+
Decode.map6 ParameterInfo
4448
(field "id" Decode.string)
4549
(Decode.maybe (field "name" Decode.string))
4650
(Decode.maybe (field "default" Decode.string))
4751
(Decode.maybe (field "secret" Decode.bool))
4852
(Decode.maybe (field "orderIndex" Decode.float))
53+
(Decode.maybe (field "type" decodeDataType))
54+
55+
56+
decodeDataType: Decode.Decoder DataType
57+
decodeDataType =
58+
Decode.string
59+
|> Decode.andThen (\dataType ->
60+
case dataType of
61+
"numeric" -> Decode.succeed NumericParam
62+
"string" -> Decode.succeed StringParam
63+
"raw" -> Decode.succeed RawParam
64+
_ -> Decode.fail <| "Unknown dataType: " ++ dataType
65+
)

‎webui/src/Views/ParameterFormView.elm

+192-115
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import Set exposing (Set)
1616
import Maybe
1717
import Maybe.Extra exposing (isJust, join)
1818
import Json.Decode
19+
import Regex exposing (contains, regex)
1920

2021

2122
editingParamColor =
@@ -223,6 +224,24 @@ editParameterValueView instance parameterValues parameterInfos maybeInstancePara
223224
( Nothing, Just (Just original) ) ->
224225
original
225226

227+
dataType =
228+
maybeParameterInfo
229+
|> Maybe.andThen (\i -> i.dataType)
230+
|> Maybe.withDefault RawParam
231+
232+
maybeErrMsg =
233+
case maybeEditedValue of
234+
Just value ->
235+
if String.isEmpty value then
236+
Nothing -- In this case the default value gets picked up
237+
else getErrorMsg value dataType
238+
Nothing -> Nothing
239+
240+
hasError =
241+
case maybeErrMsg of
242+
Nothing -> False
243+
Just _ -> True
244+
226245
isSecret =
227246
maybeParameterInfo
228247
|> Maybe.andThen (\i -> i.secret)
@@ -238,69 +257,83 @@ editParameterValueView instance parameterValues parameterInfos maybeInstancePara
238257
in
239258
p
240259
[]
241-
[ div
242-
[ class "input-group" ]
243-
(List.append
244-
[ span
245-
[ class "input-group-addon"
246-
, style
247-
[ ( "background-color", Maybe.withDefault normalParamColor (Maybe.map (\v -> editingParamColor) maybeEditedValue) )
248-
]
249-
]
250-
[ text parameterName ]
251-
, input
252-
[ type_
253-
(if (isSecret && (not secretVisible)) then
254-
"password"
255-
else
256-
"text"
257-
)
258-
, class "form-control"
259-
, attribute "aria-label" parameter
260-
, placeholder placeholderValue
261-
, value parameterValue
262-
, disabled (not enabled)
263-
, onInput (EnterEditInstanceParameterValue instance parameter)
264-
]
265-
[]
260+
(List.append
261+
[ div
262+
[ classList [
263+
("input-group", True),
264+
("has-error", hasError)
265+
]
266266
]
267-
(if (isSecret && enabled) then
268-
[ a
267+
(List.append
268+
[ span
269269
[ class "input-group-addon"
270-
, attribute "role" "button"
271-
, onClick (ToggleEditInstanceSecretVisibility instance.id parameter)
270+
, style
271+
[ ( "background-color", Maybe.withDefault normalParamColor (Maybe.map (\v -> editingParamColor) maybeEditedValue) )
272+
]
272273
]
273-
[ icon
274-
(String.concat
275-
[ "glyphicon glyphicon-eye-"
276-
, (if secretVisible then
277-
"close"
278-
else
279-
"open"
280-
)
281-
]
274+
[ text parameterName ]
275+
, input
276+
[ type_
277+
(if (isSecret && (not secretVisible)) then
278+
"password"
279+
else
280+
"text"
282281
)
283-
[]
282+
, class "form-control"
283+
, attribute "aria-label" parameter
284+
, placeholder placeholderValue
285+
, value parameterValue
286+
, disabled (not enabled)
287+
, onInput (EnterEditInstanceParameterValue instance parameter)
284288
]
285-
, a
286-
[ class "input-group-addon"
287-
, attribute "role" "button"
288-
, attribute
289-
"onclick"
290-
(String.concat
291-
[ "copy('"
292-
, parameterValue
293-
, "')"
294-
]
295-
)
296-
]
297-
[ icon "glyphicon glyphicon-copy" [] ]
289+
[]
298290
]
299-
else
300-
[]
291+
(if (isSecret && enabled) then
292+
[ a
293+
[ class "input-group-addon"
294+
, attribute "role" "button"
295+
, onClick (ToggleEditInstanceSecretVisibility instance.id parameter)
296+
]
297+
[ icon
298+
(String.concat
299+
[ "glyphicon glyphicon-eye-"
300+
, (if secretVisible then
301+
"close"
302+
else
303+
"open"
304+
)
305+
]
306+
)
307+
[]
308+
]
309+
, a
310+
[ class "input-group-addon"
311+
, attribute "role" "button"
312+
, attribute
313+
"onclick"
314+
(String.concat
315+
[ "copy('"
316+
, parameterValue
317+
, "')"
318+
]
319+
)
320+
]
321+
[ icon "glyphicon glyphicon-copy" [] ]
322+
]
323+
else
324+
[]
325+
)
301326
)
302-
)
303-
]
327+
]
328+
(case maybeErrMsg of
329+
Nothing -> []
330+
Just msg ->
331+
[span
332+
[class "help-block"]
333+
[text msg]
334+
]
335+
)
336+
)
304337

305338

306339
newView template maybeInstanceParameterForm visibleSecrets =
@@ -404,6 +437,11 @@ newParameterValueView template parameterInfos maybeInstanceParameterForm enabled
404437
maybeEditedValue
405438
|> Maybe.withDefault ""
406439

440+
dataType =
441+
maybeParameterInfo
442+
|> Maybe.andThen (\i -> i.dataType)
443+
|> Maybe.withDefault RawParam
444+
407445
isSecret =
408446
maybeParameterInfo
409447
|> Maybe.andThen (\i -> i.secret)
@@ -416,73 +454,112 @@ newParameterValueView template parameterInfos maybeInstanceParameterForm enabled
416454
maybeParameterInfo
417455
|> Maybe.andThen (\i -> i.name)
418456
|> Maybe.withDefault parameter
457+
458+
maybeErrMsg =
459+
case maybeEditedValue of
460+
Just value ->
461+
if String.isEmpty value then
462+
Nothing -- In this case the default value gets picked up
463+
else getErrorMsg value dataType
464+
Nothing -> Nothing
465+
466+
hasError =
467+
case maybeErrMsg of
468+
Nothing -> False
469+
Just _ -> True
419470
in
420471
p
421472
[]
422-
[ div
423-
[ class "input-group"
424-
, id <| String.concat [ "new-instance-form-input-group-", template.id, "-", parameter ]
425-
]
426-
(List.append
427-
[ span
428-
[ class "input-group-addon"
429-
, style
430-
[ ( "background-color", Maybe.withDefault normalParamColor (Maybe.map (\v -> editingParamColor) maybeEditedValue) )
431-
]
432-
]
433-
[ text parameterName ]
434-
, input
435-
[ type_
436-
(if (isSecret && (not secretVisible)) then
437-
"password"
438-
else
439-
"text"
440-
)
441-
, class "form-control"
442-
, attribute "aria-label" parameter
443-
, placeholder placeholderValue
444-
, value parameterValue
445-
, disabled (not enabled)
446-
, id <| String.concat [ "new-instance-form-parameter-input-", template.id, "-", parameter ]
447-
, onInput (EnterNewInstanceParameterValue template.id parameter)
473+
(List.append
474+
[ div
475+
[ classList [
476+
("input-group", True),
477+
("has-error", hasError)
448478
]
449-
[]
479+
, id <| String.concat [ "new-instance-form-input-group-", template.id, "-", parameter ]
450480
]
451-
(if (isSecret) then
452-
[ a
481+
(List.append
482+
[ span
453483
[ class "input-group-addon"
454-
, attribute "role" "button"
455-
, onClick (ToggleNewInstanceSecretVisibility template.id parameter)
456-
, id <| String.concat [ "new-instance-form-parameter-secret-visibility-", template.id, "-", parameter ]
484+
, style
485+
[ ( "background-color", Maybe.withDefault normalParamColor (Maybe.map (\v -> editingParamColor) maybeEditedValue) )
486+
]
457487
]
458-
[ icon
459-
(String.concat
460-
[ "glyphicon glyphicon-eye-"
461-
, (if secretVisible then
462-
"close"
463-
else
464-
"open"
465-
)
466-
]
488+
[ text parameterName ]
489+
, input
490+
[ type_
491+
(if (isSecret && (not secretVisible)) then
492+
"password"
493+
else
494+
"text"
467495
)
468-
[]
496+
, class "form-control"
497+
, attribute "aria-label" parameter
498+
, placeholder placeholderValue
499+
, value parameterValue
500+
, disabled (not enabled)
501+
, id <| String.concat [ "new-instance-form-parameter-input-", template.id, "-", parameter ]
502+
, onInput (EnterNewInstanceParameterValue template.id parameter)
469503
]
470-
, a
471-
[ class "input-group-addon"
472-
, attribute "role" "button"
473-
, attribute
474-
"onclick"
475-
(String.concat
476-
[ "copy('"
477-
, parameterValue
478-
, "')"
479-
]
480-
)
481-
]
482-
[ icon "glyphicon glyphicon-copy" [] ]
504+
[]
483505
]
484-
else
485-
[]
506+
(if (isSecret) then
507+
[ a
508+
[ class "input-group-addon"
509+
, attribute "role" "button"
510+
, onClick (ToggleNewInstanceSecretVisibility template.id parameter)
511+
, id <| String.concat [ "new-instance-form-parameter-secret-visibility-", template.id, "-", parameter ]
512+
]
513+
[ icon
514+
(String.concat
515+
[ "glyphicon glyphicon-eye-"
516+
, (if secretVisible then
517+
"close"
518+
else
519+
"open"
520+
)
521+
]
522+
)
523+
[]
524+
]
525+
, a
526+
[ class "input-group-addon"
527+
, attribute "role" "button"
528+
, attribute
529+
"onclick"
530+
(String.concat
531+
[ "copy('"
532+
, parameterValue
533+
, "')"
534+
]
535+
)
536+
]
537+
[ icon "glyphicon glyphicon-copy" [] ]
538+
]
539+
else
540+
[]
541+
)
486542
)
487-
)
488-
]
543+
]
544+
(case maybeErrMsg of
545+
Nothing -> []
546+
Just msg ->
547+
[span
548+
[class "help-block"]
549+
[text msg]
550+
]
551+
)
552+
)
553+
554+
getErrorMsg: String -> DataType -> Maybe String
555+
getErrorMsg value dataType =
556+
case dataType of
557+
-- we do not validate string and raw fields
558+
StringParam -> Nothing
559+
RawParam -> Nothing
560+
NumericParam ->
561+
let
562+
expr = regex "^-?[0-9]+(\\.[0-9]+)?$"
563+
in
564+
if (contains expr value) then Nothing
565+
else Just "Not a valid number"

0 commit comments

Comments
 (0)
Please sign in to comment.