From 1e2a904e253192813335e130ab79ae1bbebd685d Mon Sep 17 00:00:00 2001 From: cgoodwin90 Date: Thu, 20 Feb 2025 10:40:00 +1100 Subject: [PATCH 1/2] Adds copy functionality to breadcrumbs --- package.json | 1 + src/components/Breadcrumbs/Breadcrumb.tsx | 61 +++++++++++++------ .../Breadcrumbs/StyledBreadCrumb.tsx | 44 ++++++++++++- yarn.lock | 7 +++ 4 files changed, 93 insertions(+), 20 deletions(-) diff --git a/package.json b/package.json index a628be3a..0ed60710 100644 --- a/package.json +++ b/package.json @@ -105,6 +105,7 @@ "@types/core-js": "^2.5.5", "@types/git-url-parse": "^9.0.1", "@types/react": "^18.0.37", + "@types/react-copy-to-clipboard": "^5.0.7", "@types/react-dom": "^18.0.11", "@types/react-highlight-words": "^0.16.4", "@types/recompose": "^0.30.10", diff --git a/src/components/Breadcrumbs/Breadcrumb.tsx b/src/components/Breadcrumbs/Breadcrumb.tsx index 0a4e8d50..522d714e 100644 --- a/src/components/Breadcrumbs/Breadcrumb.tsx +++ b/src/components/Breadcrumbs/Breadcrumb.tsx @@ -1,9 +1,10 @@ -import React, { FC } from 'react'; +import React, { FC, useState } from 'react'; +import { CopyToClipboard } from 'react-copy-to-clipboard'; import Skeleton from 'react-loading-skeleton'; import Router from 'next/router'; -import { BreadCrumbLink, StyledBreadCrumb } from './StyledBreadCrumb'; +import { BreadCrumbLink, StyledBreadCrumb, StyledCopyWrapper } from './StyledBreadCrumb'; interface BreadcrumbProps { header: string; @@ -17,24 +18,46 @@ interface BreadcrumbProps { asPath: string; loading?: boolean; } +const Breadcrumb: FC = ({ header, title, urlObject, asPath, loading }) => { + const [copied, setCopied] = useState(false); -const Breadcrumb: FC = ({ header, title, urlObject, asPath, loading }) => ( - <> - { - e.preventDefault(); - void Router.push(urlObject, asPath); - }} - > - -
- - {title ?

{title}

: loading && } + return ( + <> + { + e.preventDefault(); + void Router.push(urlObject, asPath); + }} + > + +
+ + {title ?

{title}

: loading && } +
+
+
+ +
+ + Copied + + { + setCopied(true); + setTimeout(function () { + setCopied(false); + }, 750); + }} + > + +
- - - -); +
+ + ); +}; export default Breadcrumb; diff --git a/src/components/Breadcrumbs/StyledBreadCrumb.tsx b/src/components/Breadcrumbs/StyledBreadCrumb.tsx index fbad1654..ff5f3895 100644 --- a/src/components/Breadcrumbs/StyledBreadCrumb.tsx +++ b/src/components/Breadcrumbs/StyledBreadCrumb.tsx @@ -1,4 +1,4 @@ -import { bp, color } from 'lib/variables'; +import { bp, color, fontSize } from 'lib/variables'; import styled from 'styled-components'; export const StyledBreadCrumb = styled.div` @@ -62,3 +62,45 @@ export const StyledBreadcrumbsWrapper = styled.div` margin: 0 calc((100vw / 16) * 1); } `; + +export const StyledCopyWrapper = styled.div` + margin-right: 8px; + + .copy-field { + display: flex; + width: 100%; + overflow: visible; + transform: translateX(-13px); + } + + .copy { + background: url('/static/images/copy.svg') center center no-repeat ${props => props.theme.backgrounds.breadCrumbs}; + background-size: 16px; + bottom: 0; + height: 34px; + position: absolute; + right: 20px; + width: 40px; + top: 10px; + transition: all 0.5s; + + &:hover { + background-color: ${props => props.theme.backgrounds.sidebar}; + cursor: pointer; + } + } + + .copied { + background-color: ${props => props.theme.backgrounds.breadCrumbs}; + ${fontSize(9, 16)}; + border-radius: 3px; + padding: 0 2px; + position: absolute; + right: 20px; + text-transform: uppercase; + top: 10px; + transition: + top 0.5s, + opacity 0.75s ease-in; + } +`; diff --git a/yarn.lock b/yarn.lock index 2b1cb465..572c3454 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4015,6 +4015,13 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== +"@types/react-copy-to-clipboard@^5.0.7": + version "5.0.7" + resolved "https://registry.yarnpkg.com/@types/react-copy-to-clipboard/-/react-copy-to-clipboard-5.0.7.tgz#0cb724d4228f1c2f8f5675671b3971c8801d5f45" + integrity sha512-Gft19D+as4M+9Whq1oglhmK49vqPhcLzk8WfvfLvaYMIPYanyfLy0+CwFucMJfdKoSFyySPmkkWn8/E6voQXjQ== + dependencies: + "@types/react" "*" + "@types/react-dom@^18.0.11": version "18.3.0" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.3.0.tgz#0cbc818755d87066ab6ca74fbedb2547d74a82b0" From 9f0bec82d265574d074a9280021aed16417604b8 Mon Sep 17 00:00:00 2001 From: cgoodwin90 Date: Thu, 20 Feb 2025 16:47:53 +1100 Subject: [PATCH 2/2] Updated cypress tests --- cypress/e2e/general/navigation.cy.ts | 2 +- src/components/Breadcrumbs/Breadcrumb.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cypress/e2e/general/navigation.cy.ts b/cypress/e2e/general/navigation.cy.ts index d2e931b1..69d583a7 100644 --- a/cypress/e2e/general/navigation.cy.ts +++ b/cypress/e2e/general/navigation.cy.ts @@ -46,7 +46,7 @@ describe('Navigation tests', () => { navigation.getLinkElement('account').click(); - const redirect = `${Cypress.env('keycloak')}/realms/lagoon/account/`; + const redirect = `${Cypress.env('keycloak')}/realms/lagoon/account`; cy.origin(redirect, { args: { redirect } }, ({ redirect }) => { cy.location().should(loc => { expect(loc.toString()).to.eq(redirect); diff --git a/src/components/Breadcrumbs/Breadcrumb.tsx b/src/components/Breadcrumbs/Breadcrumb.tsx index 522d714e..9c4fa294 100644 --- a/src/components/Breadcrumbs/Breadcrumb.tsx +++ b/src/components/Breadcrumbs/Breadcrumb.tsx @@ -43,7 +43,7 @@ const Breadcrumb: FC = ({ header, title, urlObject, asPath, loa Copied { setCopied(true);