open-consul/ui-v2/app/templates/components/discovery-chain.hbs

142 lines
4.5 KiB
Handlebars
Raw Normal View History

ui: Discovery Chain (#6746) * Add data layer for discovery chain (model/adapter/serializer/repo) * Add routing plus template for routing tab * Add extra deps - consul-api-double upgrade plus ngraph for graphing * Add discovery-chain and related components and helpers: 1. discovery-chain to orchestrate/view controller 2. route-card, splitter-card, resolver card to represent the 3 different node types. 3. route-match helper for easy formatting of route rules 4. dom-position to figure out where things are in order to draw lines 5. svg-curve, simple wrapper around svg's <path d=""> attribute format. 6. data-structs service. This isn't super required but we are using other data-structures provided by other third party npm modules in other yet to be merged PRs. All of these types of things will live here for easy access/injection/changability 7. Some additions to our css-var 'polyfill' for a couple of extra needed rules * Related CSS for discovery chain 1. We add a %card base component here, eventually this will go into our base folder and %stats-card will also use it for a base component. 2. New icon for failovers * ui: Discovery Chain Continued (#6939) 1. Add in the things we use for the animations 2 Use IntersectionObserver so we know when the tab is visible, otherwise the dom-position helper won't work as the dom elements don't have any display. 3. Add some base work for animations and use them a little 4. Try to detect if a resolver is a redirect. Right now this works for datacenters and namespaces, but it can't work for services and subsets - we are awaiting backend support for doing this properly. 5. Add a fake 'this service has no routes' route that says 'Default' 6. redirect icon 7. Add CSS.escape polyfill for Edge
2019-12-17 19:27:28 +00:00
{{#if isDisplayed }}
<style>
{{#if selected.nodes }}
{{selected.nodes}} {
opacity: 1 !important;
background-color: {{css-var '--white'}};
border: {{css-var '--decor-border-100'}};
border-radius: {{css-var '--decor-radius-300'}};
border-color: {{css-var '--gray-500'}};
box-shadow: 0 8px 10px 0 rgba(0, 0, 0, 0.1);
}
{{/if}}
{{#if selected.edges }}
{{selected.edges}} {
opacity: 1;
}
{{/if}}
</style>
<div class="routes">
<header>
<h2>
{{chain.ServiceName}} Router
<span>
<em role="tooltip">Use routers to intercept traffic using L7 criteria such as path prefixes or http headers.</em>
</span>
</h2>
</header>
<div role="group">
{{#each routes as |item|}}
{{route-card item=item onclick=(action 'click')}}
{{/each}}
</div>
</div>
<div class="splitters">
<header>
<h2>
Splitters
<span>
<em role="tooltip">Splitters are configured to split incoming requests across different services or subsets of a single service.</em>
</span>
</h2>
</header>
<div role="group">
{{#each (sort-by 'Name' splitters) as |item|}}
{{splitter-card item=item onclick=(action 'click')}}
{{/each}}
</div>
</div>
<div class="resolvers">
<header>
<h2>
Resolvers
<span>
<em role="tooltip">Resolvers are used to define which instances of a service should satisfy discovery requests.</em>
</span>
</h2>
</header>
<div role="group">
{{#each (sort-by 'Name' resolvers) as |item|}}
{{resolver-card item=item onclick=(action 'click')}}
{{/each}}
</div>
</div>
<svg width="100%" height="100%" viewBox={{concat '0 0 ' width ' ' height}} preserveAspectRatio="none">
{{#each routes as |item|}}
{{#let (dom-position (concat '#' item.ID)) as |src|}}
{{#let (dom-position (concat '#' item.NextNode)) as |destRect|}}
{{#let (tween-to (hash
x=destRect.x
y=(add destRect.y (div destRect.height 2))
) (concat item.ID)) as |dest|}}
<path
id={{concat item.ID '>' item.NextNode}}
d={{
svg-curve (hash
x=dest.x
y=dest.y
) src=(hash
x=(add src.x src.width)
y=(add src.y (div src.height 2))
)}} />
{{/let}}
{{/let}}
{{/let}}
{{/each}}
{{#each splitters as |splitter|}}
{{#let (dom-position (concat '#' splitter.ID)) as |src|}}
{{#each splitter.Splits as |item index|}}
{{#let (dom-position (concat '#' item.NextNode)) as |destRect|}}
{{#let (tween-to (hash
x=destRect.x
y=(add destRect.y (div destRect.height 2))
) (concat splitter.ID '-' index)) as |dest|}}
<path
id={{concat 'splitter:' splitter.Name '>' item.NextNode}}
class="split"
data-percentage={{item.Weight}}
d={{
svg-curve (hash
x=dest.x
y=dest.y
) src=(hash
x=(add src.x src.width)
y=(add src.y (div src.height 2))
)}} />
{{/let}}
{{/let}}
{{/each}}
{{/let}}
{{/each}}
</svg>
<svg class="resolver-inlets" viewBox={{concat '0 0 10 ' height}}>
{{#each routes as |item|}}
{{#if (starts-with 'resolver:' item.NextNode) }}
{{#let (dom-position (concat '#' item.NextNode)) as |dest|}}
<circle r="2.5" cx="5" cy={{add dest.y (div dest.height 2)}} />
{{/let}}
{{/if}}
{{/each}}
{{#each splitters as |item|}}
{{#each item.Splits as |item|}}
{{#let (dom-position (concat '#' item.NextNode)) as |dest|}}
<circle r="2.5" cx="5" cy={{add dest.y (div dest.height 2)}} />
{{/let}}
{{/each}}
{{/each}}
</svg>
<svg class="splitter-inlets" viewBox={{concat '0 0 10 ' height}}>
{{#each routes as |item|}}
{{#if (starts-with 'splitter:' item.NextNode) }}
{{#let (dom-position (concat '#' item.NextNode)) as |dest|}}
<circle r="2.5" cx="5" cy={{add dest.y (div dest.height 2)}} />
{{/let}}
{{/if}}
{{/each}}
</svg>
<div class={{concat 'tooltip' (if activeTooltip ' active' '')}} style={{{ concat 'position: absolute;top:' y 'px;left:' x 'px;'}}}>
<span role="tooltip">{{round tooltip decimals=2}}%</span>
</div>
{{/if}}