From 4a79acfc267a85cb1f673bdbad0504c91d5568cb Mon Sep 17 00:00:00 2001 From: Tiia Valtonen Date: Mon, 15 Mar 2021 12:57:29 +0200 Subject: [PATCH 01/35] 150 - limit robotframework's version to be 3.2.2 --- backend_server/tests/requirements.txt | 3 --- end_to_end_tests/requirements.txt | 8 ++++---- 2 files changed, 4 insertions(+), 7 deletions(-) delete mode 100644 backend_server/tests/requirements.txt diff --git a/backend_server/tests/requirements.txt b/backend_server/tests/requirements.txt deleted file mode 100644 index 97051638..00000000 --- a/backend_server/tests/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -robotframework==3.1.2 -RESTinstance==1.0.2 -robotframework-requests==0.6.5 diff --git a/end_to_end_tests/requirements.txt b/end_to_end_tests/requirements.txt index 909bd3a1..9dcf8e08 100644 --- a/end_to_end_tests/requirements.txt +++ b/end_to_end_tests/requirements.txt @@ -1,8 +1,8 @@ -# Requirements for running the robot tests, -# also make sure the execution machine has webdriver in PATH. -robotframework >= 3.1.2 +# Requirements for running the robot tests, +# also make sure the execution machine has webdriver in PATH. +robotframework >= 3.2.2 robotframework-seleniumlibrary >= 4.3.0 psycopg2-binary == 2.8.5 requests==2.23.0 RESTinstance==1.0.2 -robotframework-requests==0.6.5 \ No newline at end of file +robotframework-requests==0.6.5 From 8be5f4c97f507a0382c353623c34ff8883d0acdd Mon Sep 17 00:00:00 2001 From: Tiia Valtonen Date: Fri, 19 Mar 2021 13:27:12 +0200 Subject: [PATCH 02/35] Feature/148 - Create a reusable tab component (#149) * Create a new tab component and styles for it * Refactor 'ContentHeader' to use the new tab component * Remove a header that was not in the UI pictures and add a header that was missing from 'History' view * Fix checkboxes' focus styles --- .../buttons/LastRunCheckbox.styles.js | 2 +- .../src/components/header/ContentHeader.jsx | 58 +++++++------------ .../components/header/ContentHeader.styles.js | 44 -------------- frontend/src/components/tablist/Tab.jsx | 25 ++++++++ frontend/src/components/tablist/Tab.styles.js | 34 +++++++++++ frontend/src/locales/en/parentData.json | 2 +- frontend/src/pages/History.jsx | 8 +-- 7 files changed, 84 insertions(+), 89 deletions(-) delete mode 100644 frontend/src/components/header/ContentHeader.styles.js create mode 100644 frontend/src/components/tablist/Tab.jsx create mode 100644 frontend/src/components/tablist/Tab.styles.js diff --git a/frontend/src/components/buttons/LastRunCheckbox.styles.js b/frontend/src/components/buttons/LastRunCheckbox.styles.js index 3ac5ef33..5efd4a06 100644 --- a/frontend/src/components/buttons/LastRunCheckbox.styles.js +++ b/frontend/src/components/buttons/LastRunCheckbox.styles.js @@ -45,7 +45,7 @@ export const StyledInput = styled.input` appearance: none; opacity: 0; position: absolute; - top: 3px; + top: 8px; height: 16px; width: 16px; border-radius: 2px; diff --git a/frontend/src/components/header/ContentHeader.jsx b/frontend/src/components/header/ContentHeader.jsx index 5c60514b..4d594254 100644 --- a/frontend/src/components/header/ContentHeader.jsx +++ b/frontend/src/components/header/ContentHeader.jsx @@ -2,21 +2,13 @@ import React from 'react'; import { useLocation } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { useStateValue } from '../../contexts/state'; -import { - LinkContainer, - OverviewLink, - HistoryLink, - AnalysisLink, -} from './ContentHeader.styles'; import { ContainerGrid12, ContentGrid6 } from '../../styles/baseComponents'; +import Tab from '../tablist/Tab'; const ContentHeader = () => { const [t] = useTranslation(['header']); const pathname = useLocation().pathname; - const overviewUrl = pathname.includes('overview'); - const historyUrl = pathname.includes('history'); - const analysisUrl = pathname.includes('analysis'); const buildUrl = pathname.includes('build'); const suiteUrl = pathname.includes('suite'); @@ -78,38 +70,28 @@ const ContentHeader = () => { : beginningUrl.concat('/' + prop + '?' + numberOfBuildsUrl); }; + const tabLinks = [ + { to: correctUrl('overview'), translation: t('buttons.overview') }, + { to: correctUrl('history'), translation: t('buttons.history') }, + ]; + if (buildUrl) { + tabLinks.push({ + to: correctUrl('analysis'), + translation: t('buttons.analysis'), + }); + } + return ( <> {(seriesData || buildData) && ( - - -

{formHeader()}

- {!selectedSuiteState && ( - - - {t('buttons.overview')} - - - {t('buttons.history')} - - {buildUrl && ( - - {t('buttons.analysis')} - - )} - - )} -
-
+ <> + + +

{formHeader()}

+
+
+ {!selectedSuiteState && } + )} ); diff --git a/frontend/src/components/header/ContentHeader.styles.js b/frontend/src/components/header/ContentHeader.styles.js deleted file mode 100644 index 4e7e3f95..00000000 --- a/frontend/src/components/header/ContentHeader.styles.js +++ /dev/null @@ -1,44 +0,0 @@ -import styled from 'styled-components'; -import React from 'react'; -import { NavLink } from 'react-router-dom'; - -export const LinkContainer = styled.div` - padding: 10px 0; - - a { - margin-left: 10px; - &:first-child { - margin-left: 0; - } - } -`; - -// eslint-disable-next-line no-unused-vars -export const StyledLink = styled(({ overview, ...props }) => ( - -))` - width: 100px; - margin: 10px 15px 10px 0; - cursor: pointer; - color: var(--titan-green); - background: var(--nero-white) !important; - text-decoration: none !important; - font-size: 16px; - font-weight: bold; - line-height: 24px; -`; - -export const OverviewLink = styled(StyledLink)` - color: ${props => props.overview && 'var(--pirlo-blue) !important'}; - border-bottom: ${props => props.overview && '4px solid var(--pirlo-blue)'}; -`; - -export const HistoryLink = styled(StyledLink)` - color: ${props => props.history && 'var(--pirlo-blue) !important'}; - border-bottom: ${props => props.history && '4px solid var(--pirlo-blue)'}; -`; - -export const AnalysisLink = styled(StyledLink)` - color: ${props => props.analysis && 'var(--pirlo-blue) !important'}; - border-bottom: ${props => props.analysis && '4px solid var(--pirlo-blue)'}; -`; diff --git a/frontend/src/components/tablist/Tab.jsx b/frontend/src/components/tablist/Tab.jsx new file mode 100644 index 00000000..26f733a8 --- /dev/null +++ b/frontend/src/components/tablist/Tab.jsx @@ -0,0 +1,25 @@ +import React from 'react'; +import { Tabs, TabLink } from './Tab.styles'; +import { ContainerGrid12, ContentGrid6 } from '../../styles/baseComponents'; + +const Tab = props => { + const { tabLinks } = props; + + const tabLinkItems = tabLinks.map(element => { + return ( + + {element.translation} + + ); + }); + + return ( + + + {tabLinkItems} + + + ); +}; + +export default Tab; diff --git a/frontend/src/components/tablist/Tab.styles.js b/frontend/src/components/tablist/Tab.styles.js new file mode 100644 index 00000000..420098ca --- /dev/null +++ b/frontend/src/components/tablist/Tab.styles.js @@ -0,0 +1,34 @@ +import styled from 'styled-components'; +import React from 'react'; +import { NavLink } from 'react-router-dom'; + +export const Tabs = styled.nav` + display: block; + border-bottom: 1px solid var(--tonic-grey); +`; + +export const TabLink = styled(({ ...props }) => )` + display: inline-block; + height: 37px; + background: var(--nero-white) !important; + color: var(--titan-green); + position: relative; + top: 3px; + margin-right: var(--space-24); + font-size: var(--space-16); + font-weight: bold; + line-height: var(--space-24); + text-decoration: none !important; + + &.active { + color: var(--pirlo-blue); + border-bottom: var(--space-4) solid var(--pirlo-blue); + height: var(--space-40); + } + + &:hover { + color: var(--titan-green); + border-bottom: var(--space-4) solid var(--tonic-grey); + height: var(--space-40); + } +`; diff --git a/frontend/src/locales/en/parentData.json b/frontend/src/locales/en/parentData.json index 63e5d36f..f075ddd3 100644 --- a/frontend/src/locales/en/parentData.json +++ b/frontend/src/locales/en/parentData.json @@ -1,3 +1,3 @@ { - "title": "Last Build Information" + "test_result_history": "Test result history for series" } diff --git a/frontend/src/pages/History.jsx b/frontend/src/pages/History.jsx index 376c1b08..2ba5ed6c 100644 --- a/frontend/src/pages/History.jsx +++ b/frontend/src/pages/History.jsx @@ -85,11 +85,6 @@ const History = () => { - - -

{t('title')}

-
-
@@ -101,6 +96,9 @@ const History = () => { +

+ {t('test_result_history')} {selectedBranchState.name} +

From f5cef9037935402637eb5bed868feb888d84bff0 Mon Sep 17 00:00:00 2001 From: Tiia Valtonen Date: Thu, 11 Mar 2021 10:17:01 +0200 Subject: [PATCH 03/35] 143 - Create a reusable table that supports both table styles: SpreadSheetTable and SimpleTable --- frontend/src/components/table/Table.jsx | 34 +++ frontend/src/components/table/Table.styles.js | 228 ++++++++++++++++++ 2 files changed, 262 insertions(+) create mode 100644 frontend/src/components/table/Table.jsx create mode 100644 frontend/src/components/table/Table.styles.js diff --git a/frontend/src/components/table/Table.jsx b/frontend/src/components/table/Table.jsx new file mode 100644 index 00000000..69b721ae --- /dev/null +++ b/frontend/src/components/table/Table.jsx @@ -0,0 +1,34 @@ +import React from 'react'; +import { + OverflowWrapper, + SimpleTable, + SpreadSheetTable, + TableWrapper, +} from './Table.styles'; +import ScrollTableButton from './ScrollTableButton'; + +export const TableSpreadSheet = props => { + const tableId = props['table-id']; + + return ( + + + + {props.children} + + + ); +}; + +export const TableSimple = props => { + const tableId = props['table-id']; + + return ( + + + + {props.children} + + + ); +}; diff --git a/frontend/src/components/table/Table.styles.js b/frontend/src/components/table/Table.styles.js new file mode 100644 index 00000000..bdde405e --- /dev/null +++ b/frontend/src/components/table/Table.styles.js @@ -0,0 +1,228 @@ +import styled from 'styled-components'; + +export const TableWrapper = styled.div` + position: relative; +`; + +export const OverflowWrapper = styled.div` + overflow-x: auto; + position: relative; + width: 100%; +`; + +export const SpreadSheetTable = styled.table` + width: 100%; + border-collapse: separate; + font-size: 14px; + line-height: 20px; + border: 1px solid var(--evidence-grey-lighter); + border-radius: var(--space-8); + border-spacing: 0; + overflow: hidden; + + thead { + text-align: left; + + tr th { + padding: var(--space-8) var(--space-16) var(--space-4) 0; + background-color: var(--hermanni-grey); + + &:first-of-type { + padding-left: var(--space-8); + } + + &:last-of-type { + padding-right: var(--space-8); + } + } + } + + tbody { + tr { + vertical-align: top; + + &:hover { + background-color: var(--kumpula-yellow); + } + + td { + border-bottom: 1px solid var(--hermanni-grey); + position: relative; + padding: var(--space-4) var(--space-16) var(--space-4) 0; + + &:first-of-type { + padding-left: var(--space-8); + } + + &:last-of-type { + padding-right: var(--space-8); + } + + a { + &:visited { + color: var(--evidence-grey); + } + } + } + } + } + + a { + text-decoration: none; + + &:hover { + text-decoration: underline; + } + + &:active { + color: var(--pirlo-blue); + } + } +`; + +export const SimpleTable = styled.table` + width: 100%; + border-collapse: collapse; + font-size: 14px; + line-height: 20px; + + thead { + text-align: left; + + & tr th { + padding: var(--space-8) 0 var(--space-4) 0; + } + } + + tbody { + tr { + border-bottom: 1px solid var(--hermanni-grey); + vertical-align: top; + + &:hover { + background-color: var(--kumpula-yellow); + } + + &:last-of-type { + border-bottom: 0; + } + + td { + padding: 1px 0; + position: relative; + + &:first-of-type { + padding-left: 2px; + } + + &::before { + content: ''; + width: 100%; + height: 1px; + background: white; + position: absolute; + top: 0; + left: 0; + } + + &::after { + content: ''; + width: 100%; + height: 1px; + background: white; + position: absolute; + bottom: 0; + left: 0; + } + + a { + &:visited { + color: var(--evidence-grey); + } + } + } + } + } + + a { + text-decoration: none; + + &:hover { + text-decoration: underline; + } + + &:active { + color: var(--pirlo-blue); + } + } +`; + +export const WideTh = styled.th` + min-width: 200px; +`; + +export const NarrowTh = styled.th` + max-width: 160px; +`; + +function calculateSpanMargin() { + let spansMarginRules = []; + + for (let i = 0; i < 11; i++) { + spansMarginRules.push( + `span:nth-of-type(${i}) { + margin-left: ${8 * i}px; + display: inline-block; + }` + ); + } + + return spansMarginRules; +} + +export const HierarchicalSuiteNameTh = styled.th` + font-weight: normal; + text-align: left; + border-top: 1px solid var(--hermanni-grey); + + & ~ td { + border-top: 1px solid var(--hermanni-grey); + } + + a { + &:hover { + background-color: transparent; + + span { + text-decoration: underline; + background-color: var(--hermanni-grey-lighter); + } + } + } + + ${calculateSpanMargin()}; +`; + +export const SuiteRow = styled.tr` + border-top: ${props => props.position !== 0 && 'none !important'}; + + &:hover { + th { + background-color: var(--nero-white); + } + } + + th:hover { + & ~ td { + background: white; + } + } + + td { + border-bottom: 0 !important; + + &:first-of-type { + padding-left: 0 !important; + } + } +`; From e3a47ab582773baae68cbdef5dcaa597b19acd3b Mon Sep 17 00:00:00 2001 From: Tiia Valtonen Date: Thu, 11 Mar 2021 07:48:51 +0200 Subject: [PATCH 04/35] 143 - Create scroll buttons for table that are enabled when table is scrollable (takes into account window resize and scrolling without using the scroll buttons) --- .../buttons/DropdownSelect.styles.js | 1 + .../components/table/ScrollTableButton.jsx | 30 +++++ .../table/ScrollTableButton.styles.js | 57 ++++++++++ frontend/src/components/table/Table.jsx | 106 +++++++++++++++--- frontend/src/components/table/Table.styles.js | 1 + 5 files changed, 179 insertions(+), 16 deletions(-) create mode 100644 frontend/src/components/table/ScrollTableButton.jsx create mode 100644 frontend/src/components/table/ScrollTableButton.styles.js diff --git a/frontend/src/components/buttons/DropdownSelect.styles.js b/frontend/src/components/buttons/DropdownSelect.styles.js index 26a8a751..6f12232a 100644 --- a/frontend/src/components/buttons/DropdownSelect.styles.js +++ b/frontend/src/components/buttons/DropdownSelect.styles.js @@ -56,6 +56,7 @@ export const DropdownWrapper = styled.div` border-radius: 4px; box-shadow: 0 3px 5px 1px var(--tonic-grey); padding: 5px 3px; + z-index: 10; } .ReactA11ySelect__ul__li:focus { diff --git a/frontend/src/components/table/ScrollTableButton.jsx b/frontend/src/components/table/ScrollTableButton.jsx new file mode 100644 index 00000000..f85f3771 --- /dev/null +++ b/frontend/src/components/table/ScrollTableButton.jsx @@ -0,0 +1,30 @@ +import React from 'react'; +import { ScrollButton } from './ScrollTableButton.styles'; +import ChevronRight from '../../images/chevron-right.svg'; +import ChevronLeft from '../../images/chevron-left.svg'; + +const ScrollTableButton = props => { + const { canScrollLeft, canScrollRight } = props; + + return ( + <> + props.moveLeft()} + disabled={!canScrollLeft} + > + > + + + props.moveRight()} + disabled={!canScrollRight} + > + > + + + ); +}; + +export default ScrollTableButton; diff --git a/frontend/src/components/table/ScrollTableButton.styles.js b/frontend/src/components/table/ScrollTableButton.styles.js new file mode 100644 index 00000000..4b848778 --- /dev/null +++ b/frontend/src/components/table/ScrollTableButton.styles.js @@ -0,0 +1,57 @@ +import styled from 'styled-components'; + +export const ScrollButton = styled.button` + position: absolute; + height: 100%; + width: 50px; + background: white; + top: 0; + border: 0; + + &::before { + position: absolute; + top: 0; + content: ''; + width: 20px; + height: 100%; + z-index: 1; + } + + &[disabled] { + opacity: 0.2; + + &::before { + content: none; + } + } + + &.left { + left: -50px; + + &::before { + right: -20px; + background-image: linear-gradient( + to left, + rgba(255, 255, 255, 0.001), + var(--hermanni-grey) + ); + } + } + + &.right { + right: -50px; + + &::before { + left: -20px; + background-image: linear-gradient( + to right, + rgba(255, 255, 255, 0.001), + var(--hermanni-grey) + ); + } + } + + img { + width: 15px; + } +`; diff --git a/frontend/src/components/table/Table.jsx b/frontend/src/components/table/Table.jsx index 69b721ae..926a800e 100644 --- a/frontend/src/components/table/Table.jsx +++ b/frontend/src/components/table/Table.jsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { OverflowWrapper, SimpleTable, @@ -7,27 +7,101 @@ import { } from './Table.styles'; import ScrollTableButton from './ScrollTableButton'; -export const TableSpreadSheet = props => { +export const Table = props => { const tableId = props['table-id']; + const simpleTable = props['simple-table']; + const ref = React.createRef(); - return ( - - - - {props.children} - - - ); -}; + const [canScrollLeft, setCanScrollLeft] = useState(false); + const [canScrollRight, setCanScrollRight] = useState(false); + const [scrollPosition, setScrollPosition] = useState(0); + const [windowSize, setWindowSize] = useState([0, 0]); + const maxScrollLeft = React.useRef(0); -export const TableSimple = props => { - const tableId = props['table-id']; + // Checks if table is scrolled using other methods than scrollButtons (e.g. keyboard / mouse) ==> scrollPosition + useEffect(() => { + const savedRef = ref.current; + + function updateScrollPosition() { + setScrollPosition(savedRef.scrollLeft); + } + + savedRef.addEventListener('scroll', updateScrollPosition); + updateScrollPosition(); + + return () => + savedRef.removeEventListener('scroll', updateScrollPosition); + }, [ref]); + + // Checks if window is resized ==> windowSize + useEffect(() => { + function updateWindowSize() { + setWindowSize([window.innerWidth, window.innerHeight]); + } + + window.addEventListener('resize', updateWindowSize); + updateWindowSize(); + + return () => window.removeEventListener('resize', updateWindowSize); + }, []); + + // Checks if table is scrollable and decides to which directions it's scrollable + useEffect(() => { + maxScrollLeft.current = + ref.current.scrollWidth - ref.current.clientWidth; + + // check that table is scrollable and it has not been scrolled + if (maxScrollLeft.current !== 0 && scrollPosition === 0) { + setCanScrollRight(true); + setCanScrollLeft(false); + } + + // show scroll left and right button + if (scrollPosition !== 0) { + setCanScrollLeft(true); + setCanScrollRight(true); + } + + // hide scroll left button when there's nothing to scroll + if (scrollPosition === 0) { + setCanScrollLeft(false); + } + + // hide scroll right button when there's nothing to scroll + if ( + scrollPosition === maxScrollLeft.current || + scrollPosition === maxScrollLeft.current - 1 + ) { + setCanScrollRight(false); + } + }, [ref, scrollPosition, windowSize]); + + function moveRight() { + ref.current.scrollLeft += 150; + setScrollPosition(scrollPosition + 150); + } + + function moveLeft() { + ref.current.scrollLeft -= 150; + setScrollPosition(scrollPosition - 150); + } return ( - - - {props.children} + moveRight()} + moveLeft={() => moveLeft()} + /> + + {simpleTable ? ( + {props.children} + ) : ( + + {props.children} + + )} ); diff --git a/frontend/src/components/table/Table.styles.js b/frontend/src/components/table/Table.styles.js index bdde405e..a1c43cc5 100644 --- a/frontend/src/components/table/Table.styles.js +++ b/frontend/src/components/table/Table.styles.js @@ -8,6 +8,7 @@ export const OverflowWrapper = styled.div` overflow-x: auto; position: relative; width: 100%; + scroll-behavior: smooth; `; export const SpreadSheetTable = styled.table` From c16eb4942214eb55f203fc9ce576568f950a45cf Mon Sep 17 00:00:00 2001 From: Tiia Valtonen Date: Thu, 11 Mar 2021 12:41:32 +0200 Subject: [PATCH 05/35] 143 - Add vertical hover for a single build in All build's table --- .../src/components/historyTable/Heading.jsx | 28 +++++++++++++++---- .../components/historyTable/Heading.styles.js | 10 +++---- .../components/historyTable/HistoryTable.jsx | 27 ++++++++++++++++++ .../components/historyTable/TestStatus.jsx | 11 +++++++- 4 files changed, 64 insertions(+), 12 deletions(-) create mode 100644 frontend/src/components/historyTable/HistoryTable.jsx diff --git a/frontend/src/components/historyTable/Heading.jsx b/frontend/src/components/historyTable/Heading.jsx index f42198d5..0da93a4d 100644 --- a/frontend/src/components/historyTable/Heading.jsx +++ b/frontend/src/components/historyTable/Heading.jsx @@ -1,13 +1,30 @@ import React from 'react'; import { useStateValue } from '../../contexts/state'; import { StyledLink, BuildNumberCell } from './Heading.styles'; +import { colorTypes } from '../../utils/colorTypes'; // helper for build number sorting function compareNumbers(a, b) { return a - b; } -const Heading = () => { +export function addBgColor(id) { + const elements = document.getElementsByClassName(id); + + for (let item of elements) { + item.style.backgroundColor = colorTypes['kumpula yellow']; + } +} + +export function removeBgColor(id) { + const elements = document.getElementsByClassName(id); + + for (let item of elements) { + item.style = ''; + } +} + +export const Heading = () => { const [ { historyDataState: { max_build_num }, @@ -41,6 +58,9 @@ const Heading = () => { handleBuildClick(e)} + onMouseEnter={() => addBgColor(`id-${buildNumber}`)} + onMouseLeave={() => removeBgColor(`id-${buildNumber}`)} + className={`id-${buildNumber}`} > Build @@ -51,12 +71,10 @@ const Heading = () => { return ( - Suite - Test + Suite + Test {buildNumbers} ); }; - -export default Heading; diff --git a/frontend/src/components/historyTable/Heading.styles.js b/frontend/src/components/historyTable/Heading.styles.js index c4df1909..60f63f0a 100644 --- a/frontend/src/components/historyTable/Heading.styles.js +++ b/frontend/src/components/historyTable/Heading.styles.js @@ -8,16 +8,14 @@ export const StyledLink = styled(Link)` padding: 0px; text-align: center; height: 100%; - transition: 0.33s background-color; text-decoration: none; - .buildNumber:hover { - background: var(--hermanni-grey-lighter); + &:hover { + background-color: transparent; } `; export const BuildNumberCell = styled.th` - :hover { - background: var(--hermanni-grey-lighter); - } + padding-right: var(--space-8) !important; + padding-left: var(--space-8) !important; `; diff --git a/frontend/src/components/historyTable/HistoryTable.jsx b/frontend/src/components/historyTable/HistoryTable.jsx new file mode 100644 index 00000000..5249fa54 --- /dev/null +++ b/frontend/src/components/historyTable/HistoryTable.jsx @@ -0,0 +1,27 @@ +import React from 'react'; +import { Heading } from './Heading'; +import Body from './Body'; +import NotFound from '../NotFound'; +import { useStateValue } from '../../contexts/state'; +import { Table } from '../table/Table'; + +const HistoryTable = () => { + const [ + { + historyDataState: { max_build_num }, + }, + ] = useStateValue(); + + if (max_build_num > 0) { + return ( + + + +
+ ); + } else { + return ; + } +}; + +export default HistoryTable; diff --git a/frontend/src/components/historyTable/TestStatus.jsx b/frontend/src/components/historyTable/TestStatus.jsx index 40a02c81..97ae5b77 100644 --- a/frontend/src/components/historyTable/TestStatus.jsx +++ b/frontend/src/components/historyTable/TestStatus.jsx @@ -2,6 +2,7 @@ import React from 'react'; import { useStateValue } from '../../contexts/state'; import { pickIcon } from '../TestIcon'; import { DefinedData } from './TestStatus.styles'; +import { addBgColor, removeBgColor } from './Heading'; const TableTestStatusCell = ({ builds, position }) => { const [ @@ -25,6 +26,7 @@ const TableTestStatusCell = ({ builds, position }) => { suite_start_time: '', }); } + return arr.map((filledBuild, i) => { let test_status; try { @@ -43,10 +45,17 @@ const TableTestStatusCell = ({ builds, position }) => { return ( + addBgColor(`id-${filledBuild.build_number}`) + } + onMouseLeave={() => + removeBgColor(`id-${filledBuild.build_number}`) + } > {testStatusIcon} From c6be5f65bd401a16ad7654840bedd6d5732e5fab Mon Sep 17 00:00:00 2001 From: Tiia Valtonen Date: Wed, 10 Mar 2021 12:30:33 +0200 Subject: [PATCH 06/35] 143 - Unify table styles and use the new table component --- .../resources/page_locators/build_page.robot | 2 +- frontend/README.md | 8 + frontend/src/components/buildTable/Body.jsx | 28 ++-- .../src/components/buildTable/BuildTable.jsx | 28 ++++ .../src/components/buildTable/Error.styles.js | 7 +- frontend/src/components/buildTable/Row.jsx | 6 +- .../src/components/buildTable/Row.styles.js | 38 ----- frontend/src/components/buildTable/Table.jsx | 40 ----- .../src/components/buildTable/Table.styles.js | 51 ------ .../src/components/buildTable/TestCase.jsx | 5 +- .../components/buildTable/TextCase.styles.js | 5 - .../dashlist/KeywordAnalysisTable.jsx | 86 +++++----- frontend/src/components/historyTable/Body.jsx | 2 +- .../src/components/historyTable/Heading.jsx | 5 +- .../src/components/historyTable/Suite.jsx | 5 +- .../src/components/historyTable/SuiteName.jsx | 6 +- .../historyTable/SuiteName.styles.js | 39 ----- .../src/components/historyTable/Table.jsx | 34 ---- .../components/historyTable/Table.styles.js | 84 ---------- .../src/components/historyTable/TestCase.jsx | 5 +- .../historyTable/TestCase.styles.js | 9 -- .../historyTable/TestStatus.styles.js | 4 +- frontend/src/components/suite/LogMessages.jsx | 98 +++++------- .../components/suite/LogMessages.styles.js | 90 +++-------- .../suite/SuiteLogMessage.styles.js | 10 +- frontend/src/pages/Analysis.jsx | 6 +- frontend/src/pages/Build.jsx | 4 +- frontend/src/pages/History.jsx | 4 +- frontend/src/styles/baseComponents.js | 148 ++++++++++++++++++ 29 files changed, 347 insertions(+), 510 deletions(-) create mode 100644 frontend/src/components/buildTable/BuildTable.jsx delete mode 100644 frontend/src/components/buildTable/Row.styles.js delete mode 100644 frontend/src/components/buildTable/Table.jsx delete mode 100644 frontend/src/components/buildTable/Table.styles.js delete mode 100644 frontend/src/components/buildTable/TextCase.styles.js delete mode 100644 frontend/src/components/historyTable/SuiteName.styles.js delete mode 100644 frontend/src/components/historyTable/Table.jsx delete mode 100644 frontend/src/components/historyTable/Table.styles.js delete mode 100644 frontend/src/components/historyTable/TestCase.styles.js diff --git a/end_to_end_tests/resources/page_locators/build_page.robot b/end_to_end_tests/resources/page_locators/build_page.robot index b117d971..a1a93468 100644 --- a/end_to_end_tests/resources/page_locators/build_page.robot +++ b/end_to_end_tests/resources/page_locators/build_page.robot @@ -8,4 +8,4 @@ ${pass_span} xpath://*[@id="last-run-table"]/tbody/tr[*]/td[*]/span[ ${fail_span} xpath://*[@id="last-run-table"]/tbody/tr[*]/td[*]/span[text()='Fail'] ${last_run_table} xpath://*[@id="last-run-table"] -${first_suite} xpath://*[@id="last-run-table"]/tbody/tr[1]/td[1]/a +${first_suite} xpath://*[@id="last-run-table"]/tbody/tr[1]/th[1]/a diff --git a/frontend/README.md b/frontend/README.md index 002bb427..92406371 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -55,3 +55,11 @@ and ``` Editor: Format On Save ``` + +## Z-indexes +List of z-indexes used in order to avoid z-index collision and to help debugging. Please list the component that z-index is used in, the z-index itself and the reason z-index was used. + +- *DropdownSelect*: ```z-index: 2;``` + - The dropdown would be under ScrollTableButton's pseudo element. +- *ScrollTableButton*: ```z-index: 1;``` + - Table's header or hover effects would be on top of the scroll button. diff --git a/frontend/src/components/buildTable/Body.jsx b/frontend/src/components/buildTable/Body.jsx index 6a66e74e..3fbccd99 100644 --- a/frontend/src/components/buildTable/Body.jsx +++ b/frontend/src/components/buildTable/Body.jsx @@ -94,18 +94,22 @@ const Body = () => { }); } - return filteredRowData.map( - ({ test_cases, suite_full_name, suite_id }, i) => { - return ( - - ); - } + return ( + + {filteredRowData.map( + ({ test_cases, suite_full_name, suite_id }, i) => { + return ( + + ); + } + )} + ); }; diff --git a/frontend/src/components/buildTable/BuildTable.jsx b/frontend/src/components/buildTable/BuildTable.jsx new file mode 100644 index 00000000..8c1dd4d6 --- /dev/null +++ b/frontend/src/components/buildTable/BuildTable.jsx @@ -0,0 +1,28 @@ +// eslint-disable-next-line +import React from 'react'; +import Body from './Body'; +import { useTranslation } from 'react-i18next'; +import { Table } from '../table/Table'; +import { WideTh } from '../table/Table.styles'; + +const BuildTable = ({ id }) => { + const [t] = useTranslation(['history']); + + return ( + + + + {t('build.table.suite')} + + + {t('build.table.error')} + + + + + +
{t('build.table.status')}{t('build.table.test')}{t('build.table.time')}{t('build.table.flakiness')}
+ ); +}; + +export default BuildTable; diff --git a/frontend/src/components/buildTable/Error.styles.js b/frontend/src/components/buildTable/Error.styles.js index 39f061d6..0bc8d3b5 100644 --- a/frontend/src/components/buildTable/Error.styles.js +++ b/frontend/src/components/buildTable/Error.styles.js @@ -1,8 +1,11 @@ import styled from 'styled-components'; export const ErrorMsg = styled.td` - background: ${props => - props.build.status === 'FAIL' && 'var(--arabia-red) !important'}; font-size: 10px; line-height: 14px; + & > span { + display: block; + background: ${props => + props.build.status === 'FAIL' && 'var(--arabia-red) !important'}; + } `; diff --git a/frontend/src/components/buildTable/Row.jsx b/frontend/src/components/buildTable/Row.jsx index 409413ab..8fc1aea4 100644 --- a/frontend/src/components/buildTable/Row.jsx +++ b/frontend/src/components/buildTable/Row.jsx @@ -8,7 +8,7 @@ import { dashify } from '../../utils/helpers'; import { useLocation } from 'react-router'; import { Link } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; -import { SuiteRow, LinkSuiteName } from './Row.styles'; +import { HierarchicalSuiteNameTh, SuiteRow } from '../table/Table.styles'; const Row = ({ test_cases, suite, id, suiteId }) => { const tableRow = test_cases.map(({ builds, test_id }, index) => { @@ -75,7 +75,7 @@ const LinksSuiteName = ({ tableCellHeight, suiteName, suiteId }) => { } return ( - @@ -83,6 +83,6 @@ const LinksSuiteName = ({ tableCellHeight, suiteName, suiteId }) => {
{t('build.table.row.build')}
{splitSuiteName} -
+ ); }; diff --git a/frontend/src/components/buildTable/Row.styles.js b/frontend/src/components/buildTable/Row.styles.js deleted file mode 100644 index 0880355e..00000000 --- a/frontend/src/components/buildTable/Row.styles.js +++ /dev/null @@ -1,38 +0,0 @@ -import styled from 'styled-components'; - -export const SuiteRow = styled.tr` - border-top: ${props => props.position !== 0 && 'none !important'}; -`; - -export const LinkSuiteName = styled.td` - span { - display: inline-block; - } - span:nth-child(4) { - margin-left: 8px; - } - span:nth-child(6) { - margin-left: 16px; - } - span:nth-child(8) { - margin-left: 24px; - } - span:nth-child(10) { - margin-left: 32px; - } - span:nth-child(12) { - margin-left: 40px; - } - span:nth-child(14) { - margin-left: 48px; - } - span:nth-child(16) { - margin-left: 56px; - } - span:nth-child(18) { - margin-left: 64px; - } - span:nth-child(20) { - margin-left: 72px; - } -`; diff --git a/frontend/src/components/buildTable/Table.jsx b/frontend/src/components/buildTable/Table.jsx deleted file mode 100644 index f116f122..00000000 --- a/frontend/src/components/buildTable/Table.jsx +++ /dev/null @@ -1,40 +0,0 @@ -// eslint-disable-next-line -import React from 'react'; -import Body from './Body'; -import { useTranslation } from 'react-i18next'; -import { StyledTable, HeaderRow } from './Table.styles'; -import { OverflowWrapper, TableWrapper } from '../historyTable/Table.styles'; - -const Table = ({ id }) => { - const [t] = useTranslation(['history']); - - return ( - - - - - - {t('build.table.suite')} - - {t('build.table.status')} - - {t('build.table.test')} - {t('build.table.error')} - - {t('build.table.time')} - - - {t('build.table.flakiness')} - - - - - - - - - - ); -}; - -export default Table; diff --git a/frontend/src/components/buildTable/Table.styles.js b/frontend/src/components/buildTable/Table.styles.js deleted file mode 100644 index 73d88239..00000000 --- a/frontend/src/components/buildTable/Table.styles.js +++ /dev/null @@ -1,51 +0,0 @@ -import { baseTable } from '../../styles/baseComponents'; -import styled from 'styled-components'; - -export const StyledTable = styled(baseTable)` - table-layout: initial; - overflow: auto; - border: 1px solid var(--hermanni-grey); - border-radius: 8px; - position: relative; - width: 100%; - - &::after { - content: ''; - position: absolute; - right: -20px; - top: 0; - display: inline-block; - width: 20px; - height: 100%; - } - - thead th:nth-of-type(1) { - width: 10%; - text-align: left !important; - } - - thead th:nth-of-type(2) { - width: 2.8%; - } - - thead th:nth-of-type(3) { - text-align: left !important; - width: 10%; - } - - thead th:nth-of-type(4) { - width: 8%; - } - - thead th:nth-of-type(5) { - width: 3%; - } - - thead th:nth-of-type(6) { - width: 4%; - } -`; - -export const HeaderRow = styled.tr` - border-top: none !important; -`; diff --git a/frontend/src/components/buildTable/TestCase.jsx b/frontend/src/components/buildTable/TestCase.jsx index 20574cec..8875825e 100644 --- a/frontend/src/components/buildTable/TestCase.jsx +++ b/frontend/src/components/buildTable/TestCase.jsx @@ -1,17 +1,16 @@ import React from 'react'; import { Link, useLocation } from 'react-router-dom'; -import { StyledTests } from './TextCase.styles'; const TestCase = ({ testCases, index, suiteId, testId }) => { const testCase = testCases[index].test_case; const pathname = useLocation().pathname; const correctUrl = pathname.substring(0, pathname.lastIndexOf('/')); return ( - + {testCase} - + ); }; diff --git a/frontend/src/components/buildTable/TextCase.styles.js b/frontend/src/components/buildTable/TextCase.styles.js deleted file mode 100644 index b4ac0db3..00000000 --- a/frontend/src/components/buildTable/TextCase.styles.js +++ /dev/null @@ -1,5 +0,0 @@ -import styled from 'styled-components'; - -export const StyledTests = styled.td` - text-align: left !important; -`; diff --git a/frontend/src/components/dashlist/KeywordAnalysisTable.jsx b/frontend/src/components/dashlist/KeywordAnalysisTable.jsx index 5a664277..82183e2e 100644 --- a/frontend/src/components/dashlist/KeywordAnalysisTable.jsx +++ b/frontend/src/components/dashlist/KeywordAnalysisTable.jsx @@ -2,8 +2,8 @@ import React, { useEffect } from 'react'; import { useParams } from 'react-router'; import { useStateValue } from '../../contexts/state'; import { useTranslation } from 'react-i18next'; -import { StyledTable } from './KeywordAnalysisTable.styles'; -import { OverflowWrapper, TableWrapper } from '../historyTable/Table.styles'; +import { Table } from '../table/Table'; +import { NarrowTh, WideTh } from '../table/Table.styles'; const DashboardList = () => { const [t] = useTranslation(['analysis']); @@ -28,50 +28,46 @@ const DashboardList = () => { }, [dispatch, seriesId, buildId]); return ( - - - - - - {t('table.library')} - {t('table.keyword')} - {t('table.running_time')} - {t('table.min')} - {t('table.avg')} - {t('table.max')} - {t('table.total')} - {t('table.calls')} - {t('table.versions')} - {t('table.call_depth')} - - - - {keywordAnalysisList ? ( - keywordAnalysisList.map(keyword => { - return ( - - {keyword.library} - {keyword.keyword} - {keyword.percent.toFixed(2)} - {keyword.min} - {keyword.avg} - {keyword.max} - {keyword.total} - {keyword.calls} - {keyword.versions} - {keyword.max_call_depth} - - ); - }) - ) : ( - - {t('table.no_data')} + + + + {t('table.library')} + {t('table.keyword')} + {t('table.running_time')} + + + + + + + + + + + {keywordAnalysisList ? ( + keywordAnalysisList.map(keyword => { + return ( + + + + + + + + + + + - )} - - - - + ); + }) + ) : ( + + + + )} + +
{t('table.min')}{t('table.avg')}{t('table.max')}{t('table.total')}{t('table.calls')}{t('table.versions')}{t('table.call_depth')}
{keyword.library}{keyword.keyword}{keyword.percent.toFixed(2)}{keyword.min}{keyword.avg}{keyword.max}{keyword.total}{keyword.calls}{keyword.versions}{keyword.max_call_depth}
{t('table.no_data')}
); }; diff --git a/frontend/src/components/historyTable/Body.jsx b/frontend/src/components/historyTable/Body.jsx index 2b41fcb8..b94aa235 100644 --- a/frontend/src/components/historyTable/Body.jsx +++ b/frontend/src/components/historyTable/Body.jsx @@ -46,7 +46,7 @@ const Body = () => { ); } ); - return tableBody; + return {tableBody}; }; export default Body; diff --git a/frontend/src/components/historyTable/Heading.jsx b/frontend/src/components/historyTable/Heading.jsx index 0da93a4d..c5b228a6 100644 --- a/frontend/src/components/historyTable/Heading.jsx +++ b/frontend/src/components/historyTable/Heading.jsx @@ -2,6 +2,7 @@ import React from 'react'; import { useStateValue } from '../../contexts/state'; import { StyledLink, BuildNumberCell } from './Heading.styles'; import { colorTypes } from '../../utils/colorTypes'; +import { WideTh } from '../table/Table.styles'; // helper for build number sorting function compareNumbers(a, b) { @@ -71,8 +72,8 @@ export const Heading = () => { return ( - Suite - Test + Suite + Test {buildNumbers} diff --git a/frontend/src/components/historyTable/Suite.jsx b/frontend/src/components/historyTable/Suite.jsx index 5b7083ea..eeeeaafb 100644 --- a/frontend/src/components/historyTable/Suite.jsx +++ b/frontend/src/components/historyTable/Suite.jsx @@ -3,10 +3,11 @@ import { dashify } from '../../utils/helpers'; import SuiteName from './SuiteName'; import TestStatus from './TestStatus'; import TestCase from './TestCase'; +import { SuiteRow } from '../table/Table.styles'; const Suite = ({ builds, test_case, suite, index, test_cases }) => { return ( - + {index === 0 && ( { )} - + ); }; diff --git a/frontend/src/components/historyTable/SuiteName.jsx b/frontend/src/components/historyTable/SuiteName.jsx index 77bff5a8..79d42f87 100644 --- a/frontend/src/components/historyTable/SuiteName.jsx +++ b/frontend/src/components/historyTable/SuiteName.jsx @@ -1,6 +1,6 @@ import React, { Fragment } from 'react'; import { dashify } from '../../utils/helpers'; -import { StyledData } from './SuiteName.styles'; +import { HierarchicalSuiteNameTh } from '../table/Table.styles'; // Show suite name separated on different lines with dots showing depth level const SuiteName = ({ tableCellHeight, suiteName }) => { @@ -16,12 +16,12 @@ const SuiteName = ({ tableCellHeight, suiteName }) => { ); } return ( - {splitSuiteName} - + ); }; diff --git a/frontend/src/components/historyTable/SuiteName.styles.js b/frontend/src/components/historyTable/SuiteName.styles.js deleted file mode 100644 index 872ddcff..00000000 --- a/frontend/src/components/historyTable/SuiteName.styles.js +++ /dev/null @@ -1,39 +0,0 @@ -import styled from 'styled-components'; - -export const StyledData = styled.td` - padding: 8px; - text-align: left; - vertical-align: top; - min-width: 25%; - - span { - display: inline-block; - } - span:nth-child(3) { - padding-left: 8px; - } - span:nth-child(5) { - padding-left: 16px; - } - span:nth-child(7) { - padding-left: 24px; - } - span:nth-child(9) { - padding-left: 32px; - } - span:nth-child(11) { - padding-left: 40px; - } - span:nth-child(13) { - padding-left: 48px; - } - span:nth-child(15) { - padding-left: 56px; - } - span:nth-child(17) { - padding-left: 64px; - } - span:nth-child(19) { - padding-left: 72px; - } -`; diff --git a/frontend/src/components/historyTable/Table.jsx b/frontend/src/components/historyTable/Table.jsx deleted file mode 100644 index c76eeaca..00000000 --- a/frontend/src/components/historyTable/Table.jsx +++ /dev/null @@ -1,34 +0,0 @@ -// eslint-disable-next-line -import React from 'react'; -import Heading from './Heading'; -import Body from './Body'; -import NotFound from '../NotFound'; -import { useStateValue } from '../../contexts/state'; -import { OverflowWrapper, TableStyled, TableWrapper } from './Table.styles'; - -const Table = () => { - const [ - { - historyDataState: { max_build_num }, - }, - ] = useStateValue(); - - if (max_build_num > 0) { - return ( - - - - - - - - - - - ); - } else { - return ; - } -}; - -export default Table; diff --git a/frontend/src/components/historyTable/Table.styles.js b/frontend/src/components/historyTable/Table.styles.js deleted file mode 100644 index 70fc5dc4..00000000 --- a/frontend/src/components/historyTable/Table.styles.js +++ /dev/null @@ -1,84 +0,0 @@ -import styled from 'styled-components'; - -export const TableWrapper = styled.div` - max-width: calc(100% + 40px); - position: relative; - margin: 0 -20px; - &::before { - position: absolute; - top: 0; - left: 0; - content: ''; - width: 20px; - height: 100%; - background-image: linear-gradient( - to right, - white, - rgba(255, 255, 255, 0.001) - ); - z-index: 1; - } - - &::after { - position: absolute; - top: 0; - right: 0; - content: ''; - width: 20px; - height: 100%; - background-image: linear-gradient( - to left, - white, - rgba(255, 255, 255, 0.001) - ); - } -`; - -export const OverflowWrapper = styled.div` - display: inline-block; - overflow-x: auto; - position: relative; - max-width: 100%; - width: 100%; - padding: 0 20px; -`; - -export const TableStyled = styled.table` - clear: both; - border-collapse: separate !important; - border-spacing: 0; - border: 1px solid var(--hermanni-grey); - border-radius: 8px; - text-align: left; - vertical-align: top; - position: relative; - width: 100%; - - &::after { - content: ''; - position: absolute; - right: -20px; - top: 0; - display: inline-block; - width: 20px; - height: 100%; - } - - thead { - background: var(--hermanni-grey); - } - - thead th { - padding: 8px; - text-align: left; - } - - tbody td { - border-top: 1px solid var(--hermanni-grey); - vertical-align: top; - } - - .centerTableCellContent { - text-align: center; - } -`; diff --git a/frontend/src/components/historyTable/TestCase.jsx b/frontend/src/components/historyTable/TestCase.jsx index 21a65a8a..dc13da5c 100644 --- a/frontend/src/components/historyTable/TestCase.jsx +++ b/frontend/src/components/historyTable/TestCase.jsx @@ -1,11 +1,10 @@ import React from 'react'; import { dashify } from '../../utils/helpers'; -import { StyledData } from './TestCase.styles'; const TestCase = ({ test_case, position }) => ( - + {test_case} - + ); export default TestCase; diff --git a/frontend/src/components/historyTable/TestCase.styles.js b/frontend/src/components/historyTable/TestCase.styles.js deleted file mode 100644 index 42a7c867..00000000 --- a/frontend/src/components/historyTable/TestCase.styles.js +++ /dev/null @@ -1,9 +0,0 @@ -import styled from 'styled-components'; - -export const StyledData = styled.td` - padding: 10px; - text-align: left; - vertical-align: middle; - background: var(--nero-white); - border-top: ${props => props.position !== 0 && 'none !important'}; -`; diff --git a/frontend/src/components/historyTable/TestStatus.styles.js b/frontend/src/components/historyTable/TestStatus.styles.js index ea9cd6dd..682e60c0 100644 --- a/frontend/src/components/historyTable/TestStatus.styles.js +++ b/frontend/src/components/historyTable/TestStatus.styles.js @@ -1,8 +1,8 @@ import styled from 'styled-components'; export const DefinedData = styled.td` - padding: 10px; + padding-right: var(--space-8) !important; + padding-left: var(--space-8) !important; text-align: center; vertical-align: middle; - border-top: ${props => props.position !== 0 && 'none !important'}; `; diff --git a/frontend/src/components/suite/LogMessages.jsx b/frontend/src/components/suite/LogMessages.jsx index 89adf9a3..1d223fdd 100644 --- a/frontend/src/components/suite/LogMessages.jsx +++ b/frontend/src/components/suite/LogMessages.jsx @@ -1,64 +1,52 @@ import React from 'react'; import SuiteLogMessage from './SuiteLogMessage'; import { ReactComponent as Fail } from '../../images/fail-white.svg'; -import { SelectedTestContainer, LogRow, InfoLevel } from './LogMessages.styles'; -import { OverflowWrapper, TableWrapper } from '../historyTable/Table.styles'; +import { LogRow, InfoLevel } from './LogMessages.styles'; +import { Table } from '../table/Table'; const LogMessages = ({ test }) => { return test ? ( - - - - - - - - - - - - - {test.log_messages !== null && - test.log_messages.map( - ({ log_level, message, timestamp }, i) => { - return ( - - -
- {log_level} -
- - - -
-
- - - ); - } - )} - -
LevelLog messageTimestamp
- - -
- {timestamp} -
-
-
-
-
+ + + + + + + + + + {test.log_messages !== null && + test.log_messages.map( + ({ log_level, message, timestamp }, i) => { + return ( + + + {log_level} + {log_level === 'FAIL' ? ( + + + + ) : ( + '' + )} + + + + + ); + } + )} + +
LevelLog messageTimestamp
+ + +
+ {timestamp} +
+
) : null; }; diff --git a/frontend/src/components/suite/LogMessages.styles.js b/frontend/src/components/suite/LogMessages.styles.js index 8c579873..70140700 100644 --- a/frontend/src/components/suite/LogMessages.styles.js +++ b/frontend/src/components/suite/LogMessages.styles.js @@ -1,85 +1,41 @@ import styled from 'styled-components'; -export const SelectedTestContainer = styled.div` - background: var(--nero-white); - margin-top: 5px; - - table { - border-collapse: separate !important; - border-spacing: 0; - width: 100%; - border: 1px solid var(--hermanni-grey); - border-radius: 8px; - position: relative; - - &::after { - content: ''; - position: absolute; - right: -20px; - top: 0; - display: inline-block; - width: 20px; - height: 100%; - } - } - - thead { - background: var(--hermanni-grey); - text-align: left; - - th { - color: var(--gradient-black); - font-weight: bold; - padding: 8px 0; - } - - th:first-child { - padding-left: 8px; - } - } - - .table-item { - padding: 0.25rem 0rem; - white-space: normal; - display: inline-block; - } +export const LogRow = styled.tr` + background-color: ${props => + props.log_level === 'FAIL' && 'var(--nelson-purple)'}; + color: ${props => props.log_level === 'FAIL' && 'var(--nero-white)'}; - tbody tr { - border-bottom: 1px solid var(--hermanni-grey); - } + &:hover { + color: ${props => props.log_level === 'FAIL' && 'var(--nelson-purple)'}; - tbody td { - vertical-align: top; - &:first-child { - padding-left: 8px; - white-space: nowrap; + svg path { + fill: var(--nelson-purple); } - } - .suite-log-message { - > div { - width: calc(100vw / 2.5); - word-break: break-word; + .suite-log-message { + .can-be-opened { + &::after { + background-color: var(--kumpula-yellow); + } + } } } -`; -export const LogRow = styled.tr` - background-color: ${props => - props.log_level === 'FAIL' && 'var(--nelson-purple)'}; - color: ${props => props.log_level === 'FAIL' && 'var(--nero-white)'}; - - .suite-log-message { - .can-be-opened { - &::after { - background-color: ${props => - props.log_level === 'FAIL' && 'var(--nelson-purple)'}; + &:not(:hover) { + .suite-log-message { + .can-be-opened { + &::after { + background-color: ${props => + props.log_level === 'FAIL' && 'var(--nelson-purple)'}; + } } } } `; export const InfoLevel = styled.td` + white-space: nowrap; + span { position: relative; top: -2px; diff --git a/frontend/src/components/suite/SuiteLogMessage.styles.js b/frontend/src/components/suite/SuiteLogMessage.styles.js index fe49f3e4..24b738e0 100644 --- a/frontend/src/components/suite/SuiteLogMessage.styles.js +++ b/frontend/src/components/suite/SuiteLogMessage.styles.js @@ -1,8 +1,8 @@ import styled from 'styled-components'; export const TestMessage = styled.div` - padding: 0.25rem 0rem; - width: 100%; + width: calc(100vw / 2.3); + word-break: break-word; overflow: hidden; &.can-be-opened { @@ -15,12 +15,16 @@ export const TestMessage = styled.div` top: 1px; right: 0; width: 30px; - line-height: 30px; + line-height: 18px; background: var(--nero-white); display: ${props => (props.open ? 'none' : 'inline-block')}; } } + &[tabindex='-1']:focus { + outline: 0; + } + & > div { display: inline-block; white-space: ${props => (props.open ? 'normal' : 'nowrap')}; diff --git a/frontend/src/pages/Analysis.jsx b/frontend/src/pages/Analysis.jsx index f5616d1b..36b2755c 100644 --- a/frontend/src/pages/Analysis.jsx +++ b/frontend/src/pages/Analysis.jsx @@ -28,8 +28,10 @@ const Overview = () => {
-

{t('title')}

- + +

{t('title')}

+ +
); diff --git a/frontend/src/pages/Build.jsx b/frontend/src/pages/Build.jsx index 31d7fc6c..7a75c296 100644 --- a/frontend/src/pages/Build.jsx +++ b/frontend/src/pages/Build.jsx @@ -1,6 +1,6 @@ // eslint-disable-next-line import React, { Fragment, useEffect } from 'react'; -import Table from '../components/buildTable/Table'; +import BuildTable from '../components/buildTable/BuildTable'; import LastRunCheckBox from '../components/buttons/LastRunCheckbox'; import { useStateValue } from '../contexts/state'; import { useParams } from 'react-router'; @@ -103,7 +103,7 @@ const Build = () => { - + diff --git a/frontend/src/pages/History.jsx b/frontend/src/pages/History.jsx index 2ba5ed6c..6099d3b5 100644 --- a/frontend/src/pages/History.jsx +++ b/frontend/src/pages/History.jsx @@ -1,6 +1,6 @@ import React, { Fragment, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; -import Table from '../components/historyTable/Table'; +import HistoryTable from '../components/historyTable/HistoryTable'; import ParentSeries from '../components/parentData/ParentSeries'; import Offset from '../components/buttons/OffSetButtons'; import LastRunCheckbox from '../components/buttons/LastRunCheckbox'; @@ -117,7 +117,7 @@ const History = () => { > Content loaded. -
+ )} diff --git a/frontend/src/styles/baseComponents.js b/frontend/src/styles/baseComponents.js index 68549bd5..a08abf8d 100644 --- a/frontend/src/styles/baseComponents.js +++ b/frontend/src/styles/baseComponents.js @@ -59,3 +59,151 @@ export const ContentGrid6 = styled.div` max-width: 100%; margin: 0 calc(100% / 12); `; + +export const SpreadSheetTable = styled.table` + width: 100%; + border-collapse: separate; + font-size: 12px; + line-height: 20px; + border: 1px solid var(--evidence-grey-lighter); + border-radius: 10px; + border-spacing: 0; + + thead { + border-radius: 4px; + text-align: left; + + & tr th { + padding: var(--space-8) var(--space-16) var(--space-4) 0; + background-color: var(--hermanni-grey); + &:first-of-type { + border-radius: 10px 0 0 0; + padding-left: var(--space-8); + } + &:last-of-type { + border-radius: 0 10px 0 0; + padding-right: var(--space-8); + } + } + } + + tbody { + & tr { + vertical-align: top; + + &:hover { + background-color: var(--kumpula-yellow); + } + + &:last-of-type { + border-bottom: 0; + + & td:first-of-type { + border-radius: 0 0 0 10px; + } + + & td:last-of-type { + border-radius: 0 0 10px 0; + } + } + + & td { + border-bottom: 1px solid var(--hermanni-grey); + position: relative; + padding: var(--space-4) var(--space-8) var(--space-4) 0; + + &:first-of-type { + padding-left: var(--space-8); + } + + &:last-of-type { + padding-right: var(--space-8); + } + } + } + } + + a { + text-decoration: none; + + &:hover { + text-decoration: underline; + display: inline-block; + } + + &:active { + color: var(--pirlo-blue); + } + } +`; + +export const SimpleTable = styled.table` + width: 100%; + border-collapse: collapse; + font-size: 12px; + line-height: 20px; + + thead { + text-align: left; + + & tr th { + padding: 8px 0 4px 0; + } + } + + tbody { + & tr { + border-bottom: 1px solid var(--hermanni-grey); + vertical-align: top; + + &:hover { + background-color: var(--kumpula-yellow); + } + + &:last-of-type { + border-bottom: 0; + } + + & td { + padding: 1px 0; + position: relative; + + &:first-of-type { + padding-left: 2px; + } + + &::before { + content: ''; + width: 100%; + height: 1px; + background: white; + position: absolute; + top: 0; + left: 0; + } + + &::after { + content: ''; + width: 100%; + height: 1px; + background: white; + position: absolute; + bottom: 0; + left: 0; + } + } + } + } + + a { + text-decoration: none; + + &:hover { + text-decoration: underline; + } + + &:active { + color: var(--pirlo-blue); + } + } +`; From c58a584e58d103cb9a1e06618a3ab825655ca2a4 Mon Sep 17 00:00:00 2001 From: Tiia Valtonen Date: Fri, 19 Mar 2021 14:29:03 +0200 Subject: [PATCH 07/35] Feature/153 - Unify buttons' styles (#154) * Create styles for Default button * Change OffSetButtons to use the new Default button * Unify dropdown's, input's and checkbox's styles to match Default button * Rearrange code * Create a Toggle button and use it with stability table * Accessibility and style improvements for stability table * Unify different buttons' focus styles * Remove duplicate hover styles --- frontend/src/App.styles.js | 9 -- .../src/components/BreadcrumbNav.styles.js | 2 - .../buttons/DropdownSelect.styles.js | 16 ++-- .../buttons/LastRunCheckbox.styles.js | 4 +- .../src/components/buttons/OffSetButtons.jsx | 35 ++++---- .../buttons/OffSetButtons.styles.js | 53 +---------- .../src/components/buttons/button.styles.jsx | 87 +++++++++++++++++++ .../dashlist/FailureTable.styles.js | 1 + .../components/dashlist/FlakinessTable.jsx | 36 ++++---- .../dashlist/FlakinessTable.styles.js | 12 +-- frontend/src/components/dashlist/ListMain.jsx | 58 +++++++------ .../components/dashlist/ListMain.styles.js | 19 ++-- .../src/components/suite/Testlist.styles.js | 6 -- frontend/src/index.css | 26 ++++-- 14 files changed, 200 insertions(+), 164 deletions(-) create mode 100644 frontend/src/components/buttons/button.styles.jsx diff --git a/frontend/src/App.styles.js b/frontend/src/App.styles.js index d43ba873..8b0250e1 100644 --- a/frontend/src/App.styles.js +++ b/frontend/src/App.styles.js @@ -7,13 +7,4 @@ export const StyledApp = styled.div` p { line-height: 1.6; } - - a { - color: var(--titan-green); - } - select:focus, - input:focus { - outline: 0; - box-shadow: 0 0 0 4px var(--sparkling-blue); - } `; diff --git a/frontend/src/components/BreadcrumbNav.styles.js b/frontend/src/components/BreadcrumbNav.styles.js index 8cd8e90c..f148d91d 100644 --- a/frontend/src/components/BreadcrumbNav.styles.js +++ b/frontend/src/components/BreadcrumbNav.styles.js @@ -59,8 +59,6 @@ export const StyledInnerDiv = styled.ol` export const StyledLink = styled(Link)` &:hover { text-decoration: underline; - color: var(--titan-green-darker); - background: var(--hermanni-grey-lighter); } `; diff --git a/frontend/src/components/buttons/DropdownSelect.styles.js b/frontend/src/components/buttons/DropdownSelect.styles.js index 6f12232a..c5d5511f 100644 --- a/frontend/src/components/buttons/DropdownSelect.styles.js +++ b/frontend/src/components/buttons/DropdownSelect.styles.js @@ -10,25 +10,19 @@ export const DropdownWrapper = styled.div` .ReactA11ySelect__button { width: 100%; - height: 36px; + height: var(--space-32); + line-height: var(--space-32); padding: 0 10px 0 15px; background-color: var(--nero-white); - border: 1px solid var(--tonic-grey); + border: 1px solid var(--evidence-grey); font-size: 14px; white-space: nowrap; display: flex; justify-content: space-between; - line-height: 36px; } .ReactA11ySelect__button:enabled:hover { - color: var(--gradient-black); - text-decoration: none; - } - - .ReactA11ySelect__button:enabled:focus { - outline: 0; - box-shadow: 0 0 0 4px var(--sparkling-blue); + background-color: var(--hermanni-grey); } .ReactA11ySelect__button > span:first-child { @@ -53,7 +47,7 @@ export const DropdownWrapper = styled.div` margin: 0; font-size: 14px; border: 1px solid var(--tonic-grey); - border-radius: 4px; + border-radius: var(--space-4); box-shadow: 0 3px 5px 1px var(--tonic-grey); padding: 5px 3px; z-index: 10; diff --git a/frontend/src/components/buttons/LastRunCheckbox.styles.js b/frontend/src/components/buttons/LastRunCheckbox.styles.js index 5efd4a06..adc5b105 100644 --- a/frontend/src/components/buttons/LastRunCheckbox.styles.js +++ b/frontend/src/components/buttons/LastRunCheckbox.styles.js @@ -9,11 +9,11 @@ export const StyledDiv = styled.div` display: flex; flex-direction: ${props => props.direction}; border: 1px solid var(--tonic-grey); - border-radius: 4px; + border-radius: var(--space-4); width: ${props => (props.direction === 'column' ? '10%' : '30%')}; max-width: 230px; min-width: ${props => (props.direction === 'column' ? '200px' : '230px')}; - line-height: 34px; + line-height: 30px; padding: 0 var(--space-8); @media only screen and (max-width: 1024px) { diff --git a/frontend/src/components/buttons/OffSetButtons.jsx b/frontend/src/components/buttons/OffSetButtons.jsx index 3a6b7efa..69dc30aa 100644 --- a/frontend/src/components/buttons/OffSetButtons.jsx +++ b/frontend/src/components/buttons/OffSetButtons.jsx @@ -5,17 +5,14 @@ import { useStateValue } from '../../contexts/state'; import { useHistory, useLocation } from 'react-router-dom'; import { useQueryParams } from '../../hooks/useQuery'; -import { - StyledInput, - StyledDirectionButton, - LatestButton, - FlexDiv, - StyledEndLeft, - Heading, -} from './OffSetButtons.styles'; +import { StyledInput, FlexDiv, Heading } from './OffSetButtons.styles'; + +import { DefaultButton } from './button.styles'; + +import { ReactComponent as Left } from '../../images/chevron-left.svg'; +import { ReactComponent as Right } from '../../images/chevron-right.svg'; +import { ReactComponent as EndLeft } from '../../images/chevron-verticalbar-left.svg'; -import Left from '../../images/chevron-left.svg'; -import Right from '../../images/chevron-right.svg'; const Offset = () => { const history = useHistory(); const location = useLocation(); @@ -101,34 +98,34 @@ const Offset = () => {
Offset - - LATEST - - LATEST + + handleDirectionButtonPress('left')} disabled={leftDisabled} id="left_offset_button" className={`left${leftDisabled}`} > - < - + + - handleDirectionButtonPress('right')} disabled={rightDisabled} id="right_offset_button" className={`right${rightDisabled}`} > - > - + +
); diff --git a/frontend/src/components/buttons/OffSetButtons.styles.js b/frontend/src/components/buttons/OffSetButtons.styles.js index 3dc060ee..59e95bd7 100644 --- a/frontend/src/components/buttons/OffSetButtons.styles.js +++ b/frontend/src/components/buttons/OffSetButtons.styles.js @@ -1,69 +1,22 @@ import styled from 'styled-components'; -import { ReactComponent as EndLeft } from '../../images/chevron-verticalbar-left.svg'; export const Heading = styled.div` color: var(--evidence-grey); - margin: 8px 0; -`; - -export const StyledEndLeft = styled(EndLeft)` - left: 25%; - right: 24.99%; - top: 6.25%; - bottom: 6.25%; + margin: var(--space-8) 0; `; export const FlexDiv = styled.div` display: flex; - button:hover { - text-decoration: none; - color: var(--evidence-grey-darker); - } - > * { margin-right: var(--space-8); } `; -export const StyledDirectionButton = styled.button` - width: 36px; - height: 36px; - background: ${props => - props.disabled ? 'var(--tonic-grey) !important' : 'var(--nero-white)'}; - border: 1px solid var(--tonic-grey); - box-sizing: border-box; - border-radius: 4px; -`; - -export const LatestButton = styled.button` - width: 89px; - height: 36px; - background: var(--nero-white); - border: 1px solid var(--tonic-grey); - box-sizing: border-box; - border-radius: 4px; - - font-family: Hack; - font-style: normal; - font-weight: bold; - font-size: 12px; - - letter-spacing: -0.04em; - text-transform: uppercase; - color: var(--evidence-grey); - - span { - vertical-align: middle; - position: relative; - top: 1px; - } -`; - export const StyledInput = styled.input` - border: 1px solid var(--tonic-grey); + border: 1px solid var(--evidence-grey); border-radius: 4px; max-width: 54px; - height: 36px; + height: var(--space-32); text-align: right; `; diff --git a/frontend/src/components/buttons/button.styles.jsx b/frontend/src/components/buttons/button.styles.jsx new file mode 100644 index 00000000..af86ca2b --- /dev/null +++ b/frontend/src/components/buttons/button.styles.jsx @@ -0,0 +1,87 @@ +import styled from 'styled-components'; + +export const DefaultButton = styled.button` + font-family: Hack; + font-style: normal; + font-weight: bold; + font-size: 12px; + color: var(--evidence-grey); + white-space: nowrap; + background-color: var(--nero-white); + border: 1px solid var(--evidence-grey); + border-radius: var(--space-4); + height: var(--space-32); + min-width: var(--space-32); + line-height: var(--space-32); + padding: 0 var(--space-8); + + svg { + vertical-align: sub; + + path { + fill: var(--evidence-grey); + + &[stroke] { + stroke: var(--evidence-grey); + } + } + } + + &:hover { + background-color: var(--hermanni-grey); + } + + &:focus { + color: var(--pirlo-blue); + + svg path { + fill: var(--pirlo-blue); + + &[stroke] { + stroke: var(--pirlo-blue); + } + } + } + + &[disabled] { + border-color: var(--tonic-grey); + color: var(--tonic-grey); + + svg path { + fill: var(--tonic-grey); + + &[stroke] { + stroke: var(--tonic-grey); + } + } + } +`; + +export const ToggleButton = styled.button` + font-family: Hack; + font-style: normal; + font-weight: bold; + font-size: 14px; + text-transform: uppercase; + color: var(--evidence-grey); + background-color: var(--nero-white); + border: 1px solid var(--evidence-grey); + border-radius: var(--space-4); + height: var(--space-40); + min-width: var(--space-40); + padding: 0 var(--space-16); + white-space: nowrap; + box-shadow: 0px 3px 3px -1px var(--tonic-grey); + + &.selected { + color: var(--nero-white); + background-color: var(--titan-green); + border-color: var(--titan-green); + } +`; + +export const ToggleButtonSmall = styled(ToggleButton)` + font-size: 12px; + height: var(--space-24); + line-height: var(--space-24); +`; diff --git a/frontend/src/components/dashlist/FailureTable.styles.js b/frontend/src/components/dashlist/FailureTable.styles.js index 49994b54..892c4f86 100644 --- a/frontend/src/components/dashlist/FailureTable.styles.js +++ b/frontend/src/components/dashlist/FailureTable.styles.js @@ -7,6 +7,7 @@ export const TableContainer = styled.div` grid-area: table; max-height: 100%; overflow-y: scroll; + padding-top: var(--space-8); `; export const StyledTable = styled.table` diff --git a/frontend/src/components/dashlist/FlakinessTable.jsx b/frontend/src/components/dashlist/FlakinessTable.jsx index 4162c8c1..330e1265 100644 --- a/frontend/src/components/dashlist/FlakinessTable.jsx +++ b/frontend/src/components/dashlist/FlakinessTable.jsx @@ -1,30 +1,29 @@ import React, { useEffect } from 'react'; import { useParams } from 'react-router'; import { useStateValue } from '../../contexts/state'; -import { - TableContainer, - StyledTable, - HighlightedButton, -} from './FlakinessTable.styles'; +import { TableContainer, StyledTable } from './FlakinessTable.styles'; +import { ToggleButtonSmall } from '../buttons/button.styles'; const StabilityButton = ({ value, text }) => { const [{ stabilityChecker }, dispatch] = useStateValue(); return ( - { dispatch({ type: 'setStabilityChecker', setStability: value, }); + + document.getElementById( + 'flakiness-table-status' + ).textContent = `Content updated. Showing now ${value} in stability table.`; }} - color={ - stabilityChecker === value - ? 'var(--evidence grey)' - : 'var(--nero-white)' - } > {text} - + ); }; @@ -50,10 +49,15 @@ const DashboardList = () => { }, [dispatch, seriesId, stabilityChecker, amountOfBuilds, offset]); return ( - - - - + +

+ {' '} +

+ + + + +
diff --git a/frontend/src/components/dashlist/FlakinessTable.styles.js b/frontend/src/components/dashlist/FlakinessTable.styles.js index 53a946e7..5eea8c3c 100644 --- a/frontend/src/components/dashlist/FlakinessTable.styles.js +++ b/frontend/src/components/dashlist/FlakinessTable.styles.js @@ -6,7 +6,10 @@ export const TableContainer = styled.div` width: 100%; max-height: 400px; overflow-y: scroll; - grid-area: table; + + button { + margin: var(--space-16) var(--space-8) var(--space-16) 0; + } `; export const StyledTable = styled.table` @@ -33,10 +36,3 @@ export const StyledTable = styled.table` text-align: left; } `; - -export const HighlightedButton = styled.button` - background-color: ${props => props.color}; - color: var(--gradient-black); - border: 1px solid var(--gradient-black); - outline: none; -`; diff --git a/frontend/src/components/dashlist/ListMain.jsx b/frontend/src/components/dashlist/ListMain.jsx index b609ecec..d7d14be5 100644 --- a/frontend/src/components/dashlist/ListMain.jsx +++ b/frontend/src/components/dashlist/ListMain.jsx @@ -1,41 +1,49 @@ import React, { useState } from 'react'; import FlakinessTable from './FlakinessTable'; import FailureTable from './FailureTable'; -import { - StyledListContainer, - TableSelectors, - TableButtons, -} from './ListMain.styles'; +import { StyledListContainer, TableSelectors } from './ListMain.styles'; +import { ToggleButton } from '../buttons/button.styles'; const DashboardList = () => { const [window, setWindow] = useState('flakiness'); + + function updateTable(window) { + setWindow(window); + document.getElementById( + 'stability-table-status' + ).textContent = `Content updated. Showing now ${window} table.`; + } + return ( - - setWindow('flakiness')} +

+ {' '} +

+ + updateTable('flakiness')} > Stability -
- setWindow('failures')} + + updateTable('failures')} > Failures - +
- {window === 'flakiness' ? : } + + {window === 'flakiness' ? : } +
); }; diff --git a/frontend/src/components/dashlist/ListMain.styles.js b/frontend/src/components/dashlist/ListMain.styles.js index 4d7fc35d..c5e1eddb 100644 --- a/frontend/src/components/dashlist/ListMain.styles.js +++ b/frontend/src/components/dashlist/ListMain.styles.js @@ -9,21 +9,18 @@ export const StyledListContainer = styled.div` grid-template-rows: 0.6fr 0.55fr 6fr; grid-template-areas: 'selectorbox selectorbox' - 'amount amount' 'table table'; + + #stability-table { + grid-area: table; + } `; export const TableSelectors = styled.div` grid-area: selectorbox; -`; + margin-bottom: var(--space-16); -export const TableButtons = styled.button` - padding: 10px; - margin-left: 4px; - margin-right: 4px; - margin-bottom: 2px; - background-color: ${props => props.color}; - color: var(--gradient-black); - border: 1px solid var(--gradient-black); - outline: none; + button { + margin-right: var(--space-8); + } `; diff --git a/frontend/src/components/suite/Testlist.styles.js b/frontend/src/components/suite/Testlist.styles.js index 1ede29a3..88f78e9b 100644 --- a/frontend/src/components/suite/Testlist.styles.js +++ b/frontend/src/components/suite/Testlist.styles.js @@ -37,12 +37,6 @@ export const HeaderContainer = styled.button` text-align: left; padding: 0; - &:hover:enabled { - background-color: var(--titan-green); - color: var(--nero-white); - text-decoration: none; - } - h2 { font-size: 20px; font-family: 'Hack'; diff --git a/frontend/src/index.css b/frontend/src/index.css index 4a44aac1..724221e7 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -57,6 +57,7 @@ html { --space-64: 64px; --space-48: 48px; --space-40: 40px; + --space-32: 32px; --space-24: 24px; --space-16: 16px; --space-8: 8px; @@ -122,13 +123,10 @@ svg { vertical-align: middle; } -button:focus, -input:focus, -a:focus { - outline: 2px solid var(--pirlo-blue); +a { + color: var(--titan-green); } -button:hover:enabled, a:hover { cursor: pointer; text-decoration: underline; @@ -136,6 +134,24 @@ a:hover { color: var(--titan-green-darker); } +a:focus { + outline: 2px solid var(--pirlo-blue); +} + +button { + cursor: pointer; +} + +button[disabled] { + pointer-events: none; +} + +button:focus, +input:focus { + outline: 0; + box-shadow: 0 0 0 var(--space-4) var(--sparkling-blue); +} + /** a11y **/ .sr-show { From 931b173fc06b1c65e44e17f023bf26e2f44fd550 Mon Sep 17 00:00:00 2001 From: Tiia Valtonen Date: Fri, 19 Mar 2021 14:36:29 +0200 Subject: [PATCH 08/35] Feature/157 - Style grey 'Context' block (#158) * Style the 'Context' block * Improve color contrast * Fix tests --- .../src/components/parentData/ParentTable.jsx | 14 +++++++--- .../parentData/ParentTable.styles.js | 26 +++++++++++++++---- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/parentData/ParentTable.jsx b/frontend/src/components/parentData/ParentTable.jsx index 62851b54..6e0d8778 100644 --- a/frontend/src/components/parentData/ParentTable.jsx +++ b/frontend/src/components/parentData/ParentTable.jsx @@ -4,6 +4,7 @@ import { pick } from 'ramda'; import { capitalCaseInitial, removeUnderscore } from '../../utils/helpers'; import { Container, + ContentBlockContainer, ParagraphContainer, StatusSpan, } from './ParentTable.styles'; @@ -31,9 +32,16 @@ const ParentTable = props => { }; return ( - - {data && {showData()}} - + <> + {data && ( + + + Context + {showData()} + + + )} + ); }; diff --git a/frontend/src/components/parentData/ParentTable.styles.js b/frontend/src/components/parentData/ParentTable.styles.js index 655673ac..153536a4 100644 --- a/frontend/src/components/parentData/ParentTable.styles.js +++ b/frontend/src/components/parentData/ParentTable.styles.js @@ -1,20 +1,36 @@ import styled from 'styled-components'; export const Container = styled.div` + padding: var(--space-8) 0 var(--space-16) 0; +`; + +export const ContentBlockContainer = styled.div` padding: var(--space-8) 0; - display: flex; - flex-flow: row wrap; - justify-content: space-between; - width: 100%; + + .title { + display: block; + color: var(--evidence-grey); + font-size: 12px; + } + + p { + display: inline-block; + margin: 0 var(--space-16) 0 0; + font-size: 12px; + } `; export const ParagraphContainer = styled.p` span:first-child { font-weight: bolder; + display: inline-block; + margin-right: var(--space-4); } `; export const StatusSpan = styled.span` color: ${props => - props.status === 'PASS' ? 'var(--pirlo-blue)' : 'var(--nelson-purple)'}; + props.status === 'PASS' + ? 'var(--pirlo-blue-darker)' + : 'var(--semolina-red)'}; `; From 8e28fffe1d3c6e813b31c0a42f24bca0ab506d09 Mon Sep 17 00:00:00 2001 From: Tiia Valtonen Date: Tue, 30 Mar 2021 12:53:12 +0300 Subject: [PATCH 09/35] Feature/155 - Unify link styles (#156) * 155 - Fix MainNav's link styles * 155 - Add a proper focus style for footer's links and replace pixels with variables * 155 - Refactor Breadcrumb a bit so there's no need to repeat link styles * 155 - Rearrange code * 155 - Remove redundant code * 155 - Remove table links' visited style * 155 - Add generic family for fonts --- frontend/src/components/BreadcrumbNav.jsx | 92 +++++++++---------- .../src/components/BreadcrumbNav.styles.js | 55 +++-------- frontend/src/components/Footer.styles.js | 14 ++- frontend/src/components/MainNav.jsx | 18 +--- frontend/src/components/MainNav.styles.js | 48 +++++----- .../metadata/MetadataTable.styles.js | 4 - .../src/components/suite/Testlist.styles.js | 4 - frontend/src/components/table/Table.styles.js | 20 ---- frontend/src/index.css | 25 ++--- 9 files changed, 107 insertions(+), 173 deletions(-) diff --git a/frontend/src/components/BreadcrumbNav.jsx b/frontend/src/components/BreadcrumbNav.jsx index 1f199147..a75f5d6e 100644 --- a/frontend/src/components/BreadcrumbNav.jsx +++ b/frontend/src/components/BreadcrumbNav.jsx @@ -1,18 +1,14 @@ import React from 'react'; import { useStateValue } from '../contexts/state'; import { useParams } from 'react-router'; -import { - BreadcrumbContainer, - StyledInnerDiv, - StyledLink, - TeamsLink, -} from './BreadcrumbNav.styles'; +import { BreadcrumbContainer, StyledInnerOl } from './BreadcrumbNav.styles'; import { ContainerGrid12, ContentGrid6 } from '../styles/baseComponents'; +import { Link } from 'react-router-dom'; const BreadcrumbTeams = () => { return (
  • - Teams + Teams
  • ); }; @@ -22,20 +18,20 @@ const BreadcrumbItemTeam = props => { const [{ selectedBranchState }] = useStateValue(); const teamName = name || selectedBranchState.team; return ( - + <>
  • - / - +
  • -
    + ); }; @@ -44,63 +40,63 @@ const BreadcrumbItemSeries = props => { const [{ selectedBranchState }] = useStateValue(); const seriesId = series || selectedBranchState.id; return ( - + <>
  • - / - +
  • -
    + ); }; const BreadcrumbItemBuild = props => { const { buildId, seriesId } = useParams(); return ( - + <>
  • - / - +
  • -
    + ); }; const BreadcrumbItemSuite = props => { const { seriesId, buildId, suiteId } = useParams(); return ( - + <>
  • - / - +
  • -
    + ); }; @@ -113,17 +109,19 @@ const BREADCRUMB_STATUS = { const BreadcrumbNav = ({ status }) => { return ( - - - - - - - + + + + + {BREADCRUMB_STATUS[`${status}`]} + + + + ); }; diff --git a/frontend/src/components/BreadcrumbNav.styles.js b/frontend/src/components/BreadcrumbNav.styles.js index f148d91d..b24bd08d 100644 --- a/frontend/src/components/BreadcrumbNav.styles.js +++ b/frontend/src/components/BreadcrumbNav.styles.js @@ -1,67 +1,38 @@ import styled from 'styled-components'; -import { Link } from 'react-router-dom'; -export const BreadcrumbContainer = styled.div` +export const BreadcrumbContainer = styled.nav` font-size: 14px; padding-top: var(--space-40); a { text-decoration: none; font-weight: bold; - } - - .TeamBreadCrumb { - color: ${props => props.status === 'team' && 'var(--pirlo-blue)'}; - } - - .TeamBreadCrumb:hover { - color: ${props => - props.status === 'team' && 'var(--pirlo-blue-darker)'}; - } - - .SeriesBreadCrumb { - color: ${props => props.status === 'series' && 'var(--pirlo-blue)'}; - } - .SeriesBreadCrumb:hover { - color: ${props => - props.status === 'series' && 'var(--pirlo-blue-darker)'}; - } + &:hover { + text-decoration: underline; + color: var(--titan-green-darker); + background: var(--hermanni-grey-lighter); + } - .BuildBreadCrumb { - color: ${props => props.status === 'build' && 'var(--pirlo-blue)'}; - } + &.active { + color: var(--pirlo-blue); - .BuildBreadCrumb:hover { - color: ${props => - props.status === 'build' && 'var(--pirlo-blue-darker)'}; + &:hover { + color: var(--pirlo-blue-darker); + } + } } `; -export const StyledInnerDiv = styled.ol` +export const StyledInnerOl = styled.ol` display: inline; display: flex; flex-direction: row; list-style-type: none; padding: 0; - #SuiteBreadCrumb { - color: var(--pirlo-blue); - font-weight: bolder; - } - span { color: var(--tonic-grey); padding: 0 var(--space-8); } `; - -export const StyledLink = styled(Link)` - &:hover { - text-decoration: underline; - } -`; - -export const TeamsLink = styled(StyledLink)` - padding-left: 0 !important; -`; diff --git a/frontend/src/components/Footer.styles.js b/frontend/src/components/Footer.styles.js index 5d1fe603..85d2df70 100644 --- a/frontend/src/components/Footer.styles.js +++ b/frontend/src/components/Footer.styles.js @@ -9,8 +9,12 @@ export const FooterContainer = styled.footer` height: var(--space-48); a { - background: var(--titan-green); + background-color: var(--titan-green); color: var(--nero-white) !important; + + &:focus { + outline-color: var(--nero-white); + } } .underline { @@ -19,14 +23,14 @@ export const FooterContainer = styled.footer` `; export const EpiIcon = styled.span` - margin-left: 40px; + margin-left: var(--space-40); background: var(--nero-white); color: var(--titan-green); - border-radius: 6px; - padding: 0 7px; + border-radius: var(--space-4); + padding: 0 var(--space-8); font-weight: bolder; `; export const TextStyles = styled.span` - margin-left: 20px; + margin-left: var(--space-24); `; diff --git a/frontend/src/components/MainNav.jsx b/frontend/src/components/MainNav.jsx index 96959044..00edfa8b 100644 --- a/frontend/src/components/MainNav.jsx +++ b/frontend/src/components/MainNav.jsx @@ -1,4 +1,3 @@ -// eslint-disable-next-line import React from 'react'; import { NavLink } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; @@ -18,22 +17,15 @@ const MainNav = () => { {t('logo')} - + {t('help')} - + {t('team')} - {t('github')} + + {t('github')} + diff --git a/frontend/src/components/MainNav.styles.js b/frontend/src/components/MainNav.styles.js index 490b6275..916d6f4c 100644 --- a/frontend/src/components/MainNav.styles.js +++ b/frontend/src/components/MainNav.styles.js @@ -1,7 +1,7 @@ import styled from 'styled-components'; export const NavBar = styled.nav` - background: var(--titan-green); + background-color: var(--titan-green); color: var(--nero-white); display: flex; align-items: center; @@ -9,51 +9,45 @@ export const NavBar = styled.nav` `; export const SiteLogo = styled.div` - padding: 0px 24px 0px 40px; + margin: 0px var(--space-24) 0px var(--space-40); font-family: 'Hack' !important; letter-spacing: 1px; font-size: 30px; font-weight: 700; + @media only screen and (max-width: 540px) { - width: 0; + width: var(--space-16); + margin-right: 0; overflow: hidden; - display: block; } `; export const LinkContainer = styled.div` a { - margin: 0 15px 0 15px; - color: var(--nero-white) !important; - font-size: 16px; - line-height: 24px; + color: var(--nero-white); + font-size: var(--space-16); + line-height: var(--space-24); font-weight: bold; text-decoration: none; border-bottom: none; - } + margin: 0 var(--space-16) 0 var(--space-16); + padding-bottom: var(--space-4); - a:hover, - .about:hover, - .team:hover { - background: var(--titan-green); - border-bottom: 3px solid var(--titan-green-darkest); - } - a:focus { - outline-color: var(--nero-white); - } + &:hover { + background-color: var(--titan-green); + border-bottom: var(--space-4) solid var(--titan-green-darkest); + } - .about { - border-bottom: ${props => !props.team && '3px solid var(--nero-white)'}; - } + &:focus { + outline-color: var(--nero-white); + } - .team { - border-bottom: ${props => props.team && '3px solid var(--nero-white)'}; + &.active { + border-bottom: var(--space-4) solid var(--nero-white); + } } @media only screen and (max-width: 540px) { - margin-left: 10px; - a { - margin: 0 5px 0 5px; - } + margin-left: var(--space-4); } `; diff --git a/frontend/src/components/metadata/MetadataTable.styles.js b/frontend/src/components/metadata/MetadataTable.styles.js index d007cf0a..63e33342 100644 --- a/frontend/src/components/metadata/MetadataTable.styles.js +++ b/frontend/src/components/metadata/MetadataTable.styles.js @@ -68,8 +68,4 @@ export const DataRow = styled.div` font-weight: bolder; padding-bottom: 8px; } - - a:hover { - color: var(--titan-green-darker); - } `; diff --git a/frontend/src/components/suite/Testlist.styles.js b/frontend/src/components/suite/Testlist.styles.js index 88f78e9b..b15e3de2 100644 --- a/frontend/src/components/suite/Testlist.styles.js +++ b/frontend/src/components/suite/Testlist.styles.js @@ -144,10 +144,6 @@ export const StyledLink = styled(({ isselected, ...props }) => ( flex: 2; color: ${props => props.isselected && 'var(--pirlo-blue) !important'}; outline-offset: -2px; - - :hover { - color: var(--titan-green-darker); - } `; export const SvgStatus = styled.span` diff --git a/frontend/src/components/table/Table.styles.js b/frontend/src/components/table/Table.styles.js index a1c43cc5..7ee72978 100644 --- a/frontend/src/components/table/Table.styles.js +++ b/frontend/src/components/table/Table.styles.js @@ -58,12 +58,6 @@ export const SpreadSheetTable = styled.table` &:last-of-type { padding-right: var(--space-8); } - - a { - &:visited { - color: var(--evidence-grey); - } - } } } } @@ -74,10 +68,6 @@ export const SpreadSheetTable = styled.table` &:hover { text-decoration: underline; } - - &:active { - color: var(--pirlo-blue); - } } `; @@ -135,12 +125,6 @@ export const SimpleTable = styled.table` bottom: 0; left: 0; } - - a { - &:visited { - color: var(--evidence-grey); - } - } } } } @@ -151,10 +135,6 @@ export const SimpleTable = styled.table` &:hover { text-decoration: underline; } - - &:active { - color: var(--pirlo-blue); - } } `; diff --git a/frontend/src/index.css b/frontend/src/index.css index 724221e7..62c4d1ce 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -1,3 +1,10 @@ +/* Fonts +----------------------*/ +@import url('https://fonts.googleapis.com/css?family=Open+Sans'); +@import url('https://fonts.googleapis.com/css?family=Cantarell'); +@import url('https://fonts.googleapis.com/css?family=Space+Mono'); +@import url('https://fonts.googleapis.com/css?family=Noto+Serif'); + /* Box-sizing ----------------------*/ html { @@ -9,14 +16,6 @@ html { box-sizing: inherit; } -/* Fonts -----------------------*/ - -@import url('https://fonts.googleapis.com/css?family=Open+Sans'); -@import url('https://fonts.googleapis.com/css?family=Cantarell'); -@import url('https://fonts.googleapis.com/css?family=Space+Mono'); -@import url('https://fonts.googleapis.com/css?family=Noto+Serif'); - :root { /* Colors ----------------------*/ @@ -71,7 +70,7 @@ html { /** Basics **/ body { - font-family: 'Hack'; + font-family: 'Hack', monospace; font-size: 14px; line-height: 24px; } @@ -81,7 +80,7 @@ h2, h3, h4, h5 { - font-family: 'Noto Serif Semibold'; + font-family: 'Noto Serif Semibold', serif; margin-top: var(--space-40); margin-bottom: var(--space-24); } @@ -128,7 +127,6 @@ a { } a:hover { - cursor: pointer; text-decoration: underline; background: var(--hermanni-grey-lighter); color: var(--titan-green-darker); @@ -138,6 +136,11 @@ a:focus { outline: 2px solid var(--pirlo-blue); } +a:active { + color: var(--pirlo-blue); + text-decoration: underline; +} + button { cursor: pointer; } From d4c796c5be617a14c0560e1a1116a7a5be20d6e7 Mon Sep 17 00:00:00 2001 From: Tiia Valtonen Date: Tue, 30 Mar 2021 13:08:02 +0300 Subject: [PATCH 10/35] Feature/159 - Improvements to cards (#162) * 159 - Rename folder and files and separate SeriesList from SeriesCard * 159 - Accessibility and style improvements: create actual links and remove redundant hovers/focuses. The card headers are links from now on. * 159 - Change class names' from camel case to kebab case * 159 - Create rounded corners for first and last row's first and last SeriesCard * 159 - Create shared styles for cards * 159 - Improve structure by creating TeamList + style Team page and TeamCard * 159 - Fix tests --- .../resources/page_locators/build_page.robot | 4 +- .../resources/page_locators/series_page.robot | 4 +- .../resources/page_locators/team_page.robot | 2 +- frontend/src/components/TestIcon.js | 18 +-- frontend/src/components/card/SeriesCard.jsx | 65 ++++++++ .../src/components/card/SeriesCard.styles.js | 28 ++++ frontend/src/components/card/TeamCard.jsx | 20 +++ .../src/components/card/TeamCard.styles.js | 10 ++ frontend/src/components/card/card.styles.js | 141 +++++++++++++++++ frontend/src/components/team/Card.jsx | 27 ---- frontend/src/components/team/Card.styles.js | 38 ----- frontend/src/components/team/SelectedTeam.jsx | 149 ------------------ .../components/team/SelectedTeam.styles.js | 113 ------------- frontend/src/pages/SeriesList.jsx | 76 +++++++++ frontend/src/pages/SeriesList.styles.js | 7 + frontend/src/pages/Team.jsx | 32 +--- frontend/src/pages/Team.styles.js | 20 --- frontend/src/pages/TeamList.jsx | 39 +++++ 18 files changed, 404 insertions(+), 389 deletions(-) create mode 100644 frontend/src/components/card/SeriesCard.jsx create mode 100644 frontend/src/components/card/SeriesCard.styles.js create mode 100644 frontend/src/components/card/TeamCard.jsx create mode 100644 frontend/src/components/card/TeamCard.styles.js create mode 100644 frontend/src/components/card/card.styles.js delete mode 100644 frontend/src/components/team/Card.jsx delete mode 100644 frontend/src/components/team/Card.styles.js delete mode 100644 frontend/src/components/team/SelectedTeam.jsx delete mode 100644 frontend/src/components/team/SelectedTeam.styles.js create mode 100644 frontend/src/pages/SeriesList.jsx create mode 100644 frontend/src/pages/SeriesList.styles.js delete mode 100644 frontend/src/pages/Team.styles.js create mode 100644 frontend/src/pages/TeamList.jsx diff --git a/end_to_end_tests/resources/page_locators/build_page.robot b/end_to_end_tests/resources/page_locators/build_page.robot index a1a93468..da205c13 100644 --- a/end_to_end_tests/resources/page_locators/build_page.robot +++ b/end_to_end_tests/resources/page_locators/build_page.robot @@ -4,8 +4,8 @@ ${pass_checkbox_locator} xpath://*[@id="last-run-checkbox-container"]/label[2 ${table_locator} xpath://*[@id="last-run-table"]/tbody ${table_row_locator} xpath://*[@id="last-run-table"]/tbody/tr -${pass_span} xpath://*[@id="last-run-table"]/tbody/tr[*]/td[*]/span[text()='Pass'] -${fail_span} xpath://*[@id="last-run-table"]/tbody/tr[*]/td[*]/span[text()='Fail'] +${pass_span} xpath://*[@id="last-run-table"]/tbody/tr[*]/td[*]/span[text()='Status: Pass'] +${fail_span} xpath://*[@id="last-run-table"]/tbody/tr[*]/td[*]/span[text()='Status: Fail'] ${last_run_table} xpath://*[@id="last-run-table"] ${first_suite} xpath://*[@id="last-run-table"]/tbody/tr[1]/th[1]/a diff --git a/end_to_end_tests/resources/page_locators/series_page.robot b/end_to_end_tests/resources/page_locators/series_page.robot index 8af6a3ef..3a562ce3 100644 --- a/end_to_end_tests/resources/page_locators/series_page.robot +++ b/end_to_end_tests/resources/page_locators/series_page.robot @@ -1,5 +1,5 @@ ***Variables*** ${series_xpath} xpath://*[@id="selectedTeam"]/div[2]/div[1]/div[2]/div[1]/h4 -${series_list} xpath://*[@id="selectedTeam"]/div[3]/div/div/section[*] +${series_list} xpath://*[@id="selectedTeam"]/div[3]/div/div[2]/section[*] ${team_breadcrumb} xpath://*[@id="TeamBreadCrumb"] -${series_click_elements} xpath://*[@id="selectedTeam"]/div[2]/div[*]/div/div[2]/div[1] +${series_click_elements} xpath://*[@id="selectedTeam"]/div[3]/div/div[2]/section/span[1]/a diff --git a/end_to_end_tests/resources/page_locators/team_page.robot b/end_to_end_tests/resources/page_locators/team_page.robot index 93c7ce8e..85b54464 100644 --- a/end_to_end_tests/resources/page_locators/team_page.robot +++ b/end_to_end_tests/resources/page_locators/team_page.robot @@ -1,3 +1,3 @@ ***Variables*** ${team_xpath} xpath://*[@id="team"]/div/section/h4 -${teams_xpath} xpath://*[@id="team"]/div/div/div/section[*] +${teams_xpath} xpath://*[@id="team"]/div[2]/div/div/section[*] diff --git a/frontend/src/components/TestIcon.js b/frontend/src/components/TestIcon.js index dc99682b..97f62c5c 100644 --- a/frontend/src/components/TestIcon.js +++ b/frontend/src/components/TestIcon.js @@ -27,32 +27,32 @@ export const pickIcon = (test_status, key) => { case 'PASS': result = ( <> - - Pass +
    - - - + {t('series.stability_table.test_name')} + + {failureList.map(entry => { return ( - + {entry.name} ); })} - + ); }; diff --git a/frontend/src/components/dashlist/FailureTable.styles.js b/frontend/src/components/dashlist/FailureTable.styles.js index 892c4f86..b94a316e 100644 --- a/frontend/src/components/dashlist/FailureTable.styles.js +++ b/frontend/src/components/dashlist/FailureTable.styles.js @@ -1,36 +1,6 @@ import styled from 'styled-components'; export const TableContainer = styled.div` - border-top: solid; - border-color: var(--tonic-grey); - max-width: 100%; - grid-area: table; - max-height: 100%; - overflow-y: scroll; + border-top: 1px solid var(--tonic-grey); padding-top: var(--space-8); `; - -export const StyledTable = styled.table` - th:nth-of-type(1) { - width: 70%; - } - th:nth-of-type(2) { - width: 20%; - } - th:nth-of-type(3) { - width: 10%; - } - - th { - border-bottom: 1px solid var(--tonic-grey); - padding-left: 5px; - padding-right: 5px; - text-align: left; - } - td { - border-bottom: 1px solid var(--tonic-grey); - padding-left: 5px; - padding-right: 5px; - text-align: left; - } -`; diff --git a/frontend/src/components/dashlist/FlakinessTable.jsx b/frontend/src/components/dashlist/FlakinessTable.jsx index 330e1265..6eb0fd37 100644 --- a/frontend/src/components/dashlist/FlakinessTable.jsx +++ b/frontend/src/components/dashlist/FlakinessTable.jsx @@ -1,10 +1,13 @@ import React, { useEffect } from 'react'; import { useParams } from 'react-router'; import { useStateValue } from '../../contexts/state'; -import { TableContainer, StyledTable } from './FlakinessTable.styles'; +import { useTranslation } from 'react-i18next'; +import { TableContainer } from './FlakinessTable.styles'; import { ToggleButtonSmall } from '../buttons/button.styles'; +import { BreakWordTd, SimpleTable, WideTh } from '../table/Table.styles'; const StabilityButton = ({ value, text }) => { + const [t] = useTranslation(['overview']); const [{ stabilityChecker }, dispatch] = useStateValue(); return ( { document.getElementById( 'flakiness-table-status' - ).textContent = `Content updated. Showing now ${value} in stability table.`; + ).textContent = `${t('series.status_update_stability', { + value, + })}`; }} > {text} @@ -28,6 +33,7 @@ const StabilityButton = ({ value, text }) => { }; const DashboardList = () => { + const [t] = useTranslation(['overview']); const { seriesId } = useParams(); const [ { testStabilityList, stabilityChecker, amountOfBuilds, offset }, @@ -54,29 +60,35 @@ const DashboardList = () => { {' '}

    - - + + - +
    - - - + {t('series.stability_table.test_name')} + + {testStabilityList.map(test => { return ( - + {test.test_name} ); })} - + ); }; diff --git a/frontend/src/components/dashlist/FlakinessTable.styles.js b/frontend/src/components/dashlist/FlakinessTable.styles.js index 5eea8c3c..8775b254 100644 --- a/frontend/src/components/dashlist/FlakinessTable.styles.js +++ b/frontend/src/components/dashlist/FlakinessTable.styles.js @@ -1,38 +1,9 @@ import styled from 'styled-components'; export const TableContainer = styled.div` - border-top: solid; - border-color: var(--tonic-grey); - width: 100%; - max-height: 400px; - overflow-y: scroll; + border-top: 1px solid var(--tonic-grey); button { margin: var(--space-16) var(--space-8) var(--space-16) 0; } `; - -export const StyledTable = styled.table` - th:nth-of-type(1) { - width: 70%; - } - th:nth-of-type(2) { - width: 20%; - } - th:nth-of-type(3) { - width: 10%; - } - - th { - border-bottom: 1px solid var(--tonic-grey); - padding-left: 5px; - padding-right: 5px; - text-align: left; - } - td { - border-bottom: 1px solid var(--tonic-grey); - padding-left: 5px; - padding-right: 5px; - text-align: left; - } -`; diff --git a/frontend/src/components/dashlist/ListMain.jsx b/frontend/src/components/dashlist/ListMain.jsx index d7d14be5..7413c48e 100644 --- a/frontend/src/components/dashlist/ListMain.jsx +++ b/frontend/src/components/dashlist/ListMain.jsx @@ -1,21 +1,23 @@ import React, { useState } from 'react'; import FlakinessTable from './FlakinessTable'; import FailureTable from './FailureTable'; -import { StyledListContainer, TableSelectors } from './ListMain.styles'; +import { useTranslation } from 'react-i18next'; +import { TableSelectors } from './ListMain.styles'; import { ToggleButton } from '../buttons/button.styles'; const DashboardList = () => { - const [window, setWindow] = useState('flakiness'); + const [t] = useTranslation(['overview']); + const [window, setWindow] = useState('stability'); function updateTable(window) { setWindow(window); document.getElementById( 'stability-table-status' - ).textContent = `Content updated. Showing now ${window} table.`; + ).textContent = `${t('series.status_update', { window })}`; } return ( - +

    {' '}

    @@ -26,11 +28,11 @@ const DashboardList = () => { > updateTable('flakiness')} + aria-checked={window === 'stability'} + className={window === 'stability' ? 'selected' : ''} + onClick={() => updateTable('stability')} > - Stability + {t('series.stability_table.stability')} { className={window === 'failures' ? 'selected' : ''} onClick={() => updateTable('failures')} > - Failures + {t('series.stability_table.failures')} - - {window === 'flakiness' ? : } - - +
    + {window === 'stability' ? : } +
    +
    ); }; diff --git a/frontend/src/components/dashlist/ListMain.styles.js b/frontend/src/components/dashlist/ListMain.styles.js index c5e1eddb..709b5f08 100644 --- a/frontend/src/components/dashlist/ListMain.styles.js +++ b/frontend/src/components/dashlist/ListMain.styles.js @@ -1,23 +1,6 @@ import styled from 'styled-components'; -export const StyledListContainer = styled.div` - padding: 10px; - display: inline-grid; - min-width: 100%; - height: 500px; - grid-template-columns: 1fr 1fr; - grid-template-rows: 0.6fr 0.55fr 6fr; - grid-template-areas: - 'selectorbox selectorbox' - 'table table'; - - #stability-table { - grid-area: table; - } -`; - export const TableSelectors = styled.div` - grid-area: selectorbox; margin-bottom: var(--space-16); button { diff --git a/frontend/src/components/graphs/SuiteInstability.js b/frontend/src/components/graphs/SuiteInstability.js index 707c8240..8fedab25 100644 --- a/frontend/src/components/graphs/SuiteInstability.js +++ b/frontend/src/components/graphs/SuiteInstability.js @@ -4,9 +4,9 @@ import { VegaLite } from 'react-vega'; import { useStateValue } from '../../contexts/state'; import Loading from '../Loading'; import { colorTypes } from '../../utils/colorTypes'; -import styled, { css } from 'styled-components'; -import { baseTable } from '../../styles/baseComponents'; +import { css } from 'styled-components'; import { pickIcon } from '../TestIcon'; +import { Table } from '../table/Table'; const canvasStyles = css` padding: 20px 0px; @@ -15,16 +15,6 @@ const canvasStyles = css` } `; -const SuiteTable = styled(baseTable)` - width: 100%; - th { - font-family: 'Hack'; - } - td { - font-family: 'Hack'; - } -`; - const SuiteInstability = () => { const [selectedSuite, setSelectedSuite] = useState(null); const [ @@ -286,7 +276,7 @@ const SuiteInstability = () => { css={canvasStyles} /> {selectedSuite && ( - +
    Test_Name
    Test_NameTest_IdFailures{t('series.stability_table.test_id')}{t('series.stability_table.flakiness')}
    {entry.name} {entry.id} {entry.failures}
    Test_NameTest_IdFlakiness{t('series.stability_table.test_id')}{t('series.stability_table.flakiness')}
    {test.test_name} {test.test_id} {test.instability.toFixed(2)}
    @@ -301,7 +291,7 @@ const SuiteInstability = () => { ))} - +
    {selectedSuite.name}
    )} ); diff --git a/frontend/src/components/graphs/TimeLineChart.js b/frontend/src/components/graphs/TimeLineChart.js index 839f8192..8a7ae1f5 100644 --- a/frontend/src/components/graphs/TimeLineChart.js +++ b/frontend/src/components/graphs/TimeLineChart.js @@ -41,7 +41,7 @@ const TimeLineChart = () => { }; const namedBuildNumberList = - statusCount && statusCount.map(build => 'Build: ' + build.build_number); + statusCount && statusCount.map(build => build.build_number); const series = [ { @@ -61,15 +61,26 @@ const TimeLineChart = () => { const options = { xaxis: { categories: namedBuildNumberList, + title: { + text: 'Build', + }, labels: { rotate: -45, rotateAlways: false, hideOverlappingLabels: true, }, }, + yaxis: { + title: { + text: 'Number of tests', + }, + }, stroke: { curve: 'smooth', }, + legend: { + position: 'top', + }, colors: [ colorTypes['titan green'], colorTypes['semolina red'], @@ -102,12 +113,7 @@ const TimeLineChart = () => {
    {namedBuildNumberList && statusCount ? ( - + ) : ( diff --git a/frontend/src/components/lastBuildElement/BuildInfoTable.js b/frontend/src/components/lastBuildElement/BuildInfoTable.jsx similarity index 59% rename from frontend/src/components/lastBuildElement/BuildInfoTable.js rename to frontend/src/components/lastBuildElement/BuildInfoTable.jsx index 54646c78..d07ad918 100644 --- a/frontend/src/components/lastBuildElement/BuildInfoTable.js +++ b/frontend/src/components/lastBuildElement/BuildInfoTable.jsx @@ -1,30 +1,32 @@ import React from 'react'; import { useStateValue } from '../../contexts/state'; -import { LastBuildTable } from './BuildInfoTable.styles'; +import { useTranslation } from 'react-i18next'; +import { SimpleTable, WideTh } from '../table/Table.styles'; const BuildInfoTable = () => { + const [t] = useTranslation(['overview']); const [ { parentData: { seriesData }, }, ] = useStateValue(); return ( - + - Last Build ID + {t('series.last_build.id')} {seriesData.last_build_id} - Start Time + {t('series.last_build.start_time')} {seriesData.last_started} - Status + {t('series.last_build.status')} {seriesData.last_status} - + ); }; diff --git a/frontend/src/components/lastBuildElement/BuildInfoTable.styles.js b/frontend/src/components/lastBuildElement/BuildInfoTable.styles.js deleted file mode 100644 index 95afc962..00000000 --- a/frontend/src/components/lastBuildElement/BuildInfoTable.styles.js +++ /dev/null @@ -1,26 +0,0 @@ -import styled from 'styled-components'; - -export const LastBuildTable = styled.table` - width: 100%; - - th { - margin: 20px; - text-align: left; - vertical-align: middle; - } - - td { - margin: 20px; - padding-right: 5px; - text-align: left; - vertical-align: middle; - } - - td:nth-of-type(1) { - width: 40%; - } - - td:nth-of-type(2) { - width: 50%; - } -`; diff --git a/frontend/src/components/lastBuildElement/FailuresTable.js b/frontend/src/components/lastBuildElement/FailuresTable.js deleted file mode 100644 index 05b799fe..00000000 --- a/frontend/src/components/lastBuildElement/FailuresTable.js +++ /dev/null @@ -1,51 +0,0 @@ -import React from 'react'; -import styled from 'styled-components'; - -const LastBuildTable = styled.table` - width: 100%; - th { - margin: 20px; - text-align: left; - vertical-align: middle; - border-bottom: 1px solid var(--tonic-grey); - } - - td { - padding-right: 5px; - margin: 20px; - text-align: left; - vertical-align: middle; - } - thead th:nth-of-type(1) { - width: 40%; - } - - thead th:nth-of-type(2) { - width: 50%; - } -`; - -const FailuresTable = ({ failures }) => { - return ( - - - - Suite - Test Case - - - - {failures.map(x => { - return ( - - {x.suite} - {x.name} - - ); - })} - - - ); -}; - -export default FailuresTable; diff --git a/frontend/src/components/lastBuildElement/FailuresTable.jsx b/frontend/src/components/lastBuildElement/FailuresTable.jsx new file mode 100644 index 00000000..f0260826 --- /dev/null +++ b/frontend/src/components/lastBuildElement/FailuresTable.jsx @@ -0,0 +1,29 @@ +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { SimpleTable } from '../table/Table.styles'; + +const FailuresTable = ({ failures }) => { + const [t] = useTranslation(['overview']); + return ( + + + + {t('series.last_build.suite')} + {t('series.last_build.test_case')} + + + + {failures.map(x => { + return ( + + {x.suite} + {x.name} + + ); + })} + + + ); +}; + +export default FailuresTable; diff --git a/frontend/src/components/lastBuildElement/LastBuild.js b/frontend/src/components/lastBuildElement/LastBuild.jsx similarity index 82% rename from frontend/src/components/lastBuildElement/LastBuild.js rename to frontend/src/components/lastBuildElement/LastBuild.jsx index 54ea16a2..a6083725 100644 --- a/frontend/src/components/lastBuildElement/LastBuild.js +++ b/frontend/src/components/lastBuildElement/LastBuild.jsx @@ -1,22 +1,14 @@ /* eslint-disable react-hooks/exhaustive-deps */ import React, { useEffect, useState } from 'react'; -import styled from 'styled-components'; import FailuresTable from './FailuresTable'; import BuildInfoTable from './BuildInfoTable'; import { useParams } from 'react-router'; import { useStateValue } from '../../contexts/state'; - -const TableHeading = styled.div` - border-bottom: 1px solid var(--tonic-grey); - min-width: 300px; - font-weight: bold; -`; - -const Containing = styled.div` - min-width: 300px; -`; +import { useTranslation } from 'react-i18next'; +import { TableHeading } from './LastBuild.styles'; const LastBuildElement = () => { + const [t] = useTranslation(['overview']); const { seriesId } = useParams(); const [failures, setFailures] = useState([]); const [{ offset }, dispatch] = useStateValue(); @@ -58,16 +50,17 @@ const LastBuildElement = () => { }, [seriesId, offset]); return ( - - Last Build Status + <> {failures.length > 0 && ( - - Failing Test Cases + <> + + {t('series.last_build.failing_cases')} + - + )} - + ); }; diff --git a/frontend/src/components/lastBuildElement/LastBuild.styles.js b/frontend/src/components/lastBuildElement/LastBuild.styles.js new file mode 100644 index 00000000..7e686b10 --- /dev/null +++ b/frontend/src/components/lastBuildElement/LastBuild.styles.js @@ -0,0 +1,8 @@ +import styled from 'styled-components'; + +export const TableHeading = styled.h3` + font-family: 'Hack'; + font-size: 14px; + text-align: center; + margin: var(--space-24) 0 var(--space-8) 0; +`; diff --git a/frontend/src/components/overview/Build.styles.js b/frontend/src/components/overview/Build.styles.js index ee6fff71..dad11853 100644 --- a/frontend/src/components/overview/Build.styles.js +++ b/frontend/src/components/overview/Build.styles.js @@ -1,5 +1,4 @@ import styled from 'styled-components'; -import { overviewElement } from '../../styles/baseComponents'; export const PageContainer = styled.div` display: flex; @@ -14,7 +13,9 @@ export const FlexDiv = styled.div` width: 100%; `; -export const ChartContainer = styled(overviewElement)` +export const ChartContainer = styled.div` + padding: var(--space-8); + border: 1px solid var(--evidence-grey); margin: 0 0 var(--space-24) 0; background-color: var(--nero-white); width: ${props => props.width}; diff --git a/frontend/src/components/overview/Series.jsx b/frontend/src/components/overview/Series.jsx index ec30dc6d..32cb9f84 100644 --- a/frontend/src/components/overview/Series.jsx +++ b/frontend/src/components/overview/Series.jsx @@ -11,6 +11,7 @@ import { ChartContainer, ElementHeader, } from './Series.styles'; +import { TableHolder } from './Series.styles'; const Series = () => { const [t] = useTranslation(['overview']); @@ -53,19 +54,26 @@ const Series = () => { }, [seriesId, branchesState]); return ( - - + <> + {t('series.all_builds')} - - - - - {t('series.stability_table')} - - - + + + + {t('series.last_build.title')} + + + + + + {t('series.stability_table.title')} + + + + + ); }; diff --git a/frontend/src/components/overview/Series.styles.js b/frontend/src/components/overview/Series.styles.js index c347a65d..0da2056d 100644 --- a/frontend/src/components/overview/Series.styles.js +++ b/frontend/src/components/overview/Series.styles.js @@ -1,19 +1,37 @@ import styled from 'styled-components'; -import { overviewElement } from '../../styles/baseComponents'; export const ParentContainer = styled.div` display: flex; - flex-flow: row wrap; + flex-wrap: wrap; + align-items: flex-start; + column-gap: var(--space-24); `; -export const ChartContainer = styled(overviewElement)` - margin: var(--space-24) var(--space-40) var(--space-40) 0; - background-color: var(--nero-white); - width: ${props => props.width}; +export const ChartContainer = styled.div` + border: 1px solid var(--evidence-grey); + padding: var(--space-8); + margin: 0 0 var(--space-24) 0; + width: 100%; + max-width: calc(var(--max-page-width) / 1.6); `; -export const ElementHeader = styled.h3` - text-align: center; - margin: var(--space-8); +export const ElementHeader = styled.h2` font-family: 'Hack'; + font-size: 20px; + text-align: center; + margin-top: 0; +`; + +export const TableHolder = styled.div` + border: 1px solid var(--evidence-grey); + margin-bottom: var(--space-24); + padding: var(--space-16); + + &:first-of-type { + flex: 2; + } + + &:last-of-type { + flex: 3; + } `; diff --git a/frontend/src/components/table/Table.styles.js b/frontend/src/components/table/Table.styles.js index 7ee72978..70e5880c 100644 --- a/frontend/src/components/table/Table.styles.js +++ b/frontend/src/components/table/Table.styles.js @@ -81,7 +81,7 @@ export const SimpleTable = styled.table` text-align: left; & tr th { - padding: var(--space-8) 0 var(--space-4) 0; + padding: var(--space-8) var(--space-8) var(--space-4) 0; } } @@ -98,9 +98,11 @@ export const SimpleTable = styled.table` border-bottom: 0; } - td { - padding: 1px 0; + td, + th { + padding: 1px var(--space-8) 1px 0; position: relative; + text-align: left; &:first-of-type { padding-left: 2px; @@ -140,12 +142,20 @@ export const SimpleTable = styled.table` export const WideTh = styled.th` min-width: 200px; + + @media only screen and (max-width: 540px) { + min-width: unset; + } `; export const NarrowTh = styled.th` max-width: 160px; `; +export const BreakWordTd = styled.td` + overflow-wrap: anywhere; +`; + function calculateSpanMargin() { let spansMarginRules = []; diff --git a/frontend/src/locales/en/overview.json b/frontend/src/locales/en/overview.json index 215d7b3c..1efa83d6 100644 --- a/frontend/src/locales/en/overview.json +++ b/frontend/src/locales/en/overview.json @@ -1,8 +1,28 @@ { "series": { "all_builds": "All Build History", - "stability_table": "Stability Table", - "unstable_tests": "Suites with unstable tests" + "stability_table": { + "title": "Stability Table", + "test_name": "Test_Name", + "test_id": "Test_Id", + "flakiness": "Flakiness", + "stability": "Stability", + "failures": "Failures", + "unstable": "Unstable", + "stable": "Stable" + }, + "unstable_tests": "Suites with unstable tests", + "last_build": { + "title": "Last Build Status", + "id": "Last build ID", + "start_time": "Start time", + "status": "Status", + "failing_cases": "Failing Test Cases", + "suite": "Suite", + "test_case": "Test case" + }, + "status_update": "Content updated. Showing now {{window}} table.", + "status_update_stability": "Content updated. Showing now {{value}} in stability table." }, "build": { "test": "Test status", diff --git a/frontend/src/styles/baseComponents.js b/frontend/src/styles/baseComponents.js index a08abf8d..354670b0 100644 --- a/frontend/src/styles/baseComponents.js +++ b/frontend/src/styles/baseComponents.js @@ -1,53 +1,5 @@ import styled from 'styled-components'; -export const baseTable = styled.table` - table-layout: fixed; - width: 100%; - border-collapse: separate !important; - border-spacing: 0; - text-align: left; - vertical-align: top; - word-wrap: break-word; - - thead { - background: var(--hermanni-grey); - } - - td { - } - td.test-result-undefined { - background: var(--hermanni-grey); - } - - td, - th { - padding: 8px; - text-align: left; - word-wrap: break-word; - vertical-align: top; - } - - td { - background: var(--nero-white); - } - - tr { - border-top: 1px solid var(--hermanni-grey); - } - a { - text-decoration: none; - } -`; - -export const overviewElement = styled.div` - padding: 10px; - border-style: solid; - border-width: thin; - display: block; - margin: 20px; - height: min-content; -`; - export const ContainerGrid12 = styled.div` max-width: calc(var(--max-page-width) + calc(100% / 12) + calc(100% / 12)); padding-right: calc(100% / 12); @@ -59,151 +11,3 @@ export const ContentGrid6 = styled.div` max-width: 100%; margin: 0 calc(100% / 12); `; - -export const SpreadSheetTable = styled.table` - width: 100%; - border-collapse: separate; - font-size: 12px; - line-height: 20px; - border: 1px solid var(--evidence-grey-lighter); - border-radius: 10px; - border-spacing: 0; - - thead { - border-radius: 4px; - text-align: left; - - & tr th { - padding: var(--space-8) var(--space-16) var(--space-4) 0; - background-color: var(--hermanni-grey); - &:first-of-type { - border-radius: 10px 0 0 0; - padding-left: var(--space-8); - } - &:last-of-type { - border-radius: 0 10px 0 0; - padding-right: var(--space-8); - } - } - } - - tbody { - & tr { - vertical-align: top; - - &:hover { - background-color: var(--kumpula-yellow); - } - - &:last-of-type { - border-bottom: 0; - - & td:first-of-type { - border-radius: 0 0 0 10px; - } - - & td:last-of-type { - border-radius: 0 0 10px 0; - } - } - - & td { - border-bottom: 1px solid var(--hermanni-grey); - position: relative; - padding: var(--space-4) var(--space-8) var(--space-4) 0; - - &:first-of-type { - padding-left: var(--space-8); - } - - &:last-of-type { - padding-right: var(--space-8); - } - } - } - } - - a { - text-decoration: none; - - &:hover { - text-decoration: underline; - display: inline-block; - } - - &:active { - color: var(--pirlo-blue); - } - } -`; - -export const SimpleTable = styled.table` - width: 100%; - border-collapse: collapse; - font-size: 12px; - line-height: 20px; - - thead { - text-align: left; - - & tr th { - padding: 8px 0 4px 0; - } - } - - tbody { - & tr { - border-bottom: 1px solid var(--hermanni-grey); - vertical-align: top; - - &:hover { - background-color: var(--kumpula-yellow); - } - - &:last-of-type { - border-bottom: 0; - } - - & td { - padding: 1px 0; - position: relative; - - &:first-of-type { - padding-left: 2px; - } - - &::before { - content: ''; - width: 100%; - height: 1px; - background: white; - position: absolute; - top: 0; - left: 0; - } - - &::after { - content: ''; - width: 100%; - height: 1px; - background: white; - position: absolute; - bottom: 0; - left: 0; - } - } - } - } - - a { - text-decoration: none; - - &:hover { - text-decoration: underline; - } - - &:active { - color: var(--pirlo-blue); - } - } -`; From d7bb495effa6e4ccd83869001ec7fd51f00dcc00 Mon Sep 17 00:00:00 2001 From: Tiia Valtonen Date: Wed, 31 Mar 2021 08:59:06 +0300 Subject: [PATCH 12/35] Feature/160 - Reform accordion panel (#161) * Feature/160 - Reform accordion panel --- .../resources/page_locators/suite_page.robot | 2 +- frontend/package.json | 1 + .../src/components/accordion/Accordion.jsx | 66 ++++++++++++++++ .../components/accordion/Accordion.styles.js | 79 +++++++++++++++++++ .../buttons/LastRunCheckbox.styles.js | 8 +- .../src/components/metadata/BuildMetadata.jsx | 12 ++- .../src/components/metadata/MetadataTable.jsx | 53 ------------- .../metadata/MetadataTable.styles.js | 71 ----------------- .../src/components/metadata/SuiteMetadata.jsx | 18 ++--- frontend/src/components/suite/Testlist.jsx | 5 +- .../src/components/suite/Testlist.styles.js | 2 +- frontend/src/components/table/Table.styles.js | 8 +- .../en/{metadata.json => accordion.json} | 0 frontend/src/utils/i118n.js | 4 +- 14 files changed, 183 insertions(+), 146 deletions(-) create mode 100644 frontend/src/components/accordion/Accordion.jsx create mode 100644 frontend/src/components/accordion/Accordion.styles.js delete mode 100644 frontend/src/components/metadata/MetadataTable.jsx delete mode 100644 frontend/src/components/metadata/MetadataTable.styles.js rename frontend/src/locales/en/{metadata.json => accordion.json} (100%) diff --git a/end_to_end_tests/resources/page_locators/suite_page.robot b/end_to_end_tests/resources/page_locators/suite_page.robot index ae1c9caf..1e3e84ee 100644 --- a/end_to_end_tests/resources/page_locators/suite_page.robot +++ b/end_to_end_tests/resources/page_locators/suite_page.robot @@ -1,3 +1,3 @@ ***Variables*** ${suite_breadcrumb} xpath://*[@id="SuiteBreadCrumb"] -${suite_id_locator} xpath://*[@id="datatable"]/div[2]/span[2] +${suite_id_locator} xpath://*[@id="datatable"]/tbody/tr/td[2]/span diff --git a/frontend/package.json b/frontend/package.json index abd5241a..12568118 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -19,6 +19,7 @@ "react-scripts": "^3.4.3", "react-vega": "^7.3.0", "styled-components": "^5.1.1", + "uuid": "^3.4.0", "vega": "^5.13.0", "vega-lite": "^4.13.0" }, diff --git a/frontend/src/components/accordion/Accordion.jsx b/frontend/src/components/accordion/Accordion.jsx new file mode 100644 index 00000000..b4bfe094 --- /dev/null +++ b/frontend/src/components/accordion/Accordion.jsx @@ -0,0 +1,66 @@ +import React, { useState } from 'react'; +import { v4 as uuidv4 } from 'uuid'; +import { useTranslation } from 'react-i18next'; +import { + Container, + HeaderContainer, + Content, + SplitBorder, +} from './Accordion.styles'; +import { ReactComponent as Up } from '../../images/chevron-up.svg'; +import { ReactComponent as Down } from '../../images/chevron-down.svg'; +import { SimpleTable } from '../table/Table.styles'; + +const Accordion = ({ header, name, value }) => { + const [t] = useTranslation(['accordion']); + const [Open, setOpen] = useState(true); + const NameValuePairTable = []; + const id = uuidv4(); + + if (name.length === value.length) { + for (let i = 0; i < name.length; i++) { + NameValuePairTable.push({ name: name[i], value: value[i] }); + } + } + + return ( + + setOpen(!Open)} + aria-expanded={Open} + aria-controls={id} + > +

    {header}

    + {Open ? : } +
    + + + + + + {t('name')} + {t('value')} + + + + {NameValuePairTable.map((item, index) => ( + + {item.name} + + {item.value.includes('Http') || + item.value.includes('http') ? ( + {item.value} + ) : ( + {item.value} + )} + + + ))} + + + +
    + ); +}; + +export default Accordion; diff --git a/frontend/src/components/accordion/Accordion.styles.js b/frontend/src/components/accordion/Accordion.styles.js new file mode 100644 index 00000000..17ef3d9a --- /dev/null +++ b/frontend/src/components/accordion/Accordion.styles.js @@ -0,0 +1,79 @@ +import styled from 'styled-components'; + +export const Container = styled.div` + border: 1px solid var(--tonic-grey); + border-radius: var(--space-4); + width: 100%; + padding: var(--space-8); + margin: var(--space-24) 0; + + > * { + padding: 0 var(--space-8); + } +`; + +export const HeaderContainer = styled.button` + display: flex; + justify-content: space-between; + align-items: center; + font-size: 20px; + font-family: 'Noto Serif'; + width: 100%; + border: 0; + background: var(--nero-white); + + &:hover { + background-color: var(--hermanni-grey-lighter); + } + + &[aria-expanded='true'] { + p { + color: var(--pirlo-blue); + } + + &:hover:enabled { + background-color: var(--nero-white); + } + } + + p { + margin: 0; + padding-top: var(--space-4); + padding-bottom: var(--space-4); + line-height: var(--space-24) !important; // same as h4's + } + + .caret { + line-height: 0; + } +`; + +export const Content = styled.div` + &.Open, + &.Close { + visibility: hidden; + max-height: 0; + overflow-y: hidden; + transition: all 0.2s ease-in-out; + } + + &.Open { + visibility: visible; + max-height: 5000px; + } + + table { + overflow: hidden; + word-break: break-word; + + th:first-of-type { + min-width: 150px; + } + } +`; + +export const SplitBorder = styled.div` + background: var(--hermanni-grey-lighter); + height: var(--space-4); + margin-top: var(--space-8); +`; diff --git a/frontend/src/components/buttons/LastRunCheckbox.styles.js b/frontend/src/components/buttons/LastRunCheckbox.styles.js index adc5b105..3dba3049 100644 --- a/frontend/src/components/buttons/LastRunCheckbox.styles.js +++ b/frontend/src/components/buttons/LastRunCheckbox.styles.js @@ -24,7 +24,7 @@ export const StyledDiv = styled.div` } span { - padding-right: 8px; + padding-right: var(--space-8); position: relative; top: -1px; @@ -45,9 +45,9 @@ export const StyledInput = styled.input` appearance: none; opacity: 0; position: absolute; - top: 8px; - height: 16px; - width: 16px; + top: 6px; + height: var(--space-16); + width: var(--space-16); border-radius: 2px; &:focus { diff --git a/frontend/src/components/metadata/BuildMetadata.jsx b/frontend/src/components/metadata/BuildMetadata.jsx index d2e23aff..5fd2cd9c 100644 --- a/frontend/src/components/metadata/BuildMetadata.jsx +++ b/frontend/src/components/metadata/BuildMetadata.jsx @@ -1,9 +1,11 @@ import React from 'react'; -import MetadataTable from './MetadataTable'; +import Accordion from '../accordion/Accordion'; import { capitalCaseInitial, removeUnderscore } from '../../utils/helpers'; import { useStateValue } from '../../contexts/state'; +import { useTranslation } from 'react-i18next'; -const BuildMetadata = isOverview => { +const BuildMetadata = () => { + const [t] = useTranslation(['accordion']); const [{ metadataState }] = useStateValue(); const metadata = @@ -25,7 +27,11 @@ const BuildMetadata = isOverview => { removeUnderscore(capitalCaseInitial(metadata_value)) ); - return metadata && ; + return ( + metadata && ( + + ) + ); }; export default BuildMetadata; diff --git a/frontend/src/components/metadata/MetadataTable.jsx b/frontend/src/components/metadata/MetadataTable.jsx deleted file mode 100644 index 674e0b48..00000000 --- a/frontend/src/components/metadata/MetadataTable.jsx +++ /dev/null @@ -1,53 +0,0 @@ -import React, { useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { - Container, - HeaderContainer, - SplitBorder, - TableContainer, - DataRow, -} from './MetadataTable.styles'; -import { ReactComponent as Up } from '../../images/chevron-up.svg'; -import { ReactComponent as Down } from '../../images/chevron-down.svg'; - -const MetadataTable = ({ name, value }) => { - const [t] = useTranslation(['metadata']); - const [Open, setOpen] = useState(true); - - return ( - - setOpen(!Open)} - onKeyPress={() => setOpen(!Open)} - role="button" - tabIndex="0" - > -

    {t('metadata')}

    - {Open ? : } -
    - - - - {t('name')} - {name.map((n, index) => ( - {n} - ))} - - - {t('value')} - {value.map((v, index) => - v.includes('Http') || v.includes('http') ? ( - - {v} - - ) : ( - {v} - ) - )} - - -
    - ); -}; - -export default MetadataTable; diff --git a/frontend/src/components/metadata/MetadataTable.styles.js b/frontend/src/components/metadata/MetadataTable.styles.js deleted file mode 100644 index 63e33342..00000000 --- a/frontend/src/components/metadata/MetadataTable.styles.js +++ /dev/null @@ -1,71 +0,0 @@ -import styled from 'styled-components'; - -export const Container = styled.div` - border: 1px solid var(--hermanni-grey); - border-radius: 4px; - padding: 0 var(--space-16); - margin: var(--space-24) calc(var(--space-16) * -1); - width: calc(100% + 16px + 16px); - word-break: break-word; -`; - -export const HeaderContainer = styled.div` - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; - :hover { - cursor: pointer; - } - - font-size: 20px; - font-family: 'Noto Serif'; -`; - -export const SplitBorder = styled.div` - background: var(--hermanni-grey); - opacity: 0.4; - height: ${props => (props.open ? '4px' : '0px')}; -`; - -export const TableContainer = styled.div` - display: flex; - - .Open, - .Close { - max-height: 0; - overflow-y: hidden; - padding: 0; - -webkit-transition: max-height 0.3s ease-in-out; - -moz-transition: max-height 0.3s ease-in-out; - -o-transition: max-height 0.3s ease-in-out; - transition: max-height 0.3s ease-in-out; - -webkit-transition: padding 0.25s ease; - -moz-transition: padding 0.25s ease; - -o-transition: padding 0.25s ease; - transition: padding 0.25s ease; - } - - .Open { - max-height: 500px; - padding: 16px 0; - } -`; - -export const DataRow = styled.div` - display: flex; - flex-direction: column; - flex: ${props => (props.first ? '0.35' : '0.65')}; - - span { - border-bottom: 1px solid var(--hermanni-grey); - } - span:first-child, - span:last-child { - border-bottom: none; - } - span:first-child { - font-weight: bolder; - padding-bottom: 8px; - } -`; diff --git a/frontend/src/components/metadata/SuiteMetadata.jsx b/frontend/src/components/metadata/SuiteMetadata.jsx index 74cef50f..ccf0dc64 100644 --- a/frontend/src/components/metadata/SuiteMetadata.jsx +++ b/frontend/src/components/metadata/SuiteMetadata.jsx @@ -1,17 +1,13 @@ import React from 'react'; -import MetadataTable from './MetadataTable'; +import Accordion from '../accordion/Accordion'; import { useStateValue } from '../../contexts/state'; +import { useTranslation } from 'react-i18next'; const SuiteMetadata = () => { + const [t] = useTranslation(['accordion']); const [{ selectedSuiteState }] = useStateValue(); - const name = [ - 'Suite Id:', - 'Name:', - 'Full name:', - 'Repository:', - 'Starttime:', - ]; + const name = ['Suite Id', 'Name', 'Full name', 'Repository', 'Start time']; const value = selectedSuiteState && [ selectedSuiteState.suite.id.toString(), @@ -23,7 +19,11 @@ const SuiteMetadata = () => { : '', ]; - return selectedSuiteState && ; + return ( + selectedSuiteState && ( + + ) + ); }; export default SuiteMetadata; diff --git a/frontend/src/components/suite/Testlist.jsx b/frontend/src/components/suite/Testlist.jsx index b06cdcdc..9489dca7 100644 --- a/frontend/src/components/suite/Testlist.jsx +++ b/frontend/src/components/suite/Testlist.jsx @@ -16,16 +16,19 @@ import { TagContainer, } from './Testlist.styles'; import AttributeTag from '../attributeTag/AttributeTag'; +import { v4 as uuidv4 } from 'uuid'; const Testlist = ({ suite }) => { const { suiteId, buildId, seriesId, testId } = useParams(); const [Open, setOpen] = useState(true); + const id = uuidv4(); return ( setOpen(!Open)} aria-expanded={Open} + aria-controls={id} >

    {suite.name} Tests

    @@ -35,7 +38,7 @@ const Testlist = ({ suite }) => {

    {Open ? : }
    - +