mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Resolver] Refactor resolver assets (#77795)
This PR splits the `assets` module into several other modules/hooks: * `calculateResolverFontSize` is now `fontSize` * `colorMap` is now `useColors` * `cubeAssetsForNow` is now `useCubeAssets` * `nodeAssets` is gone (inlined into `useCubeAssets`) The PaintServer and Symbol IDs no longer use random IDs. They are now based on the `resolverComponentInstanceID`. This sets us up to use a provider that can allow multiple resolver instances to share these assets.
This commit is contained in:
parent
3e5ae012c5
commit
cdb3c30ab9
16 changed files with 634 additions and 565 deletions
|
@ -1,521 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
/* eslint-disable react/display-name */
|
||||
|
||||
import React, { memo } from 'react';
|
||||
import euiThemeAmsterdamDark from '@elastic/eui/dist/eui_theme_amsterdam_dark.json';
|
||||
import euiThemeAmsterdamLight from '@elastic/eui/dist/eui_theme_amsterdam_light.json';
|
||||
import { htmlIdGenerator, ButtonColor } from '@elastic/eui';
|
||||
import styled from 'styled-components';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ResolverProcessType } from '../types';
|
||||
import { useUiSetting } from '../../../../../../src/plugins/kibana_react/public';
|
||||
|
||||
type ResolverColorNames =
|
||||
| 'descriptionText'
|
||||
| 'full'
|
||||
| 'graphControls'
|
||||
| 'graphControlsBackground'
|
||||
| 'resolverBackground'
|
||||
| 'resolverEdge'
|
||||
| 'resolverEdgeText'
|
||||
| 'resolverBreadcrumbBackground'
|
||||
| 'pillStroke';
|
||||
|
||||
type ColorMap = Record<ResolverColorNames, string>;
|
||||
interface NodeStyleConfig {
|
||||
backingFill: string;
|
||||
cubeSymbol: string;
|
||||
descriptionFill: string;
|
||||
descriptionText: string;
|
||||
isLabelFilled: boolean;
|
||||
labelButtonFill: ButtonColor;
|
||||
strokeColor: string;
|
||||
}
|
||||
|
||||
interface NodeStyleMap {
|
||||
runningProcessCube: NodeStyleConfig;
|
||||
runningTriggerCube: NodeStyleConfig;
|
||||
terminatedProcessCube: NodeStyleConfig;
|
||||
terminatedTriggerCube: NodeStyleConfig;
|
||||
}
|
||||
|
||||
const idGenerator = htmlIdGenerator();
|
||||
|
||||
/**
|
||||
* Ids of paint servers to be referenced by fill and stroke attributes
|
||||
*/
|
||||
const PaintServerIds = {
|
||||
runningProcessCube: idGenerator('psRunningProcessCube'),
|
||||
runningTriggerCube: idGenerator('psRunningTriggerCube'),
|
||||
terminatedProcessCube: idGenerator('psTerminatedProcessCube'),
|
||||
terminatedTriggerCube: idGenerator('psTerminatedTriggerCube'),
|
||||
};
|
||||
|
||||
/**
|
||||
* PaintServers: Where color palettes, grandients, patterns and other similar concerns
|
||||
* are exposed to the component
|
||||
*/
|
||||
|
||||
const PaintServers = memo(({ isDarkMode }: { isDarkMode: boolean }) => (
|
||||
<>
|
||||
<linearGradient
|
||||
id={PaintServerIds.runningProcessCube}
|
||||
x1="-381.23556"
|
||||
y1="264.73802"
|
||||
x2="-380.48514"
|
||||
y2="263.8816"
|
||||
gradientTransform="matrix(70.05179, 0, 0, -79.94774, 26724.01618, 21181.09848)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0.00087" stopColor="#006bb4" />
|
||||
<stop offset="1" stopColor="#54b399" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id={PaintServerIds.runningTriggerCube}
|
||||
x1="-381.18643"
|
||||
y1="264.68195"
|
||||
x2="-380.48514"
|
||||
y2="263.8816"
|
||||
gradientTransform="matrix(70.05179, 0, 0, -79.94774, 26724.01618, 21181.09848)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0" stopColor="#dd0a73" />
|
||||
<stop offset="1" stopColor="#f66" />
|
||||
</linearGradient>
|
||||
{isDarkMode ? (
|
||||
<>
|
||||
<linearGradient
|
||||
id={PaintServerIds.terminatedProcessCube}
|
||||
x1="-381.23752"
|
||||
y1="264.24026"
|
||||
x2="-380.48514"
|
||||
y2="263.3816"
|
||||
gradientTransform="matrix(70.05178, 0, 0, -79.94771, 26724.01313, 21140.72096)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0" stopColor="#4c82c3" />
|
||||
<stop offset="1" stopColor="#8bd1c7" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id={PaintServerIds.terminatedTriggerCube}
|
||||
x1="-381.18658"
|
||||
y1="264.68187"
|
||||
x2="-380.48546"
|
||||
y2="263.8817"
|
||||
gradientTransform="matrix(70.05179, 0, 0, -79.94774, 26724.01618, 21181.09848)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0" stopColor="#dd0a73" />
|
||||
<stop offset="1" stopColor="#f66" />
|
||||
</linearGradient>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<linearGradient
|
||||
id={PaintServerIds.terminatedProcessCube}
|
||||
x1="10.5206"
|
||||
y1="9.49068"
|
||||
x2="46.8141"
|
||||
y2="45.7844"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0" stopColor="#2F6EB6" />
|
||||
<stop offset="1" stopColor="#00B4AC" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id={PaintServerIds.terminatedTriggerCube}
|
||||
x1="15.4848"
|
||||
y1="12.0468"
|
||||
x2="43.1049"
|
||||
y2="47.2331"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stopColor="#DD0A73" />
|
||||
<stop offset="1" stopColor="#FF6666" />
|
||||
</linearGradient>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
));
|
||||
|
||||
/**
|
||||
* Ids of symbols to be linked by <use> elements
|
||||
*/
|
||||
export const SymbolIds = {
|
||||
processNodeLabel: idGenerator('nodeSymbol'),
|
||||
runningProcessCube: idGenerator('runningCube'),
|
||||
runningTriggerCube: idGenerator('runningTriggerCube'),
|
||||
terminatedProcessCube: idGenerator('terminatedCube'),
|
||||
terminatedTriggerCube: idGenerator('terminatedTriggerCube'),
|
||||
processCubeActiveBacking: idGenerator('activeBacking'),
|
||||
};
|
||||
|
||||
/**
|
||||
* Defs entries that define shapes, masks and other spatial elements
|
||||
*/
|
||||
const SymbolsAndShapes = memo(({ isDarkMode }: { isDarkMode: boolean }) => (
|
||||
<>
|
||||
<symbol
|
||||
id={SymbolIds.processNodeLabel}
|
||||
viewBox="0 0 144 25"
|
||||
preserveAspectRatio="xMidYMid meet"
|
||||
>
|
||||
<rect
|
||||
x="1"
|
||||
y="1"
|
||||
width="142"
|
||||
height="23"
|
||||
fill="inherit"
|
||||
strokeWidth="0"
|
||||
paintOrder="normal"
|
||||
/>
|
||||
</symbol>
|
||||
<symbol id={SymbolIds.runningProcessCube} viewBox="0 0 88 100">
|
||||
<title>{'Running Process'}</title>
|
||||
<path
|
||||
d="M87.52127,25.129a3.79536,3.79536,0,0,0-1.43184-1.47165L45.91025.57471a3.83652,3.83652,0,0,0-3.8205,0L1.91039,23.65739A3.86308,3.86308,0,0,0,0,26.95V73.11541a3.79835,3.79835,0,0,0,1.9104,3.2925L42.08975,99.49067a3.83691,3.83691,0,0,0,3.8205,0L86.08943,76.40791A3.79852,3.79852,0,0,0,88,73.11541V26.95A3.77641,3.77641,0,0,0,87.52127,25.129Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill={`url(#${PaintServerIds.runningProcessCube})`}
|
||||
/>
|
||||
<g opacity="0.5">
|
||||
<path
|
||||
d="M59.18326,40.255,44.93983,32.07224a1.7853,1.7853,0,0,0-1.77779,0L28.91861,40.255a1.77022,1.77022,0,0,0-.64527.64058L44.0088,49.96977,59.838,40.91219a1.77,1.77,0,0,0-.65469-.65719Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M59.18326,40.255,44.93983,32.07224a1.7853,1.7853,0,0,0-1.77779,0L28.91861,40.255a1.77022,1.77022,0,0,0-.64527.64058L44.0088,49.96977,59.838,40.91219a1.77,1.77,0,0,0-.65469-.65719Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#fff"
|
||||
opacity="0.2"
|
||||
style={{ isolation: 'isolate' }}
|
||||
/>
|
||||
<path
|
||||
d="M28.27334,40.89555a1.75837,1.75837,0,0,0-.24347.89149V58.1525a1.76751,1.76751,0,0,0,.88874,1.532L43.162,67.86729a1.77951,1.77951,0,0,0,.84679.2316V49.96977Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M28.27334,40.89555a1.75837,1.75837,0,0,0-.24347.89149V58.1525a1.76751,1.76751,0,0,0,.88874,1.532L43.162,67.86729a1.77951,1.77951,0,0,0,.84679.2316V49.96977Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#fff"
|
||||
opacity="0.2"
|
||||
style={{ isolation: 'isolate' }}
|
||||
/>
|
||||
<path
|
||||
d="M44.0088,68.0989a1.7772,1.7772,0,0,0,.931-.2316l14.24344-8.18274a1.76754,1.76754,0,0,0,.889-1.532V41.787a1.76037,1.76037,0,0,0-.23432-.87485L44.0088,49.96977Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M44.0088,68.0989a1.7772,1.7772,0,0,0,.931-.2316l14.24344-8.18274a1.76754,1.76754,0,0,0,.889-1.532V41.787a1.76037,1.76037,0,0,0-.23432-.87485L44.0088,49.96977Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#fff"
|
||||
opacity="0.2"
|
||||
style={{ isolation: 'isolate' }}
|
||||
/>
|
||||
</g>
|
||||
<path
|
||||
d="M.57144,24.91834a3.79909,3.79909,0,0,1,1.34825-1.32625L42.0989.50939a3.837,3.837,0,0,1,3.82081,0L86.09892,23.59206a3.79782,3.79782,0,0,1,1.4318,1.47169L44.00915,49.96733Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#fff"
|
||||
opacity="0.3"
|
||||
style={{ isolation: 'isolate' }}
|
||||
/>
|
||||
<path
|
||||
d="M43.99984,50.03265V100a3.83392,3.83392,0,0,1-1.91024-.50933L1.91039,76.40791A3.79835,3.79835,0,0,1,0,73.11541V26.95a3.77423,3.77423,0,0,1,.56216-1.96625Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#353944"
|
||||
opacity="0.2"
|
||||
style={{ isolation: 'isolate' }}
|
||||
/>
|
||||
</symbol>
|
||||
<symbol id={SymbolIds.runningTriggerCube} viewBox="0 0 88 100">
|
||||
<title>{'resolver_dark process running'}</title>
|
||||
<path
|
||||
d="M87.52127,25.129a3.79536,3.79536,0,0,0-1.43184-1.47165L45.91025.57471a3.83652,3.83652,0,0,0-3.8205,0L1.91039,23.65739A3.86308,3.86308,0,0,0,0,26.95V73.11541a3.79835,3.79835,0,0,0,1.9104,3.2925L42.08975,99.49067a3.83691,3.83691,0,0,0,3.8205,0L86.08943,76.40791A3.79852,3.79852,0,0,0,88,73.11541V26.95A3.77641,3.77641,0,0,0,87.52127,25.129Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill={`url(#${PaintServerIds.runningTriggerCube})`}
|
||||
/>
|
||||
<g opacity="0.5">
|
||||
<path
|
||||
d="M59.18326,40.255,44.93983,32.07224a1.7853,1.7853,0,0,0-1.77779,0L28.91861,40.255a1.77022,1.77022,0,0,0-.64527.64058L44.0088,49.96977,59.838,40.91219a1.77,1.77,0,0,0-.65469-.65719Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M59.18326,40.255,44.93983,32.07224a1.7853,1.7853,0,0,0-1.77779,0L28.91861,40.255a1.77022,1.77022,0,0,0-.64527.64058L44.0088,49.96977,59.838,40.91219a1.77,1.77,0,0,0-.65469-.65719Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#fff"
|
||||
opacity="0.2"
|
||||
style={{ isolation: 'isolate' }}
|
||||
/>
|
||||
<path
|
||||
d="M28.27334,40.89555a1.75837,1.75837,0,0,0-.24347.89149V58.1525a1.76751,1.76751,0,0,0,.88874,1.532L43.162,67.86729a1.77951,1.77951,0,0,0,.84679.2316V49.96977Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M28.27334,40.89555a1.75837,1.75837,0,0,0-.24347.89149V58.1525a1.76751,1.76751,0,0,0,.88874,1.532L43.162,67.86729a1.77951,1.77951,0,0,0,.84679.2316V49.96977Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#fff"
|
||||
opacity="0.2"
|
||||
style={{ isolation: 'isolate' }}
|
||||
/>
|
||||
<path
|
||||
d="M44.0088,68.0989a1.7772,1.7772,0,0,0,.931-.2316l14.24344-8.18274a1.76754,1.76754,0,0,0,.889-1.532V41.787a1.76037,1.76037,0,0,0-.23432-.87485L44.0088,49.96977Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M44.0088,68.0989a1.7772,1.7772,0,0,0,.931-.2316l14.24344-8.18274a1.76754,1.76754,0,0,0,.889-1.532V41.787a1.76037,1.76037,0,0,0-.23432-.87485L44.0088,49.96977Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#fff"
|
||||
opacity="0.2"
|
||||
style={{ isolation: 'isolate' }}
|
||||
/>
|
||||
</g>
|
||||
<path
|
||||
d="M.57144,24.91834a3.79909,3.79909,0,0,1,1.34825-1.32625L42.0989.50939a3.837,3.837,0,0,1,3.82081,0L86.09892,23.59206a3.79782,3.79782,0,0,1,1.4318,1.47169L44.00915,49.96733Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#fff"
|
||||
opacity="0.3"
|
||||
style={{ isolation: 'isolate' }}
|
||||
/>
|
||||
<path
|
||||
d="M43.99984,50.03265V100a3.83392,3.83392,0,0,1-1.91024-.50933L1.91039,76.40791A3.79835,3.79835,0,0,1,0,73.11541V26.95a3.77423,3.77423,0,0,1,.56216-1.96625Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#353944"
|
||||
opacity="0.2"
|
||||
style={{ isolation: 'isolate' }}
|
||||
/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 88 100" id={SymbolIds.terminatedProcessCube}>
|
||||
<title>{'Terminated Process'}</title>
|
||||
<path
|
||||
d="M87.52113,24.73352a3.7956,3.7956,0,0,0-1.43182-1.47166L45.91012.17918a3.8365,3.8365,0,0,0-3.82049,0L1.91029,23.26186A3.86312,3.86312,0,0,0-.00009,26.55445V72.7199a3.79834,3.79834,0,0,0,1.91041,3.29249L42.08963,99.09514a3.83689,3.83689,0,0,0,3.82049,0L86.08931,76.01239a3.79852,3.79852,0,0,0,1.91056-3.29249V26.55445A3.77643,3.77643,0,0,0,87.52113,24.73352Z"
|
||||
transform="translate(0.00013 0.39551)"
|
||||
fill={isDarkMode ? '#010101' : '#fff'}
|
||||
/>
|
||||
<g opacity="0.7">
|
||||
<path
|
||||
opacity={isDarkMode ? 1 : 0.6}
|
||||
d="M87.52113,24.73352a3.7956,3.7956,0,0,0-1.43182-1.47166L45.91012.17918a3.8365,3.8365,0,0,0-3.82049,0L1.91029,23.26186A3.86312,3.86312,0,0,0-.00009,26.55445V72.7199a3.79834,3.79834,0,0,0,1.91041,3.29249L42.08963,99.09514a3.83689,3.83689,0,0,0,3.82049,0L86.08931,76.01239a3.79852,3.79852,0,0,0,1.91056-3.29249V26.55445A3.77643,3.77643,0,0,0,87.52113,24.73352Z"
|
||||
transform="translate(0.00013 0.39551)"
|
||||
fill={`url(#${PaintServerIds.terminatedProcessCube})`}
|
||||
/>
|
||||
<path
|
||||
opacity={isDarkMode ? 0.3 : 0.4}
|
||||
d="M.57134,24.52282a3.79906,3.79906,0,0,1,1.34824-1.32625L42.09878.11387a3.83708,3.83708,0,0,1,3.8208,0L86.09877,23.19655a3.79771,3.79771,0,0,1,1.43182,1.47165L44.00909,49.57182Z"
|
||||
transform="translate(0.00013 0.39551)"
|
||||
fill="#fff"
|
||||
style={{ isolation: 'isolate' }}
|
||||
/>
|
||||
<path
|
||||
opacity={isDarkMode ? 0.2 : 0.4}
|
||||
d="M43.99972,49.63713V99.60449a3.83406,3.83406,0,0,1-1.91025-.50932L1.91029,76.01239A3.79835,3.79835,0,0,1-.00013,72.7199V26.55445A3.77431,3.77431,0,0,1,.562,24.5882Z"
|
||||
transform="translate(0.00013 0.39551)"
|
||||
fill="#353944"
|
||||
style={{ isolation: 'isolate' }}
|
||||
/>
|
||||
</g>
|
||||
</symbol>
|
||||
<symbol id={SymbolIds.terminatedTriggerCube} viewBox="0 0 88 100">
|
||||
<title>{'Terminated Trigger Process'}</title>
|
||||
{isDarkMode && (
|
||||
<path
|
||||
opacity="1"
|
||||
d="M87.52143,25.06372a3.795,3.795,0,0,0-1.43129-1.47166L45.92578.50939a3.83384,3.83384,0,0,0-3.81907,0L1.94219,23.59206A3.8634,3.8634,0,0,0,.03252,26.88465V73.05008a3.7986,3.7986,0,0,0,1.90971,3.2925L42.10671,99.42532a3.83423,3.83423,0,0,0,3.81907,0L86.09014,76.34258A3.79881,3.79881,0,0,0,88,73.05008V26.88465A3.77748,3.77748,0,0,0,87.52143,25.06372Z"
|
||||
transform="translate(0)"
|
||||
fill="#010101"
|
||||
/>
|
||||
)}
|
||||
<g opacity="0.6">
|
||||
{!isDarkMode && (
|
||||
<path
|
||||
opacity="0.6"
|
||||
d="M87.52143,25.06372a3.795,3.795,0,0,0-1.43129-1.47166L45.92578.50939a3.83384,3.83384,0,0,0-3.81907,0L1.94219,23.59206A3.8634,3.8634,0,0,0,.03252,26.88465V73.05008a3.7986,3.7986,0,0,0,1.90971,3.2925L42.10671,99.42532a3.83423,3.83423,0,0,0,3.81907,0L86.09014,76.34258A3.79881,3.79881,0,0,0,88,73.05008V26.88465A3.77748,3.77748,0,0,0,87.52143,25.06372Z"
|
||||
transform="translate(0)"
|
||||
fill="#010101"
|
||||
/>
|
||||
)}
|
||||
<path
|
||||
opacity={isDarkMode ? 1 : 0.604}
|
||||
d="M87.48893,25.129a3.79468,3.79468,0,0,0-1.4313-1.47165L45.89329.57472a3.83381,3.83381,0,0,0-3.81908,0L1.90969,23.65739A3.86331,3.86331,0,0,0,0,26.95V73.11541a3.79859,3.79859,0,0,0,1.90969,3.2925L42.07421,99.49067a3.83425,3.83425,0,0,0,3.81908,0L86.05763,76.40791a3.79876,3.79876,0,0,0,1.90985-3.2925V26.95A3.77746,3.77746,0,0,0,87.48893,25.129Z"
|
||||
transform="translate(0)"
|
||||
fill={`url(#${PaintServerIds.terminatedTriggerCube})`}
|
||||
/>
|
||||
<path
|
||||
d="M.57124,24.91834A3.79833,3.79833,0,0,1,1.919,23.59209L42.08335.50939a3.83441,3.83441,0,0,1,3.8194,0L86.06711,23.59206a3.7972,3.7972,0,0,1,1.43128,1.47169L43.99289,49.96733Z"
|
||||
transform="translate(0)"
|
||||
fill="#fff"
|
||||
opacity="0.3"
|
||||
style={{ isolation: 'isolate' }}
|
||||
/>
|
||||
<path
|
||||
d="M43.98359,50.03265V100a3.83139,3.83139,0,0,1-1.90953-.50933L1.90969,76.40791A3.79859,3.79859,0,0,1,0,73.11541V26.95a3.77523,3.77523,0,0,1,.56195-1.96625Z"
|
||||
transform="translate(0)"
|
||||
fill="#353944"
|
||||
opacity="0.2"
|
||||
style={{ isolation: 'isolate' }}
|
||||
/>
|
||||
</g>
|
||||
</symbol>
|
||||
<symbol viewBox="0 -3 88 106" id={SymbolIds.processCubeActiveBacking}>
|
||||
<title>{'resolver active backing'}</title>
|
||||
<path
|
||||
d="m87.521 25.064a3.795 3.795 0 0 0-1.4313-1.4717l-40.164-23.083a3.8338 3.8338 0 0 0-3.8191 0l-40.165 23.083a3.8634 3.8634 0 0 0-1.9097 3.2926v46.165a3.7986 3.7986 0 0 0 1.9097 3.2925l40.164 23.083a3.8342 3.8342 0 0 0 3.8191 0l40.164-23.083a3.7988 3.7988 0 0 0 1.9099-3.2925v-46.165a3.7775 3.7775 0 0 0-0.47857-1.8209z"
|
||||
strokeWidth="2"
|
||||
/>
|
||||
</symbol>
|
||||
</>
|
||||
));
|
||||
|
||||
/**
|
||||
* This `<defs>` element is used to define the reusable assets for the Resolver
|
||||
* It confers several advantages, including but not limited to:
|
||||
* 1. Freedom of form for creative assets (beyond box-model constraints)
|
||||
* 2. Separation of concerns between creative assets and more functional areas of the app
|
||||
* 3. `<use>` elements can be handled by compositor (faster)
|
||||
*/
|
||||
const SymbolDefinitionsComponent = memo(({ className }: { className?: string }) => {
|
||||
const isDarkMode = useUiSetting<boolean>('theme:darkMode');
|
||||
return (
|
||||
<svg className={className}>
|
||||
<defs>
|
||||
<PaintServers isDarkMode={isDarkMode} />
|
||||
<SymbolsAndShapes isDarkMode={isDarkMode} />
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
});
|
||||
|
||||
export const SymbolDefinitions = styled(SymbolDefinitionsComponent)`
|
||||
position: absolute;
|
||||
left: 100%;
|
||||
top: 100%;
|
||||
width: 0;
|
||||
height: 0;
|
||||
`;
|
||||
|
||||
const processTypeToCube: Record<ResolverProcessType, keyof NodeStyleMap> = {
|
||||
processCreated: 'runningProcessCube',
|
||||
processRan: 'runningProcessCube',
|
||||
processTerminated: 'terminatedProcessCube',
|
||||
unknownProcessEvent: 'runningProcessCube',
|
||||
processCausedAlert: 'runningTriggerCube',
|
||||
unknownEvent: 'runningProcessCube',
|
||||
};
|
||||
|
||||
/**
|
||||
* A hook to bring Resolver theming information into components.
|
||||
*/
|
||||
export const useResolverTheme = (): {
|
||||
colorMap: ColorMap;
|
||||
nodeAssets: NodeStyleMap;
|
||||
cubeAssetsForNode: (isProcessTerimnated: boolean, isProcessTrigger: boolean) => NodeStyleConfig;
|
||||
} => {
|
||||
const isDarkMode = useUiSetting('theme:darkMode');
|
||||
const theme = isDarkMode ? euiThemeAmsterdamDark : euiThemeAmsterdamLight;
|
||||
|
||||
const getThemedOption = (lightOption: string, darkOption: string): string => {
|
||||
return isDarkMode ? darkOption : lightOption;
|
||||
};
|
||||
|
||||
const colorMap = {
|
||||
descriptionText: theme.euiTextColor,
|
||||
full: theme.euiColorFullShade,
|
||||
graphControls: theme.euiColorDarkestShade,
|
||||
graphControlsBackground: theme.euiColorEmptyShade,
|
||||
processBackingFill: `${theme.euiColorPrimary}${getThemedOption('0F', '1F')}`, // Add opacity 0F = 6% , 1F = 12%
|
||||
resolverBackground: theme.euiColorEmptyShade,
|
||||
resolverEdge: getThemedOption(theme.euiColorLightestShade, theme.euiColorLightShade),
|
||||
resolverBreadcrumbBackground: theme.euiColorLightestShade,
|
||||
resolverEdgeText: getThemedOption(theme.euiColorDarkShade, theme.euiColorFullShade),
|
||||
triggerBackingFill: `${theme.euiColorDanger}${getThemedOption('0F', '1F')}`,
|
||||
pillStroke: theme.euiColorLightShade,
|
||||
};
|
||||
|
||||
const nodeAssets: NodeStyleMap = {
|
||||
runningProcessCube: {
|
||||
backingFill: colorMap.processBackingFill,
|
||||
cubeSymbol: `#${SymbolIds.runningProcessCube}`,
|
||||
descriptionFill: colorMap.descriptionText,
|
||||
descriptionText: i18n.translate('xpack.securitySolution.endpoint.resolver.runningProcess', {
|
||||
defaultMessage: 'Running Process',
|
||||
}),
|
||||
isLabelFilled: true,
|
||||
labelButtonFill: 'primary',
|
||||
strokeColor: theme.euiColorPrimary,
|
||||
},
|
||||
runningTriggerCube: {
|
||||
backingFill: colorMap.triggerBackingFill,
|
||||
cubeSymbol: `#${SymbolIds.runningTriggerCube}`,
|
||||
descriptionFill: colorMap.descriptionText,
|
||||
descriptionText: i18n.translate('xpack.securitySolution.endpoint.resolver.runningTrigger', {
|
||||
defaultMessage: 'Running Trigger',
|
||||
}),
|
||||
isLabelFilled: true,
|
||||
labelButtonFill: 'danger',
|
||||
strokeColor: theme.euiColorDanger,
|
||||
},
|
||||
terminatedProcessCube: {
|
||||
backingFill: colorMap.processBackingFill,
|
||||
cubeSymbol: `#${SymbolIds.terminatedProcessCube}`,
|
||||
descriptionFill: colorMap.descriptionText,
|
||||
descriptionText: i18n.translate(
|
||||
'xpack.securitySolution.endpoint.resolver.terminatedProcess',
|
||||
{
|
||||
defaultMessage: 'Terminated Process',
|
||||
}
|
||||
),
|
||||
isLabelFilled: false,
|
||||
labelButtonFill: 'primary',
|
||||
strokeColor: theme.euiColorPrimary,
|
||||
},
|
||||
terminatedTriggerCube: {
|
||||
backingFill: colorMap.triggerBackingFill,
|
||||
cubeSymbol: `#${SymbolIds.terminatedTriggerCube}`,
|
||||
descriptionFill: colorMap.descriptionText,
|
||||
descriptionText: i18n.translate(
|
||||
'xpack.securitySolution.endpoint.resolver.terminatedTrigger',
|
||||
{
|
||||
defaultMessage: 'Terminated Trigger',
|
||||
}
|
||||
),
|
||||
isLabelFilled: false,
|
||||
labelButtonFill: 'danger',
|
||||
strokeColor: theme.euiColorDanger,
|
||||
},
|
||||
};
|
||||
|
||||
function cubeAssetsForNode(isProcessTerminated: boolean, isProcessTrigger: boolean) {
|
||||
if (isProcessTerminated) {
|
||||
if (isProcessTrigger) {
|
||||
return nodeAssets.terminatedTriggerCube;
|
||||
} else {
|
||||
return nodeAssets[processTypeToCube.processTerminated];
|
||||
}
|
||||
} else if (isProcessTrigger) {
|
||||
return nodeAssets[processTypeToCube.processCausedAlert];
|
||||
} else {
|
||||
return nodeAssets[processTypeToCube.processRan];
|
||||
}
|
||||
}
|
||||
|
||||
return { colorMap, nodeAssets, cubeAssetsForNode };
|
||||
};
|
||||
|
||||
export const calculateResolverFontSize = (
|
||||
magFactorX: number,
|
||||
minFontSize: number,
|
||||
slopeOfFontScale: number
|
||||
): number => {
|
||||
const fontSizeAdjustmentForScale = magFactorX > 1 ? slopeOfFontScale * (magFactorX - 1) : 0;
|
||||
return minFontSize + fontSizeAdjustmentForScale;
|
||||
};
|
|
@ -9,7 +9,8 @@ import styled from 'styled-components';
|
|||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { applyMatrix3, distance, angle } from '../models/vector2';
|
||||
import { Vector2, Matrix3, EdgeLineMetadata } from '../types';
|
||||
import { useResolverTheme, calculateResolverFontSize } from './assets';
|
||||
import { fontSize } from './font_size';
|
||||
import { useColors } from './use_colors';
|
||||
|
||||
interface StyledEdgeLine {
|
||||
readonly resolverEdgeColor: string;
|
||||
|
@ -19,7 +20,7 @@ interface StyledEdgeLine {
|
|||
const StyledEdgeLine = styled.div<StyledEdgeLine>`
|
||||
position: absolute;
|
||||
height: ${(props) => {
|
||||
return `${calculateResolverFontSize(props.magFactorX, 12, 8.5)}px`;
|
||||
return `${fontSize(props.magFactorX, 12, 8.5)}px`;
|
||||
}};
|
||||
background-color: ${(props) => props.resolverEdgeColor};
|
||||
`;
|
||||
|
@ -87,8 +88,8 @@ const EdgeLineComponent = React.memo(
|
|||
*/
|
||||
const screenStart = applyMatrix3(startPosition, projectionMatrix);
|
||||
const screenEnd = applyMatrix3(endPosition, projectionMatrix);
|
||||
const [magFactorX] = projectionMatrix;
|
||||
const { colorMap } = useResolverTheme();
|
||||
const [xScale] = projectionMatrix;
|
||||
const colorMap = useColors();
|
||||
const elapsedTime = edgeLineMetadata?.elapsedTime;
|
||||
|
||||
/**
|
||||
|
@ -96,7 +97,7 @@ const EdgeLineComponent = React.memo(
|
|||
* should be the same as the distance between the start and end points.
|
||||
*/
|
||||
const length = distance(screenStart, screenEnd);
|
||||
const scaledTypeSize = calculateResolverFontSize(magFactorX, 10, 7.5);
|
||||
const scaledTypeSize = fontSize(xScale, 10, 7.5);
|
||||
|
||||
const style = {
|
||||
left: `${screenStart[0]}px`,
|
||||
|
@ -120,8 +121,8 @@ const EdgeLineComponent = React.memo(
|
|||
/**
|
||||
* Calculates a fractional offset from 0 -> 5% as magFactorX decreases from 1 to a min of .5
|
||||
*/
|
||||
if (magFactorX < 1) {
|
||||
const fractionalOffset = (1 / magFactorX) * ((1 - magFactorX) * 10);
|
||||
if (xScale < 1) {
|
||||
const fractionalOffset = (1 / xScale) * ((1 - xScale) * 10);
|
||||
elapsedTimeLeftPosPct += fractionalOffset;
|
||||
}
|
||||
|
||||
|
@ -130,7 +131,7 @@ const EdgeLineComponent = React.memo(
|
|||
className={className}
|
||||
style={style}
|
||||
resolverEdgeColor={colorMap.resolverEdge}
|
||||
magFactorX={magFactorX}
|
||||
magFactorX={xScale}
|
||||
data-test-subj="resolver:graph:edgeline"
|
||||
>
|
||||
{elapsedTime && (
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Return a font-size based on a scale, minimum size, and a coefficient.
|
||||
*/
|
||||
export function fontSize(scale: number, minimum: number, slope: number): number {
|
||||
return minimum + (scale > 1 ? slope * (scale - 1) : 0);
|
||||
}
|
|
@ -13,8 +13,8 @@ import { useSelector, useDispatch } from 'react-redux';
|
|||
import { SideEffectContext } from './side_effect_context';
|
||||
import { Vector2 } from '../types';
|
||||
import * as selectors from '../store/selectors';
|
||||
import { useResolverTheme } from './assets';
|
||||
import { ResolverAction } from '../store/actions';
|
||||
import { useColors } from './use_colors';
|
||||
|
||||
interface StyledGraphControls {
|
||||
graphControlsBackground: string;
|
||||
|
@ -66,7 +66,7 @@ const GraphControlsComponent = React.memo(
|
|||
const dispatch: (action: ResolverAction) => unknown = useDispatch();
|
||||
const scalingFactor = useSelector(selectors.scalingFactor);
|
||||
const { timestamp } = useContext(SideEffectContext);
|
||||
const { colorMap } = useResolverTheme();
|
||||
const colorMap = useColors();
|
||||
|
||||
const handleZoomAmountChange = useCallback(
|
||||
(event: React.ChangeEvent<HTMLInputElement> | React.MouseEvent<HTMLButtonElement>) => {
|
||||
|
|
|
@ -11,11 +11,12 @@ import { i18n } from '@kbn/i18n';
|
|||
/* eslint-disable react/display-name */
|
||||
|
||||
import React, { memo } from 'react';
|
||||
import { useResolverTheme, SymbolIds } from '../assets';
|
||||
|
||||
interface StyledSVGCube {
|
||||
readonly isOrigin?: boolean;
|
||||
}
|
||||
import { useCubeAssets } from '../use_cube_assets';
|
||||
import { useSymbolIDs } from '../use_symbol_ids';
|
||||
|
||||
/**
|
||||
* Icon representing a process node.
|
||||
|
@ -34,8 +35,8 @@ export const CubeForProcess = memo(function ({
|
|||
isOrigin?: boolean;
|
||||
className?: string;
|
||||
}) {
|
||||
const { cubeAssetsForNode } = useResolverTheme();
|
||||
const { cubeSymbol, strokeColor } = cubeAssetsForNode(!running, false);
|
||||
const { cubeSymbol, strokeColor } = useCubeAssets(!running, false);
|
||||
const { processCubeActiveBacking } = useSymbolIDs();
|
||||
|
||||
return (
|
||||
<StyledSVG
|
||||
|
@ -54,7 +55,7 @@ export const CubeForProcess = memo(function ({
|
|||
</desc>
|
||||
{isOrigin && (
|
||||
<use
|
||||
xlinkHref={`#${SymbolIds.processCubeActiveBacking}`}
|
||||
xlinkHref={`#${processCubeActiveBacking}`}
|
||||
fill="transparent"
|
||||
x={0}
|
||||
y={-1}
|
||||
|
|
|
@ -27,7 +27,7 @@ import {
|
|||
} from '../../models/process_event';
|
||||
import { CubeForProcess } from './cube_for_process';
|
||||
import { ResolverEvent } from '../../../../common/endpoint/types';
|
||||
import { useResolverTheme } from '../assets';
|
||||
import { useCubeAssets } from '../use_cube_assets';
|
||||
import { ResolverState } from '../../types';
|
||||
import { PanelLoading } from './panel_loading';
|
||||
import { StyledPanel } from '../styles';
|
||||
|
@ -166,13 +166,7 @@ const NodeDetailView = memo(function NodeDetailView({
|
|||
},
|
||||
];
|
||||
}, [processName, nodesLinkNavProps]);
|
||||
const { cubeAssetsForNode } = useResolverTheme();
|
||||
const { descriptionText } = useMemo(() => {
|
||||
if (!processEvent) {
|
||||
return { descriptionText: '' };
|
||||
}
|
||||
return cubeAssetsForNode(isProcessTerminated, false);
|
||||
}, [processEvent, cubeAssetsForNode, isProcessTerminated]);
|
||||
const { descriptionText } = useCubeAssets(isProcessTerminated, false);
|
||||
|
||||
const nodeDetailHref = useSelector((state: ResolverState) =>
|
||||
selectors.relativeHref(state)({
|
||||
|
|
|
@ -26,7 +26,7 @@ import { SafeResolverEvent } from '../../../../common/endpoint/types';
|
|||
import { LimitWarning } from '../limit_warnings';
|
||||
import { ResolverState } from '../../types';
|
||||
import { useNavigateOrReplace } from '../use_navigate_or_replace';
|
||||
import { useResolverTheme } from '../assets';
|
||||
import { useColors } from '../use_colors';
|
||||
|
||||
const StyledLimitWarning = styled(LimitWarning)`
|
||||
flex-flow: row wrap;
|
||||
|
@ -208,9 +208,7 @@ function NodeDetailLink({ name, item }: { name: string; item: ProcessTableView }
|
|||
const isTerminated = useSelector((state: ResolverState) =>
|
||||
entityID === undefined ? false : selectors.isProcessTerminated(state)(entityID)
|
||||
);
|
||||
const {
|
||||
colorMap: { descriptionText },
|
||||
} = useResolverTheme();
|
||||
const { descriptionText } = useColors();
|
||||
return (
|
||||
<EuiButtonEmpty {...useNavigateOrReplace({ search: item.href })}>
|
||||
{name === '' ? (
|
||||
|
|
|
@ -4,11 +4,13 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
/* eslint-disable react/display-name */
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiBreadcrumbs, EuiCode, EuiBetaBadge } from '@elastic/eui';
|
||||
import styled from 'styled-components';
|
||||
import React, { memo } from 'react';
|
||||
import { useResolverTheme } from '../assets';
|
||||
import { useColors } from '../use_colors';
|
||||
|
||||
/**
|
||||
* A bold version of EuiCode to display certain titles with
|
||||
|
@ -63,7 +65,7 @@ export const GeneratedText = React.memo(function ({ children }) {
|
|||
valueSplitByWordBoundaries[0],
|
||||
...valueSplitByWordBoundaries
|
||||
.splice(1)
|
||||
.reduce(function (generatedTextMemo: Array<string | JSX.Element>, value, index) {
|
||||
.reduce(function (generatedTextMemo: Array<string | JSX.Element>, value) {
|
||||
return [...generatedTextMemo, value, <wbr />];
|
||||
}, []),
|
||||
];
|
||||
|
@ -73,7 +75,6 @@ export const GeneratedText = React.memo(function ({ children }) {
|
|||
});
|
||||
}
|
||||
});
|
||||
GeneratedText.displayName = 'GeneratedText';
|
||||
|
||||
/**
|
||||
* A component to keep time representations in blocks so they don't wrap
|
||||
|
@ -93,9 +94,7 @@ export const StyledBreadcrumbs = memo(function StyledBreadcrumbs({
|
|||
}: {
|
||||
breadcrumbs: Breadcrumbs;
|
||||
}) {
|
||||
const {
|
||||
colorMap: { resolverBreadcrumbBackground, resolverEdgeText },
|
||||
} = useResolverTheme();
|
||||
const { resolverBreadcrumbBackground, resolverEdgeText } = useColors();
|
||||
return (
|
||||
<>
|
||||
<BetaHeader>
|
||||
|
|
|
@ -12,12 +12,15 @@ import { FormattedMessage } from '@kbn/i18n/react';
|
|||
import { NodeSubMenu } from './submenu';
|
||||
import { applyMatrix3 } from '../models/vector2';
|
||||
import { Vector2, Matrix3, ResolverState } from '../types';
|
||||
import { SymbolIds, useResolverTheme, calculateResolverFontSize } from './assets';
|
||||
import { ResolverEvent, SafeResolverEvent } from '../../../common/endpoint/types';
|
||||
import { useResolverDispatch } from './use_resolver_dispatch';
|
||||
import * as eventModel from '../../../common/endpoint/models/event';
|
||||
import * as selectors from '../store/selectors';
|
||||
import { useNavigateOrReplace } from './use_navigate_or_replace';
|
||||
import { fontSize } from './font_size';
|
||||
import { useCubeAssets } from './use_cube_assets';
|
||||
import { useSymbolIDs } from './use_symbol_ids';
|
||||
import { useColors } from './use_colors';
|
||||
|
||||
interface StyledActionsContainer {
|
||||
readonly color: string;
|
||||
|
@ -108,6 +111,8 @@ const UnstyledProcessEventDot = React.memo(
|
|||
// This should be unique to each instance of Resolver
|
||||
const htmlIDPrefix = `resolver:${resolverComponentInstanceID}`;
|
||||
|
||||
const symbolIDs = useSymbolIDs();
|
||||
|
||||
/**
|
||||
* Convert the position, which is in 'world' coordinates, to screen coordinates.
|
||||
*/
|
||||
|
@ -191,7 +196,7 @@ const UnstyledProcessEventDot = React.memo(
|
|||
* 18.75 : The smallest readable font size at which labels/descriptions can be read. Font size will not scale below this.
|
||||
* 12.5 : A 'slope' at which the font size will scale w.r.t. to zoom level otherwise
|
||||
*/
|
||||
const scaledTypeSize = calculateResolverFontSize(xScale, 18.75, 12.5);
|
||||
const scaledTypeSize = fontSize(xScale, 18.75, 12.5);
|
||||
|
||||
const markerBaseSize = 15;
|
||||
const markerSize = markerBaseSize;
|
||||
|
@ -212,7 +217,7 @@ const UnstyledProcessEventDot = React.memo(
|
|||
})
|
||||
| null;
|
||||
} = React.createRef();
|
||||
const { colorMap, cubeAssetsForNode } = useResolverTheme();
|
||||
const colorMap = useColors();
|
||||
const {
|
||||
backingFill,
|
||||
cubeSymbol,
|
||||
|
@ -220,7 +225,7 @@ const UnstyledProcessEventDot = React.memo(
|
|||
isLabelFilled,
|
||||
labelButtonFill,
|
||||
strokeColor,
|
||||
} = cubeAssetsForNode(
|
||||
} = useCubeAssets(
|
||||
isProcessTerminated,
|
||||
/**
|
||||
* There is no definition for 'trigger process' yet. return false.
|
||||
|
@ -323,7 +328,7 @@ const UnstyledProcessEventDot = React.memo(
|
|||
>
|
||||
<StyledOuterGroup>
|
||||
<use
|
||||
xlinkHref={`#${SymbolIds.processCubeActiveBacking}`}
|
||||
xlinkHref={`#${symbolIDs.processCubeActiveBacking}`}
|
||||
fill={backingFill} // Only visible on hover
|
||||
x={-15.35}
|
||||
y={-15.35}
|
||||
|
@ -334,7 +339,7 @@ const UnstyledProcessEventDot = React.memo(
|
|||
/>
|
||||
{isOrigin && (
|
||||
<use
|
||||
xlinkHref={`#${SymbolIds.processCubeActiveBacking}`}
|
||||
xlinkHref={`#${symbolIDs.processCubeActiveBacking}`}
|
||||
fill="transparent" // Transparent so we don't double up on the default hover
|
||||
x={-15.35}
|
||||
y={-15.35}
|
||||
|
|
|
@ -16,13 +16,14 @@ import { EdgeLine } from './edge_line';
|
|||
import { GraphControls } from './graph_controls';
|
||||
import { ProcessEventDot } from './process_event_dot';
|
||||
import { useCamera } from './use_camera';
|
||||
import { SymbolDefinitions, useResolverTheme } from './assets';
|
||||
import { SymbolDefinitions } from './symbol_definitions';
|
||||
import { useStateSyncingActions } from './use_state_syncing_actions';
|
||||
import { StyledMapContainer, GraphContainer } from './styles';
|
||||
import { entityIDSafeVersion } from '../../../common/endpoint/models/event';
|
||||
import { SideEffectContext } from './side_effect_context';
|
||||
import { ResolverProps, ResolverState } from '../types';
|
||||
import { PanelRouter } from './panels';
|
||||
import { useColors } from './use_colors';
|
||||
|
||||
/**
|
||||
* The highest level connected Resolver component. Needs a `Provider` in its ancestry to work.
|
||||
|
@ -73,7 +74,7 @@ export const ResolverWithoutProviders = React.memo(
|
|||
const isLoading = useSelector(selectors.isTreeLoading);
|
||||
const hasError = useSelector(selectors.hadErrorLoadingTree);
|
||||
const activeDescendantId = useSelector(selectors.ariaActiveDescendant);
|
||||
const { colorMap } = useResolverTheme();
|
||||
const colorMap = useColors();
|
||||
|
||||
return (
|
||||
<StyledMapContainer className={className} backgroundColor={colorMap.resolverBackground}>
|
||||
|
|
|
@ -13,7 +13,7 @@ import styled from 'styled-components';
|
|||
import { ResolverNodeStats } from '../../../common/endpoint/types';
|
||||
import { useRelatedEventByCategoryNavigation } from './use_related_event_by_category_navigation';
|
||||
import { Matrix3 } from '../types';
|
||||
import { useResolverTheme } from './assets';
|
||||
import { useColors } from './use_colors';
|
||||
|
||||
/**
|
||||
* i18n-translated titles for submenus and identifiers for display of states:
|
||||
|
@ -182,9 +182,7 @@ const NodeSubMenuComponents = React.memo(
|
|||
// no matter what, keep track of the last project matrix that was used to size the popover
|
||||
projectionMatrixAtLastRender.current = projectionMatrix;
|
||||
}, [projectionMatrixAtLastRender, projectionMatrix]);
|
||||
const {
|
||||
colorMap: { pillStroke: pillBorderStroke, resolverBackground: pillFill },
|
||||
} = useResolverTheme();
|
||||
const { pillStroke: pillBorderStroke, resolverBackground: pillFill } = useColors();
|
||||
const listStylesFromTheme = useMemo(() => {
|
||||
return {
|
||||
border: `1.5px solid ${pillBorderStroke}`,
|
||||
|
@ -239,6 +237,7 @@ const NodeSubMenuComponents = React.memo(
|
|||
className="item"
|
||||
data-test-subj="resolver:map:node-submenu-item"
|
||||
style={listStylesFromTheme}
|
||||
key={opt.optionTitle}
|
||||
>
|
||||
<button type="button" className="kbn-resetFocusState" onClick={opt.action}>
|
||||
{opt.prefix} {opt.optionTitle}
|
||||
|
|
|
@ -0,0 +1,354 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
/* eslint-disable react/display-name */
|
||||
|
||||
import React, { memo } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { useUiSetting } from '../../../../../../src/plugins/kibana_react/public';
|
||||
import { useSymbolIDs } from './use_symbol_ids';
|
||||
import { usePaintServerIDs } from './use_paint_server_ids';
|
||||
|
||||
/**
|
||||
* PaintServers: Where color palettes, gradients, patterns and other similar concerns
|
||||
* are exposed to the component
|
||||
*/
|
||||
const PaintServers = memo(({ isDarkMode }: { isDarkMode: boolean }) => {
|
||||
const paintServerIDs = usePaintServerIDs();
|
||||
return (
|
||||
<>
|
||||
<linearGradient
|
||||
id={paintServerIDs.runningProcessCube}
|
||||
x1="-381.23556"
|
||||
y1="264.73802"
|
||||
x2="-380.48514"
|
||||
y2="263.8816"
|
||||
gradientTransform="matrix(70.05179, 0, 0, -79.94774, 26724.01618, 21181.09848)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0.00087" stopColor="#006bb4" />
|
||||
<stop offset="1" stopColor="#54b399" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id={paintServerIDs.runningTriggerCube}
|
||||
x1="-381.18643"
|
||||
y1="264.68195"
|
||||
x2="-380.48514"
|
||||
y2="263.8816"
|
||||
gradientTransform="matrix(70.05179, 0, 0, -79.94774, 26724.01618, 21181.09848)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0" stopColor="#dd0a73" />
|
||||
<stop offset="1" stopColor="#f66" />
|
||||
</linearGradient>
|
||||
{isDarkMode ? (
|
||||
<>
|
||||
<linearGradient
|
||||
id={paintServerIDs.terminatedProcessCube}
|
||||
x1="-381.23752"
|
||||
y1="264.24026"
|
||||
x2="-380.48514"
|
||||
y2="263.3816"
|
||||
gradientTransform="matrix(70.05178, 0, 0, -79.94771, 26724.01313, 21140.72096)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0" stopColor="#4c82c3" />
|
||||
<stop offset="1" stopColor="#8bd1c7" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id={paintServerIDs.terminatedTriggerCube}
|
||||
x1="-381.18658"
|
||||
y1="264.68187"
|
||||
x2="-380.48546"
|
||||
y2="263.8817"
|
||||
gradientTransform="matrix(70.05179, 0, 0, -79.94774, 26724.01618, 21181.09848)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0" stopColor="#dd0a73" />
|
||||
<stop offset="1" stopColor="#f66" />
|
||||
</linearGradient>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<linearGradient
|
||||
id={paintServerIDs.terminatedProcessCube}
|
||||
x1="10.5206"
|
||||
y1="9.49068"
|
||||
x2="46.8141"
|
||||
y2="45.7844"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0" stopColor="#2F6EB6" />
|
||||
<stop offset="1" stopColor="#00B4AC" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id={paintServerIDs.terminatedTriggerCube}
|
||||
x1="15.4848"
|
||||
y1="12.0468"
|
||||
x2="43.1049"
|
||||
y2="47.2331"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stopColor="#DD0A73" />
|
||||
<stop offset="1" stopColor="#FF6666" />
|
||||
</linearGradient>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* Defs entries that define shapes, masks and other spatial elements
|
||||
*/
|
||||
const SymbolsAndShapes = memo(({ isDarkMode }: { isDarkMode: boolean }) => {
|
||||
const symbolIDs = useSymbolIDs();
|
||||
const paintServerIDs = usePaintServerIDs();
|
||||
return (
|
||||
<>
|
||||
<symbol
|
||||
id={symbolIDs.processNodeLabel}
|
||||
viewBox="0 0 144 25"
|
||||
preserveAspectRatio="xMidYMid meet"
|
||||
>
|
||||
<rect
|
||||
x="1"
|
||||
y="1"
|
||||
width="142"
|
||||
height="23"
|
||||
fill="inherit"
|
||||
strokeWidth="0"
|
||||
paintOrder="normal"
|
||||
/>
|
||||
</symbol>
|
||||
<symbol id={symbolIDs.runningProcessCube} viewBox="0 0 88 100">
|
||||
<title>{'Running Process'}</title>
|
||||
<path
|
||||
d="M87.52127,25.129a3.79536,3.79536,0,0,0-1.43184-1.47165L45.91025.57471a3.83652,3.83652,0,0,0-3.8205,0L1.91039,23.65739A3.86308,3.86308,0,0,0,0,26.95V73.11541a3.79835,3.79835,0,0,0,1.9104,3.2925L42.08975,99.49067a3.83691,3.83691,0,0,0,3.8205,0L86.08943,76.40791A3.79852,3.79852,0,0,0,88,73.11541V26.95A3.77641,3.77641,0,0,0,87.52127,25.129Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill={`url(#${paintServerIDs.runningProcessCube})`}
|
||||
/>
|
||||
<g opacity="0.5">
|
||||
<path
|
||||
d="M59.18326,40.255,44.93983,32.07224a1.7853,1.7853,0,0,0-1.77779,0L28.91861,40.255a1.77022,1.77022,0,0,0-.64527.64058L44.0088,49.96977,59.838,40.91219a1.77,1.77,0,0,0-.65469-.65719Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M59.18326,40.255,44.93983,32.07224a1.7853,1.7853,0,0,0-1.77779,0L28.91861,40.255a1.77022,1.77022,0,0,0-.64527.64058L44.0088,49.96977,59.838,40.91219a1.77,1.77,0,0,0-.65469-.65719Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#fff"
|
||||
opacity="0.2"
|
||||
style={{ isolation: 'isolate' }}
|
||||
/>
|
||||
<path
|
||||
d="M28.27334,40.89555a1.75837,1.75837,0,0,0-.24347.89149V58.1525a1.76751,1.76751,0,0,0,.88874,1.532L43.162,67.86729a1.77951,1.77951,0,0,0,.84679.2316V49.96977Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M28.27334,40.89555a1.75837,1.75837,0,0,0-.24347.89149V58.1525a1.76751,1.76751,0,0,0,.88874,1.532L43.162,67.86729a1.77951,1.77951,0,0,0,.84679.2316V49.96977Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#fff"
|
||||
opacity="0.2"
|
||||
style={{ isolation: 'isolate' }}
|
||||
/>
|
||||
<path
|
||||
d="M44.0088,68.0989a1.7772,1.7772,0,0,0,.931-.2316l14.24344-8.18274a1.76754,1.76754,0,0,0,.889-1.532V41.787a1.76037,1.76037,0,0,0-.23432-.87485L44.0088,49.96977Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M44.0088,68.0989a1.7772,1.7772,0,0,0,.931-.2316l14.24344-8.18274a1.76754,1.76754,0,0,0,.889-1.532V41.787a1.76037,1.76037,0,0,0-.23432-.87485L44.0088,49.96977Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#fff"
|
||||
opacity="0.2"
|
||||
style={{ isolation: 'isolate' }}
|
||||
/>
|
||||
</g>
|
||||
<path
|
||||
d="M.57144,24.91834a3.79909,3.79909,0,0,1,1.34825-1.32625L42.0989.50939a3.837,3.837,0,0,1,3.82081,0L86.09892,23.59206a3.79782,3.79782,0,0,1,1.4318,1.47169L44.00915,49.96733Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#fff"
|
||||
opacity="0.3"
|
||||
style={{ isolation: 'isolate' }}
|
||||
/>
|
||||
<path
|
||||
d="M43.99984,50.03265V100a3.83392,3.83392,0,0,1-1.91024-.50933L1.91039,76.40791A3.79835,3.79835,0,0,1,0,73.11541V26.95a3.77423,3.77423,0,0,1,.56216-1.96625Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#353944"
|
||||
opacity="0.2"
|
||||
style={{ isolation: 'isolate' }}
|
||||
/>
|
||||
</symbol>
|
||||
<symbol id={symbolIDs.runningTriggerCube} viewBox="0 0 88 100">
|
||||
<title>{'resolver_dark process running'}</title>
|
||||
<path
|
||||
d="M87.52127,25.129a3.79536,3.79536,0,0,0-1.43184-1.47165L45.91025.57471a3.83652,3.83652,0,0,0-3.8205,0L1.91039,23.65739A3.86308,3.86308,0,0,0,0,26.95V73.11541a3.79835,3.79835,0,0,0,1.9104,3.2925L42.08975,99.49067a3.83691,3.83691,0,0,0,3.8205,0L86.08943,76.40791A3.79852,3.79852,0,0,0,88,73.11541V26.95A3.77641,3.77641,0,0,0,87.52127,25.129Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill={`url(#${paintServerIDs.runningTriggerCube})`}
|
||||
/>
|
||||
<g opacity="0.5">
|
||||
<path
|
||||
d="M59.18326,40.255,44.93983,32.07224a1.7853,1.7853,0,0,0-1.77779,0L28.91861,40.255a1.77022,1.77022,0,0,0-.64527.64058L44.0088,49.96977,59.838,40.91219a1.77,1.77,0,0,0-.65469-.65719Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M59.18326,40.255,44.93983,32.07224a1.7853,1.7853,0,0,0-1.77779,0L28.91861,40.255a1.77022,1.77022,0,0,0-.64527.64058L44.0088,49.96977,59.838,40.91219a1.77,1.77,0,0,0-.65469-.65719Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#fff"
|
||||
opacity="0.2"
|
||||
style={{ isolation: 'isolate' }}
|
||||
/>
|
||||
<path
|
||||
d="M28.27334,40.89555a1.75837,1.75837,0,0,0-.24347.89149V58.1525a1.76751,1.76751,0,0,0,.88874,1.532L43.162,67.86729a1.77951,1.77951,0,0,0,.84679.2316V49.96977Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M28.27334,40.89555a1.75837,1.75837,0,0,0-.24347.89149V58.1525a1.76751,1.76751,0,0,0,.88874,1.532L43.162,67.86729a1.77951,1.77951,0,0,0,.84679.2316V49.96977Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#fff"
|
||||
opacity="0.2"
|
||||
style={{ isolation: 'isolate' }}
|
||||
/>
|
||||
<path
|
||||
d="M44.0088,68.0989a1.7772,1.7772,0,0,0,.931-.2316l14.24344-8.18274a1.76754,1.76754,0,0,0,.889-1.532V41.787a1.76037,1.76037,0,0,0-.23432-.87485L44.0088,49.96977Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M44.0088,68.0989a1.7772,1.7772,0,0,0,.931-.2316l14.24344-8.18274a1.76754,1.76754,0,0,0,.889-1.532V41.787a1.76037,1.76037,0,0,0-.23432-.87485L44.0088,49.96977Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#fff"
|
||||
opacity="0.2"
|
||||
style={{ isolation: 'isolate' }}
|
||||
/>
|
||||
</g>
|
||||
<path
|
||||
d="M.57144,24.91834a3.79909,3.79909,0,0,1,1.34825-1.32625L42.0989.50939a3.837,3.837,0,0,1,3.82081,0L86.09892,23.59206a3.79782,3.79782,0,0,1,1.4318,1.47169L44.00915,49.96733Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#fff"
|
||||
opacity="0.3"
|
||||
style={{ isolation: 'isolate' }}
|
||||
/>
|
||||
<path
|
||||
d="M43.99984,50.03265V100a3.83392,3.83392,0,0,1-1.91024-.50933L1.91039,76.40791A3.79835,3.79835,0,0,1,0,73.11541V26.95a3.77423,3.77423,0,0,1,.56216-1.96625Z"
|
||||
transform="translate(0.00001 0)"
|
||||
fill="#353944"
|
||||
opacity="0.2"
|
||||
style={{ isolation: 'isolate' }}
|
||||
/>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 88 100" id={symbolIDs.terminatedProcessCube}>
|
||||
<title>{'Terminated Process'}</title>
|
||||
<path
|
||||
d="M87.52113,24.73352a3.7956,3.7956,0,0,0-1.43182-1.47166L45.91012.17918a3.8365,3.8365,0,0,0-3.82049,0L1.91029,23.26186A3.86312,3.86312,0,0,0-.00009,26.55445V72.7199a3.79834,3.79834,0,0,0,1.91041,3.29249L42.08963,99.09514a3.83689,3.83689,0,0,0,3.82049,0L86.08931,76.01239a3.79852,3.79852,0,0,0,1.91056-3.29249V26.55445A3.77643,3.77643,0,0,0,87.52113,24.73352Z"
|
||||
transform="translate(0.00013 0.39551)"
|
||||
fill={isDarkMode ? '#010101' : '#fff'}
|
||||
/>
|
||||
<g opacity="0.7">
|
||||
<path
|
||||
opacity={isDarkMode ? 1 : 0.6}
|
||||
d="M87.52113,24.73352a3.7956,3.7956,0,0,0-1.43182-1.47166L45.91012.17918a3.8365,3.8365,0,0,0-3.82049,0L1.91029,23.26186A3.86312,3.86312,0,0,0-.00009,26.55445V72.7199a3.79834,3.79834,0,0,0,1.91041,3.29249L42.08963,99.09514a3.83689,3.83689,0,0,0,3.82049,0L86.08931,76.01239a3.79852,3.79852,0,0,0,1.91056-3.29249V26.55445A3.77643,3.77643,0,0,0,87.52113,24.73352Z"
|
||||
transform="translate(0.00013 0.39551)"
|
||||
fill={`url(#${paintServerIDs.terminatedProcessCube})`}
|
||||
/>
|
||||
<path
|
||||
opacity={isDarkMode ? 0.3 : 0.4}
|
||||
d="M.57134,24.52282a3.79906,3.79906,0,0,1,1.34824-1.32625L42.09878.11387a3.83708,3.83708,0,0,1,3.8208,0L86.09877,23.19655a3.79771,3.79771,0,0,1,1.43182,1.47165L44.00909,49.57182Z"
|
||||
transform="translate(0.00013 0.39551)"
|
||||
fill="#fff"
|
||||
style={{ isolation: 'isolate' }}
|
||||
/>
|
||||
<path
|
||||
opacity={isDarkMode ? 0.2 : 0.4}
|
||||
d="M43.99972,49.63713V99.60449a3.83406,3.83406,0,0,1-1.91025-.50932L1.91029,76.01239A3.79835,3.79835,0,0,1-.00013,72.7199V26.55445A3.77431,3.77431,0,0,1,.562,24.5882Z"
|
||||
transform="translate(0.00013 0.39551)"
|
||||
fill="#353944"
|
||||
style={{ isolation: 'isolate' }}
|
||||
/>
|
||||
</g>
|
||||
</symbol>
|
||||
<symbol id={symbolIDs.terminatedTriggerCube} viewBox="0 0 88 100">
|
||||
<title>{'Terminated Trigger Process'}</title>
|
||||
{isDarkMode && (
|
||||
<path
|
||||
opacity="1"
|
||||
d="M87.52143,25.06372a3.795,3.795,0,0,0-1.43129-1.47166L45.92578.50939a3.83384,3.83384,0,0,0-3.81907,0L1.94219,23.59206A3.8634,3.8634,0,0,0,.03252,26.88465V73.05008a3.7986,3.7986,0,0,0,1.90971,3.2925L42.10671,99.42532a3.83423,3.83423,0,0,0,3.81907,0L86.09014,76.34258A3.79881,3.79881,0,0,0,88,73.05008V26.88465A3.77748,3.77748,0,0,0,87.52143,25.06372Z"
|
||||
transform="translate(0)"
|
||||
fill="#010101"
|
||||
/>
|
||||
)}
|
||||
<g opacity="0.6">
|
||||
{!isDarkMode && (
|
||||
<path
|
||||
opacity="0.6"
|
||||
d="M87.52143,25.06372a3.795,3.795,0,0,0-1.43129-1.47166L45.92578.50939a3.83384,3.83384,0,0,0-3.81907,0L1.94219,23.59206A3.8634,3.8634,0,0,0,.03252,26.88465V73.05008a3.7986,3.7986,0,0,0,1.90971,3.2925L42.10671,99.42532a3.83423,3.83423,0,0,0,3.81907,0L86.09014,76.34258A3.79881,3.79881,0,0,0,88,73.05008V26.88465A3.77748,3.77748,0,0,0,87.52143,25.06372Z"
|
||||
transform="translate(0)"
|
||||
fill="#010101"
|
||||
/>
|
||||
)}
|
||||
<path
|
||||
opacity={isDarkMode ? 1 : 0.604}
|
||||
d="M87.48893,25.129a3.79468,3.79468,0,0,0-1.4313-1.47165L45.89329.57472a3.83381,3.83381,0,0,0-3.81908,0L1.90969,23.65739A3.86331,3.86331,0,0,0,0,26.95V73.11541a3.79859,3.79859,0,0,0,1.90969,3.2925L42.07421,99.49067a3.83425,3.83425,0,0,0,3.81908,0L86.05763,76.40791a3.79876,3.79876,0,0,0,1.90985-3.2925V26.95A3.77746,3.77746,0,0,0,87.48893,25.129Z"
|
||||
transform="translate(0)"
|
||||
fill={`url(#${paintServerIDs.terminatedTriggerCube})`}
|
||||
/>
|
||||
<path
|
||||
d="M.57124,24.91834A3.79833,3.79833,0,0,1,1.919,23.59209L42.08335.50939a3.83441,3.83441,0,0,1,3.8194,0L86.06711,23.59206a3.7972,3.7972,0,0,1,1.43128,1.47169L43.99289,49.96733Z"
|
||||
transform="translate(0)"
|
||||
fill="#fff"
|
||||
opacity="0.3"
|
||||
style={{ isolation: 'isolate' }}
|
||||
/>
|
||||
<path
|
||||
d="M43.98359,50.03265V100a3.83139,3.83139,0,0,1-1.90953-.50933L1.90969,76.40791A3.79859,3.79859,0,0,1,0,73.11541V26.95a3.77523,3.77523,0,0,1,.56195-1.96625Z"
|
||||
transform="translate(0)"
|
||||
fill="#353944"
|
||||
opacity="0.2"
|
||||
style={{ isolation: 'isolate' }}
|
||||
/>
|
||||
</g>
|
||||
</symbol>
|
||||
<symbol viewBox="0 -3 88 106" id={symbolIDs.processCubeActiveBacking}>
|
||||
<title>{'resolver active backing'}</title>
|
||||
<path
|
||||
d="m87.521 25.064a3.795 3.795 0 0 0-1.4313-1.4717l-40.164-23.083a3.8338 3.8338 0 0 0-3.8191 0l-40.165 23.083a3.8634 3.8634 0 0 0-1.9097 3.2926v46.165a3.7986 3.7986 0 0 0 1.9097 3.2925l40.164 23.083a3.8342 3.8342 0 0 0 3.8191 0l40.164-23.083a3.7988 3.7988 0 0 0 1.9099-3.2925v-46.165a3.7775 3.7775 0 0 0-0.47857-1.8209z"
|
||||
strokeWidth="2"
|
||||
/>
|
||||
</symbol>
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* This `<defs>` element is used to define the reusable assets for the Resolver
|
||||
* It confers several advantages, including but not limited to:
|
||||
* 1. Freedom of form for creative assets (beyond box-model constraints)
|
||||
* 2. Separation of concerns between creative assets and more functional areas of the app
|
||||
* 3. `<use>` elements can be handled by compositor (faster)
|
||||
*/
|
||||
export const SymbolDefinitions = memo(() => {
|
||||
const isDarkMode = useUiSetting<boolean>('theme:darkMode');
|
||||
return (
|
||||
<HiddenSVG>
|
||||
<defs>
|
||||
<PaintServers isDarkMode={isDarkMode} />
|
||||
<SymbolsAndShapes isDarkMode={isDarkMode} />
|
||||
</defs>
|
||||
</HiddenSVG>
|
||||
);
|
||||
});
|
||||
|
||||
const HiddenSVG = styled('svg')`
|
||||
position: absolute;
|
||||
left: 100%;
|
||||
top: 100%;
|
||||
width: 0;
|
||||
height: 0;
|
||||
`;
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import euiThemeAmsterdamDark from '@elastic/eui/dist/eui_theme_amsterdam_dark.json';
|
||||
import euiThemeAmsterdamLight from '@elastic/eui/dist/eui_theme_amsterdam_light.json';
|
||||
import { useMemo } from 'react';
|
||||
import { useUiSetting } from '../../../../../../src/plugins/kibana_react/public';
|
||||
|
||||
type ResolverColorNames =
|
||||
| 'descriptionText'
|
||||
| 'full'
|
||||
| 'graphControls'
|
||||
| 'graphControlsBackground'
|
||||
| 'resolverBackground'
|
||||
| 'resolverEdge'
|
||||
| 'resolverEdgeText'
|
||||
| 'resolverBreadcrumbBackground'
|
||||
| 'pillStroke'
|
||||
| 'triggerBackingFill'
|
||||
| 'processBackingFill';
|
||||
type ColorMap = Record<ResolverColorNames, string>;
|
||||
|
||||
/**
|
||||
* Get access to Kibana-theme based colors.
|
||||
*/
|
||||
export function useColors(): ColorMap {
|
||||
const isDarkMode = useUiSetting('theme:darkMode');
|
||||
const theme = isDarkMode ? euiThemeAmsterdamDark : euiThemeAmsterdamLight;
|
||||
return useMemo(() => {
|
||||
return {
|
||||
descriptionText: theme.euiTextColor,
|
||||
full: theme.euiColorFullShade,
|
||||
graphControls: theme.euiColorDarkestShade,
|
||||
graphControlsBackground: theme.euiColorEmptyShade,
|
||||
processBackingFill: `${theme.euiColorPrimary}${isDarkMode ? '1F' : '0F'}`, // Add opacity 0F = 6% , 1F = 12%
|
||||
resolverBackground: theme.euiColorEmptyShade,
|
||||
resolverEdge: isDarkMode ? theme.euiColorLightShade : theme.euiColorLightestShade,
|
||||
resolverBreadcrumbBackground: theme.euiColorLightestShade,
|
||||
resolverEdgeText: isDarkMode ? theme.euiColorFullShade : theme.euiColorDarkShade,
|
||||
triggerBackingFill: `${theme.euiColorDanger}${isDarkMode ? '1F' : '0F'}`,
|
||||
pillStroke: theme.euiColorLightShade,
|
||||
};
|
||||
}, [isDarkMode, theme]);
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { ButtonColor } from '@elastic/eui';
|
||||
import euiThemeAmsterdamDark from '@elastic/eui/dist/eui_theme_amsterdam_dark.json';
|
||||
import euiThemeAmsterdamLight from '@elastic/eui/dist/eui_theme_amsterdam_light.json';
|
||||
import { useMemo } from 'react';
|
||||
import { ResolverProcessType } from '../types';
|
||||
import { useUiSetting } from '../../../../../../src/plugins/kibana_react/public';
|
||||
import { useSymbolIDs } from './use_symbol_ids';
|
||||
import { useColors } from './use_colors';
|
||||
|
||||
/**
|
||||
* Provides colors and HTML IDs used to render the 'cube' graphic that accompanies nodes.
|
||||
*/
|
||||
export function useCubeAssets(
|
||||
isProcessTerminated: boolean,
|
||||
isProcessTrigger: boolean
|
||||
): NodeStyleConfig {
|
||||
const SymbolIds = useSymbolIDs();
|
||||
const isDarkMode = useUiSetting('theme:darkMode');
|
||||
const theme = isDarkMode ? euiThemeAmsterdamDark : euiThemeAmsterdamLight;
|
||||
const colorMap = useColors();
|
||||
|
||||
const nodeAssets: NodeStyleMap = useMemo(
|
||||
() => ({
|
||||
runningProcessCube: {
|
||||
backingFill: colorMap.processBackingFill,
|
||||
cubeSymbol: `#${SymbolIds.runningProcessCube}`,
|
||||
descriptionFill: colorMap.descriptionText,
|
||||
descriptionText: i18n.translate('xpack.securitySolution.endpoint.resolver.runningProcess', {
|
||||
defaultMessage: 'Running Process',
|
||||
}),
|
||||
isLabelFilled: true,
|
||||
labelButtonFill: 'primary',
|
||||
strokeColor: theme.euiColorPrimary,
|
||||
},
|
||||
runningTriggerCube: {
|
||||
backingFill: colorMap.triggerBackingFill,
|
||||
cubeSymbol: `#${SymbolIds.runningTriggerCube}`,
|
||||
descriptionFill: colorMap.descriptionText,
|
||||
descriptionText: i18n.translate('xpack.securitySolution.endpoint.resolver.runningTrigger', {
|
||||
defaultMessage: 'Running Trigger',
|
||||
}),
|
||||
isLabelFilled: true,
|
||||
labelButtonFill: 'danger',
|
||||
strokeColor: theme.euiColorDanger,
|
||||
},
|
||||
terminatedProcessCube: {
|
||||
backingFill: colorMap.processBackingFill,
|
||||
cubeSymbol: `#${SymbolIds.terminatedProcessCube}`,
|
||||
descriptionFill: colorMap.descriptionText,
|
||||
descriptionText: i18n.translate(
|
||||
'xpack.securitySolution.endpoint.resolver.terminatedProcess',
|
||||
{
|
||||
defaultMessage: 'Terminated Process',
|
||||
}
|
||||
),
|
||||
isLabelFilled: false,
|
||||
labelButtonFill: 'primary',
|
||||
strokeColor: theme.euiColorPrimary,
|
||||
},
|
||||
terminatedTriggerCube: {
|
||||
backingFill: colorMap.triggerBackingFill,
|
||||
cubeSymbol: `#${SymbolIds.terminatedTriggerCube}`,
|
||||
descriptionFill: colorMap.descriptionText,
|
||||
descriptionText: i18n.translate(
|
||||
'xpack.securitySolution.endpoint.resolver.terminatedTrigger',
|
||||
{
|
||||
defaultMessage: 'Terminated Trigger',
|
||||
}
|
||||
),
|
||||
isLabelFilled: false,
|
||||
labelButtonFill: 'danger',
|
||||
strokeColor: theme.euiColorDanger,
|
||||
},
|
||||
}),
|
||||
[SymbolIds, colorMap, theme]
|
||||
);
|
||||
|
||||
if (isProcessTerminated) {
|
||||
if (isProcessTrigger) {
|
||||
return nodeAssets.terminatedTriggerCube;
|
||||
} else {
|
||||
return nodeAssets[processTypeToCube.processTerminated];
|
||||
}
|
||||
} else if (isProcessTrigger) {
|
||||
return nodeAssets[processTypeToCube.processCausedAlert];
|
||||
} else {
|
||||
return nodeAssets[processTypeToCube.processRan];
|
||||
}
|
||||
}
|
||||
|
||||
const processTypeToCube: Record<ResolverProcessType, keyof NodeStyleMap> = {
|
||||
processCreated: 'runningProcessCube',
|
||||
processRan: 'runningProcessCube',
|
||||
processTerminated: 'terminatedProcessCube',
|
||||
unknownProcessEvent: 'runningProcessCube',
|
||||
processCausedAlert: 'runningTriggerCube',
|
||||
unknownEvent: 'runningProcessCube',
|
||||
};
|
||||
interface NodeStyleMap {
|
||||
runningProcessCube: NodeStyleConfig;
|
||||
runningTriggerCube: NodeStyleConfig;
|
||||
terminatedProcessCube: NodeStyleConfig;
|
||||
terminatedTriggerCube: NodeStyleConfig;
|
||||
}
|
||||
interface NodeStyleConfig {
|
||||
backingFill: string;
|
||||
cubeSymbol: string;
|
||||
descriptionFill: string;
|
||||
descriptionText: string;
|
||||
isLabelFilled: boolean;
|
||||
labelButtonFill: ButtonColor;
|
||||
strokeColor: string;
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import * as selectors from '../store/selectors';
|
||||
|
||||
/**
|
||||
* Access the HTML IDs for this Resolver's reusable SVG 'paint servers'.
|
||||
* In the future these IDs may come from an outside provider (and may be shared by multiple Resolver instances.)
|
||||
*/
|
||||
export function usePaintServerIDs() {
|
||||
const resolverComponentInstanceID = useSelector(selectors.resolverComponentInstanceID);
|
||||
return useMemo(() => {
|
||||
const prefix = `${resolverComponentInstanceID}-symbols`;
|
||||
return {
|
||||
runningProcessCube: `${prefix}-psRunningProcessCube`,
|
||||
runningTriggerCube: `${prefix}-psRunningTriggerCube`,
|
||||
terminatedProcessCube: `${prefix}-psTerminatedProcessCube`,
|
||||
terminatedTriggerCube: `${prefix}-psTerminatedTriggerCube`,
|
||||
};
|
||||
}, [resolverComponentInstanceID]);
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import * as selectors from '../store/selectors';
|
||||
|
||||
/**
|
||||
* Access the HTML IDs for this Resolver's reusable SVG symbols.
|
||||
* In the future these IDs may come from an outside provider (and may be shared by multiple Resolver instances.)
|
||||
*/
|
||||
export function useSymbolIDs() {
|
||||
const resolverComponentInstanceID = useSelector(selectors.resolverComponentInstanceID);
|
||||
return useMemo(() => {
|
||||
const prefix = `${resolverComponentInstanceID}-symbols`;
|
||||
return {
|
||||
processNodeLabel: `${prefix}-nodeSymbol`,
|
||||
runningProcessCube: `${prefix}-runningCube`,
|
||||
runningTriggerCube: `${prefix}-runningTriggerCube`,
|
||||
terminatedProcessCube: `${prefix}-terminatedCube`,
|
||||
terminatedTriggerCube: `${prefix}-terminatedTriggerCube`,
|
||||
processCubeActiveBacking: `${prefix}-activeBacking`,
|
||||
};
|
||||
}, [resolverComponentInstanceID]);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue