From 519859c1b8f09d496513e94a87268545e2dd9d82 Mon Sep 17 00:00:00 2001 From: davidvader Date: Tue, 31 Oct 2023 12:34:41 -0500 Subject: [PATCH] enhance: rotate graph orientation button --- src/elm/Main.elm | 25 ++++++++++++++++++ src/elm/Pages/Build/Graph/DOT.elm | 41 ++++++++++++++++++------------ src/elm/Pages/Build/Graph/View.elm | 23 ++++++++++++++++- src/elm/Pages/Build/Model.elm | 1 + src/elm/Vela.elm | 4 ++- src/scss/_graph.scss | 4 +++ src/static/index.ts | 2 +- 7 files changed, 81 insertions(+), 19 deletions(-) diff --git a/src/elm/Main.elm b/src/elm/Main.elm index 50ac58bde..a0b8fc5c3 100644 --- a/src/elm/Main.elm +++ b/src/elm/Main.elm @@ -241,6 +241,7 @@ import Vela , updateRepoModels , updateRepoTimeout ) +import Visualization.DOT as DOT @@ -418,6 +419,7 @@ type Msg | BuildGraphShowServices Bool | BuildGraphShowSteps Bool | BuildGraphRefresh Org Repo BuildNumber + | BuildGraphRotate | BuildGraphUpdateFilter String | OnBuildGraphInteraction GraphInteraction -- Outgoing HTTP requests @@ -975,6 +977,28 @@ update msg model = , getBuildGraph um_ org repo buildNumber True ) + BuildGraphRotate -> + let + orientation = + case gm.orientation of + DOT.LR -> + DOT.TB + + _ -> + DOT.LR + + ugm = + { gm + | orientation = orientation + } + + um_ = + updateRepoModels model rm bm ugm + in + ( um_ + , renderBuildGraph um_ False + ) + BuildGraphUpdateFilter filter -> let ugm = @@ -4840,6 +4864,7 @@ buildMsgs = } , buildGraphMsgs = { refresh = BuildGraphRefresh + , rotate = BuildGraphRotate , showServices = BuildGraphShowServices , showSteps = BuildGraphShowSteps , updateFilter = BuildGraphUpdateFilter diff --git a/src/elm/Pages/Build/Graph/DOT.elm b/src/elm/Pages/Build/Graph/DOT.elm index 83aaf0dd0..11c0841a2 100644 --- a/src/elm/Pages/Build/Graph/DOT.elm +++ b/src/elm/Pages/Build/Graph/DOT.elm @@ -134,22 +134,31 @@ renderDOT model repo build buildGraph = else "" - in - digraph baseGraphStyles - [ "" - -- pipeline (stages, steps) subgraph and cluster - , pipelineSubgraph - , "" + -- reverse the subgraphs for top-bottom orientation to consistently group services and built-ins + rotation = + case model.repo.build.graph.orientation of + TB -> + List.reverse - -- built-in (init, clone) subgraph and cluster - , builtInSubgraph - , "" + _ -> + identity - -- services subgraph and cluster - , serviceSubgraph - , "" - ] + subgraphs = + [ -- pipeline (stages, steps) subgraph and cluster + pipelineSubgraph + , "" + + -- built-in (init, clone) subgraph and cluster + , builtInSubgraph + , "" + + -- services subgraph and cluster + , serviceSubgraph + ] + in + digraph (baseGraphStyles model.repo.build.graph.orientation) + (rotation subgraphs) {-| nodeLabel : takes model, graph info, a node, and returns a string representation of the "label" applied to a node element. @@ -286,9 +295,9 @@ edgeToString edge = {-| baseGraphStyles : returns the base styles applied to the root graph. -} -baseGraphStyles : Styles -baseGraphStyles = - { rankdir = LR +baseGraphStyles : Rankdir -> Styles +baseGraphStyles orientation = + { rankdir = orientation , graph = escapeAttributes [ ( "bgcolor", DefaultEscape "transparent" ) diff --git a/src/elm/Pages/Build/Graph/View.elm b/src/elm/Pages/Build/Graph/View.elm index 22165d087..550041a9b 100644 --- a/src/elm/Pages/Build/Graph/View.elm +++ b/src/elm/Pages/Build/Graph/View.elm @@ -12,7 +12,7 @@ import Svg.Attributes import SvgBuilder exposing (buildVizLegendEdge, buildVizLegendNode) import Util import Vela exposing (BuildNumber, Org, Repo) -import Visualization.DOT exposing (Attribute(..), AttributeValue(..)) +import Visualization.DOT as DOT exposing (Attribute(..), AttributeValue(..)) @@ -48,6 +48,27 @@ view model msgs org repo buildNumber = |> FeatherIcons.toHtml [] ] ] + , li [] + [ button + [ class "button" + , class "-icon" + , class "build-graph-action-rotate" + , class <| + case model.repo.build.graph.orientation of + DOT.TB -> + "-vertical" + + _ -> + "" + , Html.Attributes.title "Rotate visualization" + , onClick <| msgs.buildGraphMsgs.rotate + ] + [ FeatherIcons.share2 + |> FeatherIcons.withSize 20 + |> FeatherIcons.withClass "elm-build-graph-action-button" + |> FeatherIcons.toHtml [] + ] + ] ] , div [ class "elm-build-graph-action-toggles" ] [ div [ class "form-control" ] diff --git a/src/elm/Pages/Build/Model.elm b/src/elm/Pages/Build/Model.elm index cf6244de3..f45189168 100644 --- a/src/elm/Pages/Build/Model.elm +++ b/src/elm/Pages/Build/Model.elm @@ -76,6 +76,7 @@ type alias LogsMsgs msg = type alias BuildGraphMsgs msg = { refresh : Org -> Repo -> BuildNumber -> msg + , rotate : msg , showServices : Bool -> msg , showSteps : Bool -> msg , updateFilter : String -> msg diff --git a/src/elm/Vela.elm b/src/elm/Vela.elm index 86f30ccd5..00f858cf8 100644 --- a/src/elm/Vela.elm +++ b/src/elm/Vela.elm @@ -193,6 +193,7 @@ import Json.Encode as Encode exposing (Value) import LinkHeader exposing (WebLink) import RemoteData exposing (RemoteData(..), WebData) import Url.Builder as UB +import Visualization.DOT as DOT @@ -1380,7 +1381,7 @@ decodeBuild = defaultBuildGraphModel : BuildGraphModel defaultBuildGraphModel = - BuildGraphModel "" NotAsked "" -1 True True + BuildGraphModel "" NotAsked DOT.LR "" -1 True True defaultBuildGraph : BuildGraph @@ -1415,6 +1416,7 @@ type alias BuildGraphRenderInteropData = type alias BuildGraphModel = { buildNumber : BuildNumber , graph : WebData BuildGraph + , orientation : DOT.Rankdir , filter : String , focusedNode : Int , showServices : Bool diff --git a/src/scss/_graph.scss b/src/scss/_graph.scss index 67365e7a1..577f41eaa 100644 --- a/src/scss/_graph.scss +++ b/src/scss/_graph.scss @@ -48,6 +48,10 @@ transform: rotate(0.2turn); } +.build-graph-action-rotate.-vertical svg { + transform: rotate(0.25turn); +} + .elm-build-graph-window { position: relative; diff --git a/src/static/index.ts b/src/static/index.ts index 4cabff514..8774ebd7d 100644 --- a/src/static/index.ts +++ b/src/static/index.ts @@ -152,7 +152,7 @@ app.ports.renderBuildGraph.subscribe(function (graphData) { opts.onGraphInteraction = app.ports.onGraphInteraction; - // dispatch the draw command to avoid elm/js rendering order issues + // dispatch the draw command to avoid elm/js rendering race condition setTimeout(() => { Graph.drawGraph(opts, content); }, 0);