From ebbfa1720d15ca31900ad6a8acff4abe36cb19a2 Mon Sep 17 00:00:00 2001 From: masillan Date: Fri, 7 Feb 2025 20:14:55 +0200 Subject: [PATCH 1/2] CSCFC4EMSCR-665 Implement new CW layout: Moved schema node info to pop up window. --- .../common/components/schema-info/index.tsx | 50 ++++++++++++++----- .../schema-info/schema-info.styles.tsx | 34 ++++++++++++- .../schema-tree/node-info/index.tsx | 6 +-- 3 files changed, 73 insertions(+), 17 deletions(-) diff --git a/mscr-ui/src/common/components/schema-info/index.tsx b/mscr-ui/src/common/components/schema-info/index.tsx index 62b3009a2..dfa85c793 100644 --- a/mscr-ui/src/common/components/schema-info/index.tsx +++ b/mscr-ui/src/common/components/schema-info/index.tsx @@ -1,6 +1,6 @@ import { useEffect, useState } from 'react'; import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; -import { Checkbox, SearchInput } from 'suomifi-ui-components'; +import {Button, Checkbox, ModalFooter, ModalTitle, SearchInput} from 'suomifi-ui-components'; import IconButton from '@mui/material/IconButton'; import ExpandLessIcon from '@mui/icons-material/ExpandLess'; import Box from '@mui/material/Box'; @@ -15,7 +15,7 @@ import { ExpandButtonWrapper, NodeInfoWrapper, SchemaHeading, - SearchWrapper, + SearchWrapper, StyledSchemaModal, StyledSchemaModalContent, TreeviewWrapper, TreeWrapper, } from '@app/common/components/schema-info/schema-info.styles'; @@ -62,6 +62,8 @@ export default function SchemaInfo(props: { const [showAttributeNames, setShowAttributeNames] = useState(true); const [treeDataOriginal, setTreeDataOriginal] = useState([]); + const [modalOpen, setModalOpen] = useState(false); + useEffect(() => { if (getSchemaData?.content) { // Get two different representations of attributes: a tree and a dictionary with keys being the node ids and @@ -180,6 +182,7 @@ export default function SchemaInfo(props: { } function handleTreeClick(nodeIds: string[]) { + setModalOpen(true); setTreeSelectedArray(nodeIds); // If there's several nodes with the same id, expand paths to all const isMultiple = nodeIds @@ -199,6 +202,7 @@ export default function SchemaInfo(props: { } function handleTreeToggle(nodeIds: string[]) { + setModalOpen(true); setTreeExpandedArray(nodeIds); } @@ -228,6 +232,10 @@ export default function SchemaInfo(props: { } } + function closeModal() { + setModalOpen(false); + } + return ( <>
@@ -320,7 +328,30 @@ export default function SchemaInfo(props: {
- + + { + setShowAttributeNames(newState.checkboxState); + }} + > + {t('schema-tree.show-titles')} + + + closeModal()} + > + +
+

closeModal()}> + × +

+
+ - - { - setShowAttributeNames(newState.checkboxState); - }} - > - {t('schema-tree.show-titles')} - - +
+
+ ); diff --git a/mscr-ui/src/common/components/schema-info/schema-info.styles.tsx b/mscr-ui/src/common/components/schema-info/schema-info.styles.tsx index 03da5d35a..e6d8f7cb1 100644 --- a/mscr-ui/src/common/components/schema-info/schema-info.styles.tsx +++ b/mscr-ui/src/common/components/schema-info/schema-info.styles.tsx @@ -1,5 +1,5 @@ import styled from 'styled-components'; -import { Heading } from 'suomifi-ui-components'; +import {Heading, Modal, ModalContent} from 'suomifi-ui-components'; export const SchemaHeading = styled(Heading)` && { @@ -102,3 +102,35 @@ export const NodeInfoWrapper = styled.div` max-width: 100%; } `; + +export const StyledSchemaModal = styled(Modal)` + background-color: ${(props) => props.theme.suomifi.colors.whiteBase}; + && { + margin: auto; + max-width: 350px; + max-height: 550px; + width: auto; + height: auto; + } + + .schema-modal-header { + display: flex; + justify-content: end; + font-size: 2rem; + height: 4rem; + } + ; + .close { + cursor: pointer; + } +`; + +export const StyledSchemaModalContent = styled(ModalContent)` + font-size: 0.9rem; + && { + padding: 5px 5px 5px 5px; + } + th { + background-color: ${(props) => props.theme.suomifi.colors.highlightLight2}; + } +`; diff --git a/mscr-ui/src/common/components/schema-info/schema-tree/node-info/index.tsx b/mscr-ui/src/common/components/schema-info/schema-tree/node-info/index.tsx index 824098db4..9fed63620 100644 --- a/mscr-ui/src/common/components/schema-info/schema-tree/node-info/index.tsx +++ b/mscr-ui/src/common/components/schema-info/schema-tree/node-info/index.tsx @@ -85,13 +85,13 @@ export default function NodeInfo(props: {

{t('node-info.selected-node-info')}

-
+
From 18704b128d24e1e1ecbadc39ea9ff2a7954c6a53 Mon Sep 17 00:00:00 2001 From: masillan Date: Sat, 8 Feb 2025 00:07:57 +0200 Subject: [PATCH 2/2] CSCFC4EMSCR-665 Implement new CW layout: Save unfinished changes. --- .../src/modules/crosswalk-editor/index.tsx | 86 +-- .../function-tooltip-box.styles.tsx | 9 + .../function-tooltip-box/index.tsx | 136 +++++ .../mappings-accordion2/index.tsx | 564 ++++++++++++++++++ .../mappings-accordion.styles.tsx | 292 +++++++++ 5 files changed, 1021 insertions(+), 66 deletions(-) create mode 100644 mscr-ui/src/modules/crosswalk-editor/mappings-accordion2/function-tooltip-box/function-tooltip-box.styles.tsx create mode 100644 mscr-ui/src/modules/crosswalk-editor/mappings-accordion2/function-tooltip-box/index.tsx create mode 100644 mscr-ui/src/modules/crosswalk-editor/mappings-accordion2/index.tsx create mode 100644 mscr-ui/src/modules/crosswalk-editor/mappings-accordion2/mappings-accordion.styles.tsx diff --git a/mscr-ui/src/modules/crosswalk-editor/index.tsx b/mscr-ui/src/modules/crosswalk-editor/index.tsx index f976064d4..44b8293fb 100644 --- a/mscr-ui/src/modules/crosswalk-editor/index.tsx +++ b/mscr-ui/src/modules/crosswalk-editor/index.tsx @@ -18,6 +18,7 @@ import Tooltip from '@mui/material/Tooltip'; import {SchemaWithContent} from "@app/common/interfaces/schema.interface"; import {Format} from "@app/common/interfaces/format.interface"; import _ from "lodash"; +import MappingsAccordion2 from "@app/modules/crosswalk-editor/mappings-accordion2"; export default function CrosswalkEditor({ crosswalkData, hasEditPermission, @@ -230,7 +231,7 @@ export default function CrosswalkEditor({ } } } - + if (isSourceTree) { setSelectedSourceNodes(nodeIds); if (isPatchMappingOperation) { @@ -249,7 +250,7 @@ export default function CrosswalkEditor({
{/* SOURCE TREE */} -
+
- {/* MID BUTTONS */} -
- {hasEditPermission && ( - 1 && - selectedTargetNodes.length > 1 - ? 'Many to many node mappings are not supported' - : !isEditModeActive - ? 'Activate edit mode to enable mappings' - : 'Map selected nodes' - } - placement="bottom" - > - 1 && - selectedTargetNodes.length > 1) || - !isEditModeActive - } - onClick={() => { - addMappingButtonClick(); - }} - > - - - - )} + +
+
+ {/* MID BUTTONS */} {/* TARGET TREE */} -
+
-
-
-
- {/*TODO: Checkbox can be removed as deprecatmappingFunctionsed when all new style titles work*/} - { - setShowAttributeNames(newState.checkboxState); - }} - > - {t('crosswalk-editor.show-node-titles')} - -
-
- -
- -
-
{mappingToBeEdited && ( { + setTooltipOpen(!tooltipOpen); + setHoverTooltipOpen(false); + }; + + interface functionParam { + key: string, + value: any + } + + function generateTexts() { + + let functionName = ''; + let functionDescription = ''; + let functionParams: functionParam[] = [] as functionParam[]; + if (props.functionName === 'predicate') { + return (<> + {props.row.predicate} +
); + } else if (props.functionName === 'mappingFunction') { + const mappingFunction = props.mappingFunctions.filter(fnc => fnc.uri === props.processingId); + if (mappingFunction.length > 0) { + functionName = mappingFunction[0].name; + functionDescription = mappingFunction[0].description; + } + return (<>

{functionName}

{functionDescription}

); + } else if (props.functionName === 'sourceOperation' || 'targetOperation') { + let node: any[] | undefined = []; + if (props.functionName === 'sourceOperation') { + node = props.row.source.filter(node => node.id === props.processingId); + } else { + node = props.row.target.filter(node => node.id === props.processingId); + } + + if (props.mappingFunctions && node.length > 0) { + const sourceOperation = props.mappingFunctions.filter(fnc => { + return node && (fnc.uri === node[0]?.processing?.id); + }); + if (node[0]?.processing?.params) { + for (const [key, value] of Object.entries(node[0]?.processing?.params)) { + if (key !== 'input') { + functionParams.push({key: key, value: value}) + } + } + } + functionName = sourceOperation[0].name; + functionDescription = sourceOperation[0].description; + } + return (<>

{functionName}

{functionDescription}

{functionParams.length > 0 ? + Parameters : ''}{functionParams.map(param => <> + {param.key}: {param.value} + )}
); + } else return ''; + } + + return ( + <> + setHoverTooltipOpen(true)} + onClose={() => setHoverTooltipOpen(false)} + + title={tooltipOpen ? 'Hide ' + props.tooltipHoverText + ' details' : 'Show ' + props.tooltipHoverText + ' details'} + placement="bottom" + > + tooltipClick()}> + {props.alternateIconLetter && + {props.alternateIconLetter} + } + {!props.alternateIconLetter && + + } + + + + setTooltipOpen(false)} + > + + {props.tooltipHeading[0].toUpperCase() + props.tooltipHeading.slice(1)} + + {tooltipOpen && generateTexts()} + + { + tooltipClick(); + props.callBackFunction.performAccordionAction( + props.row, + 'highlightFunctionField', props.processingId, props.functionName, false + ); + }} + > + Edit + + + + + + + ); +} + diff --git a/mscr-ui/src/modules/crosswalk-editor/mappings-accordion2/index.tsx b/mscr-ui/src/modules/crosswalk-editor/mappings-accordion2/index.tsx new file mode 100644 index 000000000..418c8da48 --- /dev/null +++ b/mscr-ui/src/modules/crosswalk-editor/mappings-accordion2/index.tsx @@ -0,0 +1,564 @@ +import * as React from 'react'; +import {Dispatch, SetStateAction, useEffect} from 'react'; +import Collapse from '@mui/material/Collapse'; +import Table from '@mui/material/Table'; +import TableBody from '@mui/material/TableBody'; +import TableHead from '@mui/material/TableHead'; +import TableRow from '@mui/material/TableRow'; +import Paper from '@mui/material/Paper'; +import TableCell from '@mui/material/TableCell'; +import {Button as Sbutton, SearchInput} from 'suomifi-ui-components'; +import Tooltip from '@mui/material/Tooltip'; + +import {NodeMapping} from '@app/common/interfaces/crosswalk-connection.interface'; +import {InfoIcon} from '@app/common/components/shared-icons'; +import {useTranslation} from 'next-i18next'; +import { + AccordionContainer, + EmptyBlock, + HorizontalLineMidEnd, + HorizontalLineMidStart, + HorizontalLineStart, + HorizontalLineStartSecond, + HorizontalLineTarget, + HorizontalLineTargetEnd, + HorizontalLineTargetStart, + IconSpacer, + SearchWrapper, + StyledArrowRightIcon, + StyledButton, + StyledTableActionsCell, + StyledTableButtonCell, + StyledTableCell, + StyledTableRow, + StyledTableTargetCell, + TableCellPadder, + VerticalLine +} from '@app/modules/crosswalk-editor/mappings-accordion/mappings-accordion.styles'; +import FunctionTooltipBox from "@app/modules/crosswalk-editor/mappings-accordion/function-tooltip-box"; +import ConfirmModal from "@app/common/components/confirmation-modal"; +import {Format} from "@app/common/interfaces/format.interface"; +import {SchemaWithContent} from "@app/common/interfaces/schema.interface"; + +export interface highlightOperation { + operationId: string; + nodeId?: any; +} + +function Row({row, viewOnlyMode, isEditModeActive, callBackFunction, showAttributeNames, rowcount, mappingFunctions, + schemaFormats, schemaDatas, setNodeMappingsModalOpen}: { + row: NodeMapping; + viewOnlyMode: boolean; + isEditModeActive: boolean; + callBackFunction: Function; + showAttributeNames: boolean; + rowcount: number; + mappingFunctions: any; + schemaFormats: {sourceSchemaFormat: Format | undefined, targetSchemaFormat: Format | undefined}; + schemaDatas: {sourceSchemaData: SchemaWithContent | undefined, targetSchemaData: SchemaWithContent | undefined}; + setNodeMappingsModalOpen: Dispatch>; +}) { + const { t } = useTranslation('common'); + const [open, setOpen] = React.useState(false); + + const [isDeleteMappingConfirmModalOpen, setIsDeleteMappingConfirmModalOpen] = + React.useState(false); + + function selectFromTrees(row: any, mappingId: any, isSourceTree: boolean) { + callBackFunction( + row, + 'selectFromTreesByMapping', + mappingId, + '', + isSourceTree + ); + }; + + function performDeleteMappingAction() { + setIsDeleteMappingConfirmModalOpen(false); + callBackFunction( + row, + 'removeMapping' + ); + } + + return ( + <> + + + + {row.source.map((mapping, index) => { + return (<> +
+
+ + { + selectFromTrees(row, mapping.id, true); + e.stopPropagation(); + }} + >{showAttributeNames ? mapping.label : returnPath(mapping.id, mapping.label, + schemaFormats?.sourceSchemaFormat, schemaDatas?.sourceSchemaData)} + + +
+
+
+
+ + {/* +
+
*/} + {mapping['processing']?.id && + + } + {/* +
+
*/} +
+ {index === 0 && row.source.length > 1 && } + {row.source.length > 1 && +
+
} + {index === row.source.length - 1 && row.source.length > 1 && } +
+
+ ) + } + )} + +
+ + +
+ {/* +
+
*/} + {row.processing && + + } + {!row.processing && + + } + {row.predicate && + + } + {!row.predicate && + + } + {/* +
+
*/} +
+
+ + +
+ {row.target.map((mapping, index) => { + return (<> +
+
+
+ {index === 0 && row.target.length > 1 && } + {row.target.length > 1 && +
+
} + {index === row.target.length - 1 && row.target.length > 1 && + } +
+ {mapping['processing']?.id && + <>{/* +
+
*/}{/* +
+
*/} + }{!mapping['processing']?.id && <> /*
*/} + + { + selectFromTrees(row, mapping.id, false); + e.stopPropagation(); + }} + >{showAttributeNames ? mapping.label : returnPath(mapping.id, mapping.label, + schemaFormats?.targetSchemaFormat, schemaDatas?.targetSchemaData)} +
+
+ ) + } + )} +
+ +
+ + + <> +
+ <> + + { + setNodeMappingsModalOpen(true); + callBackFunction( + row, + 'openMappingDetails' + ); + }} + > + Edit + + + + { + setIsDeleteMappingConfirmModalOpen(true); + }} + > + Delete + + + {isDeleteMappingConfirmModalOpen && { + setIsDeleteMappingConfirmModalOpen(false); + }} + text1={t('confirm-modal.do-you-want-to-delete-mapping')} + />} + + {/* + + */} +
+ +
+
+ + + + +
+
+
+ {/* +
Mapping type: exact match
+
+
*/} +
+
Mapping type:
+
{row.predicate}
+
+
+
+
+ {row.notes && + <> +
Notes:
+
{row.notes}
+ + } +
+
+
+ +
+
+
+
+
+
+
+ + ); +} + +function extractPath(strings: string[]): string { + let returnString = ""; + for (let i = 0; i < strings.length; i++) { + if (strings.length === i - 1) { + returnString = returnString + "/" + strings[i]; + } else { + let separator = "/"; + if (i === 0) { + separator = "" + } + if (i === strings.length - 2 || i === strings.length - 3 && strings.length > 3) { + separator = "/ "; + } + if (i % 2 === 0) { + returnString = returnString + separator + strings[i]; + } + } + } + return returnString; +} + +function returnFullPath(id: string) : string { + let returnString = id.substring(id?.indexOf("#root-Root-") + "#root-Root-".length); + let strings; + if (returnString) { + strings = returnString.split("-"); + returnString = ""; + if (strings.length > 1) { + returnString = extractPath(strings); + } else { + returnString = strings[0]; + } + } + return returnString; +} + +function returnPath(id: string, label: string, schemaFormat: Format | undefined, schemaData: SchemaWithContent | undefined) : string { + let returnString = ''; + if (schemaFormat === Format.Xsd || schemaFormat === Format.Csv || schemaFormat === Format.Jsonschema + || schemaFormat === Format.Enum || schemaFormat === Format.Mscr) { + returnString = id.substring(id?.indexOf("#root-Root-") + "#root-Root-".length); + let strings; + if (returnString) { + strings = returnString.split("-"); + returnString = ""; + if (strings.length > 7) { + returnString = strings[0] + "/{" + (strings.length - 5) / 2 + "}/" + strings[strings.length - 2] + "/ " + strings[strings.length - 1]; + } else if (strings.length > 1) { + returnString = extractPath(strings); + } else { + returnString = strings[0]; + } + } + return returnString; + + let className = ''; + } else if (schemaFormat === Format.Shacl) { + let definitions = schemaData?.content?.definitions; + let titleValue = undefined; + if (definitions) { + let keys = Object.keys(definitions); + if (keys && keys.length > 0) { + for (let i = 0; i < keys.length; i++) { + let value = definitions[keys[i]]; + let secondLevelKeys = Object.keys(value); + for (let k = 0; k < secondLevelKeys.length; k += 1) { + if (secondLevelKeys[k] === 'properties') { + let secondLevelValue = value[secondLevelKeys[k]]; + let thirdLevelKeys = Object.keys(secondLevelValue); + for (let j = 0; j < thirdLevelKeys.length; j += 1) { + if (thirdLevelKeys[j] === id) { + for (let l = 0; l < secondLevelKeys.length; l += 1) { + if (secondLevelKeys[l] === 'title') { + titleValue = value[secondLevelKeys[l]]; + returnString = titleValue + ':' + label; + } + } + } + } + } + } + } + } + } + if (!titleValue && label && label.toLowerCase() === 'root') { + return label; + } else if (!titleValue && label && label.toLowerCase() !== 'root') { + return 'ROOT:' + label; + } + return returnString; + } else { + return label; + } +} +function filterMappings(nodeMappingsInput: NodeMapping[], value: string, showAttributeNames: boolean) { + let results: NodeMapping[] = []; + const searchString = value.toLowerCase(); + nodeMappingsInput.forEach(item => { + let itemFound = false + if (item?.notes && item.notes.toLowerCase().includes(searchString) && !itemFound) { + results.push(item); + itemFound = true; + } + if (!itemFound) { + item.source.forEach(src => { + if (src.label.toLowerCase().includes(searchString) && !itemFound) { + results.push(item); + itemFound = true; + } + }); + } + if (!itemFound) { + item.target.forEach(src => { + if (src.label.toLowerCase().includes(searchString) && !itemFound) { + results.push(item); + itemFound = true; + } + }); + } + } + ); + return results; +} + +export default function MappingsAccordion2({nodeMappings, viewOnlyMode, isEditModeActive, showAttributeNames, + mappingFunctions, performAccordionAction, schemaFormats, schemaDatas, setNodeMappingsModalOpen} + : +{nodeMappings: NodeMapping[]; + viewOnlyMode: boolean; + isEditModeActive: boolean; + showAttributeNames: boolean; + mappingFunctions: any; + performAccordionAction: Function; + schemaFormats: {sourceSchemaFormat: Format | undefined; targetSchemaFormat: Format | undefined}; + schemaDatas: {sourceSchemaData: SchemaWithContent | undefined; targetSchemaData: SchemaWithContent | undefined; }; + setNodeMappingsModalOpen: Dispatch>; +}) { + const {t} = useTranslation('common'); + const [mappingData, setMappingData] = React.useState([]); + + useEffect(() => { + setMappingData(nodeMappings); + }, [nodeMappings]); + const nodeMappingsInput = nodeMappings; + return ( + <> + +
+

Mappings

+ + { + if (typeof value === 'string') { + setMappingData(filterMappings(nodeMappingsInput, value, showAttributeNames)); + } + }} + onChange={(value) => { + if (!value) { + setMappingData(nodeMappings); + } + }} + /> + +
+ + + {/* + + + + Source + + + + + Mapping operations + + + + Target + + + + Actions + + + + */} + + {mappingData?.length > 0 && ( + + {mappingData.map((row: NodeMapping) => { + return ( + + ); + })} + + )} + {nodeMappingsInput?.length < 1 && ( + + + + + + )} +
+
+
+ +
+
+ No elements have been mapped yet. Mappings will appear in + this table. +
+
+
+
+ + ); +} diff --git a/mscr-ui/src/modules/crosswalk-editor/mappings-accordion2/mappings-accordion.styles.tsx b/mscr-ui/src/modules/crosswalk-editor/mappings-accordion2/mappings-accordion.styles.tsx new file mode 100644 index 000000000..e36109e7d --- /dev/null +++ b/mscr-ui/src/modules/crosswalk-editor/mappings-accordion2/mappings-accordion.styles.tsx @@ -0,0 +1,292 @@ +import styled from 'styled-components'; +import ArrowRightIcon from '@mui/icons-material/ArrowRight'; +import TableCell from '@mui/material/TableCell'; +import Button from '@mui/material/Button'; +import TableRow from '@mui/material/TableRow'; +import TableContainer from '@mui/material/TableContainer'; + +export const AccordionContainer = styled(TableContainer)({ + overflow: 'hidden' +}); + +export const SearchWrapper = styled.div` + && .fi-search-input { + max-width: 300px; + margin: 15px 5px; + //margin: -5px 0px -10px 0px; + } +`; + +export const StyledArrowRightIcon = styled(ArrowRightIcon)({ + color: '#d8e3f4', + margin: '6px -6px 6px -8px' +}); + + +export const StyledTableCell = styled(TableCell)({ + height: 'auto', + minHeight: '52px', + display: 'flex', + padding: '0px 0px 0px 0px', + justifyContent: 'center', + flexDirection: 'column', + alignSelf: 'normal', +}); + +export const StyledTableTargetCell = styled(TableCell)({ + height: 'auto', + minHeight: '52px', + display: 'flex', + justifyContent: 'center', + flexDirection: 'column', + alignSelf: 'normal', + paddingLeft: '136px', +}); + +export const StyledTableActionsCell = styled(TableCell)({ + height: 'auto', + minHeight: '52px', + display: 'flex', + justifyContent: 'center', + flexDirection: 'column', + alignSelf: 'normal', + textAlign: 'right', + paddingRight: '47px' +}); + +export const StyledTableButtonCell = styled(TableCell)({ + textAlign: 'end', + display: 'flex', + justifyContent: 'end', + padding: '0px 15px', + Sbutton: { + padding: '0px 15px' + } +}); + +export const StyledButton = styled(Button)({ + display: 'flex', + justifyContent: 'start', + alignSelf: 'normal', + textTransform: 'none', + textAlign: 'initial', + lineHeight: '1.3rem', + padding: '0px' +}); + +export const StyledTableRow = styled(TableRow)(({theme}) => ({ + '&:nth-of-type(odd)': { + //backgroundColor: theme.palette.action.hover, + }, + // hide last border + '&:last-child td, &:last-child th': { + border: 0, + }, +})); + +export const StooltipContainer = styled.div` + width: 30px; + margin-left: -30px; + .fi-tooltip_content { + position: absolute; + z-index: 4; + width: 210px; + } + .fi-tooltip_toggle-button { + visibility: hidden; + } +`; + +export const TableCellPadder = styled.div` + display: flex; + padding: 0px 15px 0px 20px; +`; + +export const IconCircle = styled.div` + background: hsl(212, 63%, 37%); + height: 30px; + width: 30px; + margin: 4px -30px 4px 0px; + border-radius: 40px; + cursor: pointer; + z-index: 0; + svg { + margin-top: 4px; + margin-left: 7px; + } +`; + +export const IconCircleMid = styled.div` + background: hsl(212, 63%, 37%); + height: 30px; + width: 30px; + margin: 4px; + flex-shrink: 0; + border-radius: 40px; + cursor: pointer; + z-index: 0; + svg { + margin-top: 4px; + margin-left: 7px; + } +`; + +export const IconLetterWrap = styled.div` + margin-left: 10px; + color: #fff; + font-size: 1.1rem; +`; + +export const IconSpacer = styled.div` + height: 40px; + width: 70px; +`; + +export const HorizontalLineStart = styled.div` + width: 100%; + display: flex; + flex: 1; + justify-content: center; + flex-direction: column; + color: #fff; + font-size: 1.1rem; + div { + height: 2px; + background: #d8e3f4; + margin-left: -5px; + margin-right: 5px; + } + margin-right: -15px; + left: 15px; +`; + +export const HorizontalLineStartSecond = styled.div` + width: 100%; + display: flex; + flex: 1; + justify-content: center; + flex-direction: column; + color: #fff; + font-size: 1.1rem; + div { + height: 2px; + background: #d8e3f4; + margin-left: -5px; + margin-right: 5px; + } + max-width: 20px; + min-width: 40px; +`; + +export const HorizontalLineMidStart= styled.div` + width: 100%; + display: flex; + justify-content: center; + flex-direction: column; + color: #fff; + font-size: 1.1rem; + margin-right: -70px; + + div { + height: 2px; + background: #d8e3f4; + margin-left: -5px; + margin-right: 5px; + } +`; + +export const HorizontalLineMidEnd= styled.div` + width: 100%; + display: flex; + justify-content: center; + flex-direction: column; + color: #fff; + font-size: 1.1rem; + margin-left: -45px; + div { + height: 2px; + background: #d8e3f4; + margin-left: -5px; + margin-right: 5px; + } +`; + +export const HorizontalLineTarget= styled.div` + margin-right: -8px; + width: 100%; + display: flex; + flex: 1; + justify-content: center; + flex-direction: column; + color: #fff; + font-size: 1.1rem; + div { + height: 2px; + background: #d8e3f4; + margin-left: -5px; + margin-right: 5px; + } + max-width: 40px; + min-width: 115px; +`; + +export const HorizontalLineTargetStart = styled.div` + width: 100%; + display: flex; + flex: 1; + justify-content: center; + flex-direction: column; + color: #fff; + font-size: 1.1rem; + div { + height: 2px; + background: #d8e3f4; + margin-left: -5px; + margin-right: 5px; + } + min-width: 50px; + margin-right: -13px; +`; + +export const HorizontalLineTargetEnd = styled.div` + width: 100%; + display: flex; + flex: 1; + justify-content: center; + flex-direction: column; + color: #fff; + font-size: 1.1rem; + div { + height: 2px; + background: #d8e3f4; + margin-left: -5px; + margin-right: 5px; + } + min-width: 40px; + margin-right: -8px; +`; + + + +export const VerticalLine = styled.div` + display: flex; + justify-content: start; + flex-direction: row; + color: #fff; + font-size: 1.1rem; + height: 100%; + div { + width: 2px; + background: #d8e3f4; + margin-left: -5px; + } +`; + +export const EmptyBlock = styled.div` + display: flex; + justify-content: start; + flex-direction: row; + color: #fff; + height: 100%; + margin: -1px 0px; +`;