Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #26153: Add a user interface for managing method/block loops in the techniques editor #6119

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 7 additions & 10 deletions webapp/sources/rudder/rudder-web/src/main/elm/sources/Editor.elm
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,8 @@ subscriptions model =
)
]


defaultMethodUiInfo =
MethodCallUiInfo Closed CallParameters Unchanged
MethodCallUiInfo Closed CallParameters Unchanged (NewForeach "" Dict.empty "")
defaultBlockUiInfo =
MethodBlockUiInfo Closed Children Unchanged False

Expand Down Expand Up @@ -425,7 +424,7 @@ update msg model =
updateCallUi = \optCui ->
let
b = case optCui of
Nothing -> MethodCallUiInfo Closed CallParameters Unchanged
Nothing -> defaultMethodUiInfo
Just cui -> cui


Expand Down Expand Up @@ -586,7 +585,7 @@ update msg model =
if model.hasWriteRights then
let
disableReporting = False
newCall = MethodCall newId method.id (List.map (\p -> CallParameter p.name [Value ""]) method.parameters) (Condition Nothing "") "" disableReporting Nothing
newCall = MethodCall newId method.id (List.map (\p -> CallParameter p.name [Value ""]) method.parameters) (Condition Nothing "") "" disableReporting Nothing Nothing Nothing
newModel =
case model.mode of
TechniqueDetails t o ui editInfo ->
Expand All @@ -604,7 +603,7 @@ update msg model =
AddBlock newId ->
if model.hasWriteRights then
let
newCall = MethodBlock newId "" (Condition Nothing "") WeightedReport [] Nothing
newCall = MethodBlock newId "" (Condition Nothing "") WeightedReport [] Nothing Nothing Nothing
newModel =
case model.mode of
TechniqueDetails t o ui editInfo ->
Expand Down Expand Up @@ -731,7 +730,6 @@ update msg model =
h :: t ->
update h {newModel | recClone = t}


MethodCallModified method ->
case model.mode of
TechniqueDetails t s ui editInfo ->
Expand All @@ -752,7 +750,6 @@ update msg model =
updatedStoreTechnique newModel
_ -> (model,Cmd.none)


MethodCallParameterModified call paramId newValue ->
let
newModel =
Expand All @@ -768,7 +765,7 @@ update msg model =
updateCallUi = \optCui ->
let
base = case optCui of
Nothing -> MethodCallUiInfo Closed CallParameters Unchanged
Nothing -> defaultMethodUiInfo
Just cui -> cui
filterValidation = case base.validation of
InvalidState err -> let
Expand Down Expand Up @@ -816,12 +813,12 @@ update msg model =
(baseCalls, newElem) =
case draggedItemId of
Move b -> ( removeElem (getId >> (==) (getId b)) t.elems, b)
NewBlock -> (t.elems, Block Nothing (MethodBlock (CallId "") "" (Condition Nothing "") WeightedReport [] Nothing))
NewBlock -> (t.elems, Block Nothing (MethodBlock (CallId "") "" (Condition Nothing "") WeightedReport [] Nothing Nothing Nothing))
NewMethod method ->
let
disableReporting = False
in
(t.elems, Call Nothing (MethodCall (CallId "") method.id (List.map (\p -> CallParameter p.name [Value ""]) method.parameters) (Condition Nothing "") "" disableReporting Nothing))
(t.elems, Call Nothing (MethodCall (CallId "") method.id (List.map (\p -> CallParameter p.name [Value ""]) method.parameters) (Condition Nothing "") "" disableReporting Nothing Nothing Nothing))
updatedCalls =
case dropTarget of
StartList ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,16 @@ type ReportingLogic = WorstReport WorstReportKind | WeightedReport | FocusReport

type PolicyMode = Audit | Enforce


type alias MethodBlock =
{ id : CallId
, component : String
, condition : Condition
, reportingLogic : ReportingLogic
, calls : List MethodElem
, policyMode : Maybe PolicyMode
, foreachName : Maybe String
, foreach : Maybe (Dict String (List String))
}

type alias MethodCall =
Expand All @@ -113,6 +116,14 @@ type alias MethodCall =
, component : String
, disableReporting : Bool
, policyMode : Maybe PolicyMode
, foreachName : Maybe String
, foreach : Maybe (Dict String (List String))
}

type alias NewForeach =
{ foreachName : String
, foreach : Dict String (List String)
, newKey : String
}

type alias CallParameter =
Expand Down Expand Up @@ -198,7 +209,6 @@ type alias TreeFilters =
, folded : List String
}


type MethodFilterState = FilterOpened | FilterClosed
type ValidationState error = Unchanged | ValidState | InvalidState (List error)
type TechniqueNameError = EmptyName | AlreadyTakenName
Expand All @@ -211,7 +221,9 @@ type alias MethodCallUiInfo =
{ mode : MethodCallMode
, tab : MethodCallTab
, validation : ValidationState MethodCallParamError
, newForeach : NewForeach
}

type alias MethodBlockUiInfo =
{ mode : MethodCallMode
, tab : MethodBlockTab
Expand All @@ -236,7 +248,7 @@ type alias TechniqueEditInfo =
, result : Result String ()
}

type MethodCallTab = CallParameters | CallConditions | Result | CallReporting
type MethodCallTab = CallParameters | CallConditions | Result | CallReporting | ForEach
type MethodBlockTab = BlockConditions | BlockReporting | Children
type MethodCallMode = Opened | Closed
type Tab = General | Parameters | Resources | Output | None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Json.Decode exposing (..)
import Json.Decode.Pipeline exposing (..)
import List exposing (drop, head)
import String exposing (join, split)

import Dict
import Editor.AgentValueParser exposing (..)
import Editor.DataTypes exposing (..)
import Editor.MethodConditions exposing (..)
Expand Down Expand Up @@ -96,6 +96,8 @@ decodeBlock =
|> required "reportingLogic" decodeCompositionRule
|> required "calls" (list (lazy (\_ -> decodeMethodElem Nothing)))
|> optional "policyMode" (maybe decodePolicyMode) Nothing
|> optional "foreachName" (maybe string) Nothing
|> hardcoded Nothing
>> map (\block -> { block | calls = List.map (\x ->
case x of
Block _ b -> Block (Just block.id) b
Expand All @@ -113,6 +115,8 @@ decodeMethodCall =
|> optional "component" string ""
|> optional "disabledReporting" bool False
|> optional "policyMode" (maybe decodePolicyMode) Nothing
|> optional "foreachName" (maybe string) Nothing
|> optional "foreach" (maybe (dict (list string))) Nothing

decodeTechniqueMaybe : Decoder (Maybe Technique)
decodeTechniqueMaybe =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module Editor.JsonEncoder exposing (..)

import Iso8601
import Json.Encode exposing (..)
import Json.Encode.Extra exposing (maybe)

import Editor.DataTypes exposing (..)
import Editor.MethodConditions exposing (..)
Expand Down Expand Up @@ -130,6 +131,7 @@ encodeMethodCall call =
, ("parameters" , object (List.map encodeCallParameters call.parameters))
, ("disabledReporting" , bool call.disableReporting)
, ("type", string "call")
, ("foreachName", maybe string call.foreachName)
]

encodeCompositionRule: ReportingLogic -> Value
Expand All @@ -155,6 +157,7 @@ encodeMethodBlock call =
, ("calls" , list encodeMethodElem call.calls)
, ("id" , string call.id.value)
, ("type", string "block")
, ("foreachName", maybe string call.foreachName)
]

encodeCallParameters: CallParameter -> (String, Value)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,7 @@ showChildren model block ui techniqueUi parentId =
(case call of
Call _ c ->
let
methodUi = Maybe.withDefault (MethodCallUiInfo Closed CallParameters Unchanged) (Dict.get c.id.value techniqueUi.callsUI)
methodUi = Maybe.withDefault (MethodCallUiInfo Closed CallParameters Unchanged (NewForeach "" Dict.empty "")) (Dict.get c.id.value techniqueUi.callsUI)
currentDragChild = case DragDrop.currentlyDraggedObject model.dnd of
Just (Move x) -> getId x == c.id
Nothing -> True
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import Dom exposing (..)
import Json.Decode
import VirtualDom

import Rules.ViewUtils exposing (onCustomClick)
import Editor.DataTypes exposing (..)
import Editor.MethodConditions exposing (..)
import Editor.MethodElemUtils exposing (..)
Expand Down Expand Up @@ -364,19 +365,142 @@ showMethodTab model method parentId call uiInfo=
]
]
]
ForEach ->
let
newForeach = uiInfo.newForeach
tabContent = case call.foreachName of
Nothing ->
let
newKeys = Dict.keys newForeach.foreach
|> List.map (\k ->
span[class "d-inline-flex align-items-center ps-2 me-2"]
[ text k
, i[ class "fa fa-times p-2 cursorPointer", onCustomClick (UIMethodAction call.id {uiInfo | newForeach = {newForeach | foreach = (Dict.remove k uiInfo.newForeach.foreach)}}) ][]
]
)
in
div[]
[ div [class "form-group col-12 col-md-6 col-lg-4 mb-3"]
[ label [for "foreachName", class "form-label"]
[ text "Foreach name"
]
, input
[ type_ "text"
, class "form-control"
, id "foreachName"
, placeholder "item"
, stopPropagationOn "mousedown" (Json.Decode.succeed (DisableDragDrop, True))
, onFocus DisableDragDrop
, value uiInfo.newForeach.foreachName
, onInput (\s -> UIMethodAction call.id {uiInfo | newForeach = {newForeach | foreachName = s}})
]
[]
]
, div [class "form-group col-12 col-md-6 col-lg-4"]
[ label [for "foreachKeys", class "form-label"]
[ text "Foreach keys"
]
, div [class "input-group"]
[ input
[ type_ "text"
, class "form-control"
, placeholder "name, version..."
, id "foreachKeys"
, stopPropagationOn "mousedown" (Json.Decode.succeed (DisableDragDrop, True))
, onFocus DisableDragDrop
, value uiInfo.newForeach.newKey
, onInput (\s -> UIMethodAction call.id {uiInfo | newForeach = {newForeach | newKey = s}})
][]
, button
[ class "btn btn-default"
, type_ "button"
, onCustomClick (UIMethodAction call.id {uiInfo | newForeach = {newForeach | newKey = "", foreach = (Dict.insert uiInfo.newForeach.newKey [] uiInfo.newForeach.foreach)}})
, disabled (String.isEmpty uiInfo.newForeach.newKey)
]
[ i[class "fa fa-plus-circle"][]
]
]
]
, div [class "col-12 col-md-6 col-lg-8 foreach-keys mt-2 mb-3"] ( newKeys )
, div []
[ button[class "btn btn-default me-3", onCustomClick (UIMethodAction call.id {uiInfo | newForeach = (NewForeach "" Dict.empty "")}) ]
[ text "Reset"
, i[class "fa fa-undo ms-1"][]
]
, button
[ class "btn btn-primary"
, disabled ((String.isEmpty uiInfo.newForeach.foreachName) || (Dict.isEmpty uiInfo.newForeach.foreach))
, onCustomClick (MethodCallModified (Call (Just call.id) {call | foreachName = Just newForeach.foreachName, foreach = Just newForeach.foreach }))
]
[ text "Add foreach"
, i[class "fa fa-check ms-1"][]
]
]
]
Just foreachName ->
let
keys = case call.foreach of
Just f -> Dict.keys f
Nothing -> []

header = keys
|> List.map (\k -> th[][text k])
in
div[]
[ div [class "row mb-3 form-group"]
[ label [for "inputEmail3", class "col-auto col-form-label"]
[ text "Foreach name: " ]
, div [class "col d-flex align-items-center"]
[ text foreachName
, i[class "fa fa-edit ms-2"][]
, i[class "fa fa-times ms-2", onCustomClick (MethodCallModified (Call (Just call.id) {call | foreachName = Nothing, foreach = Nothing }))][]
]
]
, table[class "table table-bordered table-foreach"]
[ thead[]
[ tr[] (header)
]
]
]
in
div [ class "tab-result" ]
[ tabContent
]

methodDetail: Method -> MethodCall -> Maybe CallId -> MethodCallUiInfo -> Model -> Html Msg
methodDetail method call parentId ui model =
let
activeClass = (\c -> if c == ui.tab then "active" else "" )
(nbForeach, foreachClass) = case call.foreachName of
Nothing ->
( "0"
, ""
)
Just f ->
let
nb = case call.foreach of
Just foreach -> String.fromInt (Dict.size foreach) --TODO : To improve
Nothing -> "0"
in
( nb
, " has-foreach"
)

in
div [ class "method-details" ] [
div [] [
ul [ class "tabs-list"] [
li [ class (activeClass CallParameters), stopPropagationOn "mousedown" (Json.Decode.succeed (UIMethodAction call.id {ui | tab = CallParameters}, True)) ] [text "Parameters"] -- click select param tabs, class active if selected
, li [ class (activeClass CallConditions),stopPropagationOn "mousedown" (Json.Decode.succeed (UIMethodAction call.id {ui | tab = CallConditions}, True)) ] [text "Conditions"]
, li [class (activeClass Result), stopPropagationOn "mousedown" (Json.Decode.succeed (UIMethodAction call.id {ui | tab = Result}, True))] [text "Result conditions"]
, li [class (activeClass CallReporting), stopPropagationOn "mousedown" (Json.Decode.succeed (UIMethodAction call.id {ui | tab = CallReporting}, True)) ] [text "Reporting"]
, li [ class (activeClass Result), stopPropagationOn "mousedown" (Json.Decode.succeed (UIMethodAction call.id {ui | tab = Result}, True))] [text "Result conditions"]
, li [ class (activeClass CallReporting), stopPropagationOn "mousedown" (Json.Decode.succeed (UIMethodAction call.id {ui | tab = CallReporting}, True)) ] [text "Reporting"]
, li [ class (activeClass ForEach), stopPropagationOn "mousedown" (Json.Decode.succeed (UIMethodAction call.id {ui | tab = ForEach}, True)) ]
[ text "Foreach"
, span[class ("badge" ++ foreachClass)]
[ text nbForeach
, i[class "fa fa-retweet ms-1"][]
]
]
]
, div [ class "tabs" ] [ (showMethodTab model method parentId call ui) ]
]
Expand Down Expand Up @@ -511,6 +635,36 @@ callBody model ui techniqueUi call pid =
Just Audit -> "label-audit"
Just Enforce -> "label-enforce"

appendForeachLabel =
let
nbForeach = case call.foreach of
Just foreach -> String.fromInt (Dict.size foreach) --TODO : To improve
Nothing -> "0"

labelTxt = case call.foreachName of
Nothing -> ""
Just f -> "foreach ${" ++ f ++ ".x}"

in
appendChildConditional
( element "div"
|> addClass ("gm-label rudder-label gm-foreach d-inline-flex ps-0 overflow-hidden")
|> appendChild
( element "span"
|> addClass "counter px-1 me-1"
|> appendText nbForeach
|> appendChild
( element "i"
|> addClass "fa fa-retweet"
)
)
|> appendChild
( element "span"
|> appendText labelTxt
)
)
( Maybe.Extra.isJust call.foreachName )

appendLeftLabels = appendChild
( element "div"
|> addClass ("gm-labels left")
Expand All @@ -524,6 +678,7 @@ callBody model ui techniqueUi call pid =
|> addClass ("gm-label rudder-label gm-label-name " ++ methodNameLabelClass)
|> appendText method.name
)
|> appendForeachLabel
)
appendRightLabels = appendChild
( case ui.mode of
Expand Down
Loading