diff --git a/apps/tup-ui/src/main.global.css b/apps/tup-ui/src/main.global.css index 927aa28ff..920048111 100644 --- a/apps/tup-ui/src/main.global.css +++ b/apps/tup-ui/src/main.global.css @@ -1,3 +1,17 @@ +/* To use new c-nav component not yet in TACC/Core-CMS core-styles.base.css */ +/* TODO: Remove when TACC/Core-CMS loads TACC/Core-Styles v2.13+ */ +/* CAVEAT: Duplicates older, unchanged, global c-nav styles */ +@import url("@tacc/core-styles/dist/components/c-nav.css"); + +/* To use s-affixed-input-wrapper which had been unused outside TACC/Core-CMS */ +/* TODO: Remove when TACC/Core-CMS loads TACC/Core-Styles v2.14+ */ +@import url("@tacc/core-styles/dist/trumps/s-affixed-input-wrapper.css"); + +/* To use new form styles in core-styles.base.css */ +/* TODO: Remove when TACC/Core-CMS loads TACC/Core-Styles v2.15+ */ +@import url("@tacc/core-styles/dist/elements/form.css"); +@import url("@tacc/core-styles/dist/trumps/s-form.css"); + /* To overwrite @tacc/core-styles CEPv2 spacing */ :root { /* TACC/Core-Styles/blob/823b7b9/src/lib/_imports/settings/space.css */ @@ -54,3 +68,10 @@ h3 { table { width: 100%; } + +/* Forms */ +/* To hide icon of a Message that is used as a form error */ +/* FAQ: Used by MfaValidationPanel, MfaSmsPanel */ +.s-form input + [role="status"] > .icon { + display: none; +} diff --git a/apps/tup-ui/src/main.global.for-core-styles.css b/apps/tup-ui/src/main.global.for-core-styles.css index dddb52c6f..7b80b3251 100644 --- a/apps/tup-ui/src/main.global.for-core-styles.css +++ b/apps/tup-ui/src/main.global.for-core-styles.css @@ -41,3 +41,10 @@ hr { margin-right: 0.25ch; text-transform: none; } + +/* TODO: Remove this after: + 0. CEP v2 colors are removed from Core-Styles settings/color--portal */ +:root { + /* FAQ: The `!important` is only necessary for dev (and thus prod) server */ + --global-color-danger--normal: #dc393b !important; +} diff --git a/apps/tup-ui/src/pages/Mfa/Mfa.tsx b/apps/tup-ui/src/pages/Mfa/Mfa.tsx index 5da884f54..b126ab1d5 100644 --- a/apps/tup-ui/src/pages/Mfa/Mfa.tsx +++ b/apps/tup-ui/src/pages/Mfa/Mfa.tsx @@ -6,13 +6,13 @@ import { Outlet } from 'react-router-dom'; const Mfa: React.FC = () => { return ( -
+
{/* Default to a "success" view if user has a verified token */} -
+
); }; diff --git a/libs/core-components/src/index.ts b/libs/core-components/src/index.ts index 599a3d804..10c8cfafe 100644 --- a/libs/core-components/src/index.ts +++ b/libs/core-components/src/index.ts @@ -16,4 +16,5 @@ export { default as InfiniteScrollTable } from './lib/InfiniteScrollTable'; export { default as Sidebar } from './lib/Sidebar'; export { default as HistoryBadge } from './lib/HistoryBadge'; export { default as Collapse } from './lib/Collapse'; +export { default as TextCopyField } from './lib/TextCopyField'; export * from './lib/Form'; diff --git a/libs/core-components/src/lib/Button/Button.tsx b/libs/core-components/src/lib/Button/Button.tsx index 374219e93..41b833057 100644 --- a/libs/core-components/src/lib/Button/Button.tsx +++ b/libs/core-components/src/lib/Button/Button.tsx @@ -41,6 +41,7 @@ type ButtonProps = React.PropsWithChildren<{ className?: string; iconNameBefore?: string; iconNameAfter?: string; + id?: string; dataTestid?: string; disabled?: boolean; onClick?: (e: React.MouseEvent) => void; @@ -54,6 +55,7 @@ const Button: React.FC = ({ className, iconNameBefore, iconNameAfter, + id, type = 'secondary', size = '', dataTestid, @@ -74,6 +76,7 @@ const Button: React.FC = ({ return ( - - ); - const CopyField = ( - - ); - - return ( - <> - {ButtonWrapper ? ( - - - - ) : ( - - )} - - - ); -}; - -TextCopyField.propTypes = { - buttonWrapper: PropTypes.node, - placeholder: PropTypes.string, - value: PropTypes.string, -}; - -TextCopyField.defaultProps = { - buttonWrapper: undefined, - placeholder: '', - value: '', -}; - -export default TextCopyField; diff --git a/libs/core-components/src/lib/TextCopyField/TextCopyField.module.css b/libs/core-components/src/lib/TextCopyField/TextCopyField.module.css index c0ad01b05..87667f65d 100644 --- a/libs/core-components/src/lib/TextCopyField/TextCopyField.module.css +++ b/libs/core-components/src/lib/TextCopyField/TextCopyField.module.css @@ -1,12 +1,8 @@ @import url('@tacc/core-styles/dist/settings/color--portal.css'); -.input { - /* composes: input from '@tacc/core-styles/dist/components/...form.css'; */ -} - .copy-button { - /* So JavaScript can set this (JavaScript also needs the value) */ - --transition-duration: 0; + /* WARNING: Must match JavaScript `transitionDuration` */ + --transition-duration: 0.15; transition: color var(--transition-duration), background-color var(--transition-duration); diff --git a/libs/core-components/src/lib/TextCopyField/TextCopyField.tsx b/libs/core-components/src/lib/TextCopyField/TextCopyField.tsx new file mode 100644 index 000000000..cd4fd9de6 --- /dev/null +++ b/libs/core-components/src/lib/TextCopyField/TextCopyField.tsx @@ -0,0 +1,75 @@ +import React, { useCallback, useState } from 'react'; + +import Button from '../Button'; + +import styles from './TextCopyField.module.css'; + +type TextCopyFieldProps = { + value: string; + placeholder?: string; + className?: string; + id?: string; + buttonClassName?: string; +}; + +const TextCopyField: React.FC = ({ + value, + placeholder, + className, + id, + buttonClassName, +}) => { + /* WARNING: Must match CSS `--transition-duration` */ + const transitionDuration = 0.15; // second(s) + const stateDuration = 1; // second(s) + const stateTimeout = transitionDuration + stateDuration; // second(s) + + const [isCopied, setIsCopied] = useState(false); + + const onCopy = useCallback(() => { + navigator.clipboard.writeText(value); + setIsCopied(true); + + const timeout = setTimeout(() => { + setIsCopied(false); + clearTimeout(timeout); + }, stateTimeout * 1000); + }, [value, setIsCopied, stateTimeout]); + const isEmpty = !value || value.length === 0; + const onChange = (event: React.ChangeEvent) => { + // Swallow keyboard events on the Input control, but + // still allow selecting the text. readOnly property of + // Input is not adequate for this purpose because it + // prevents text selection + event.preventDefault(); + }; + + return ( + <> + + + + ); +}; + +export default TextCopyField; diff --git a/libs/tup-components/src/accounts/ManageAccountMfa.tsx b/libs/tup-components/src/accounts/ManageAccountMfa.tsx index 06977e934..ca75a959c 100644 --- a/libs/tup-components/src/accounts/ManageAccountMfa.tsx +++ b/libs/tup-components/src/accounts/ManageAccountMfa.tsx @@ -73,7 +73,6 @@ const MfaUnpair: React.FC<{ pairing: MfaTokenResponse }> = ({ pairing }) => { )}

-
= ({ pairing }) => { const MfaSectionHeader: React.FC = () => (

MFA Pairing -
); @@ -144,8 +134,7 @@ export const AccountMfa: React.FC = () => { There was an error retrieving your multifactor authentication status. - Your account may be in a non-valid state. if this error persists - please{' '} + Your account may be in a non-valid state. If this error persists,{' '} submit a ticket{' '} with this information and TACC User Services will assist you. diff --git a/libs/tup-components/src/auth/LoginComponent/LoginComponent.module.css b/libs/tup-components/src/auth/LoginComponent/LoginComponent.module.css index fc04abf23..2a28a6916 100644 --- a/libs/tup-components/src/auth/LoginComponent/LoginComponent.module.css +++ b/libs/tup-components/src/auth/LoginComponent/LoginComponent.module.css @@ -1,6 +1,3 @@ -/* So login form is built off CMS styles */ -@import url('@tacc/core-styles/dist/elements/form.cms.css') layer(base); - /* CONTAINER */ .root { @@ -54,10 +51,8 @@ display: none; } .field { - max-width: unset; /* undo forms.cms.css `input...` */ - /* To use larger field inputs, always (not just coarse pointer devices) */ - padding: 12px 12px; /* mimic forms.cms.css `@media (pointer: coarse)` */ + padding: 12px 12px; /* mimic Core Styles forms.css @media (pointer: coarse) */ } diff --git a/libs/tup-components/src/mfa/Mfa.module.css b/libs/tup-components/src/mfa/Mfa.module.css index 55b142564..a91a11fd1 100644 --- a/libs/tup-components/src/mfa/Mfa.module.css +++ b/libs/tup-components/src/mfa/Mfa.module.css @@ -1,93 +1,126 @@ +@import url('@tacc/core-styles/src/lib/_imports/tools/media-queries.css'); + /* Layout styles */ .pairing-container { - display: flex; - flex-wrap: wrap; - padding: var(--global-space--section); - gap: 20px; + display: grid; + padding-inline: var(--global-space--section-left); + padding-bottom: var(--global-space--section-bottom); + gap: var(--global-space--section-left); +} +ol.pairing-container { + margin-bottom: 0; /* overwrite core-styles.base.css */ } -.pairing-container > div { - max-width: 375px; + +.pairing-container > *:not(.pairing-separator) { + width: 365px; /* FAQ: static width, so .mfa-message is centered */ } .pairing-separator { - border-left: 2px solid #D8D8D8 + border-left: var(--global-border-width--normal) solid var(--global-color-primary--light); +} +li.pairing-separator { + list-style-type: none; +} + +/* To add space between "2." and separator */ +.pairing-separator + li { + /* This assumes `list-style-position: outside` (browser default) */ + margin-left: 1.25em; } .mfa-type-selection { display: flex; gap: 20px; - margin-top: 30px; + margin-top: 30px; /* match .mfa-success-container button */ } -.mfa-type-container { - padding-top: var(--global-space--section-top); -} - -.mfa-header { - display: flex; - justify-content: space-between; - border-bottom: 1px solid black; - padding: 10px; +/* TOTP pairing styles */ +.qr-code-box > * { + --border-width: var(--global-border-width--xx-thick); + --qr-code-size: 20rem; + width: var(--qr-code-size); + height: var(--qr-code-size); + outline: var(--border-width) solid #D8D8D8; + margin-block: 20px; + margin-inline: var(--border-width); } -.mfa-header > div:first-child { - font-size: 2rem; +.qr-code-box > div:global(.loading-icon) { + display: inline-flex; /* so space above matches button and img */ } - - -/* TOTP pairing styles */ -.qr-button { - width: 200px; +.qr-code-box > button { + /* To overwrite c-button */ white-space: normal; - text-overflow: none; + text-overflow: initial; } - -.qr-code-box { - display: flex; - justify-content: center; - align-items: center; +/* TODO: Remove when TACC/Core-CMS loads TACC/Core-Styles#204 */ +.qr-code-box > button { + width: var(--qr-code-size) !important; /* overwrite c-button, which is too specific */ } -.qr-code-box > div { - display: flex; - width: 200px; - height: 200px; - border: 7px solid #D8D8D8; - margin-top: 20px; - margin-bottom: 20px; - justify-content: center; +label.qr-code-alt-label { + /* To overwrite core-styles */ + font-weight: normal; + display: inline-block; } -.qr-code-box > img { - width: 100%; - height: 100%; +.s-affixed-input-wrapper { + display: inline-grid; /* to overwrite core-styles */ } -.qr-code-error { - max-width: 200px; + + +/* Wide */ +@media screen and (--medium-and-above) { + .pairing-container { + /* To layout items on one left-aligned row */ + grid-auto-flow: column; + justify-content: start; + + /* To support `position: absolute` child */ + position: relative; + width: max-content; /* to not let wide child change parent width */ + } + .mfa-message { + /* To position message beneath both paring steps */ + position: absolute; + top: 100%; + + /* To constrain width within parent given 100% would exceed parent */ + max-width: calc( + 100% + - var(--global-space--section-left) + - var(--global-space--section-right) + ); + + /* To horizontally center content (not text) */ + left: 0; + right: 0; + margin-left: auto; + margin-right: auto; + width: max-content; + + /* To add space between message and bottom of section when it scrolls */ + padding-bottom: 2rem; + } } + + .mfa-form { padding-top: 10px; padding-bottom: 10px; } - -.submit-button { - padding-top: 20px; -} - -.verify-error-message { +.mfa-form input { + /* To prevent input field from stretching */ + /* FAQ: Input field stretched when long error message */ + /* HELP: Can this be fixed in Core Styles? */ + /* WARNING: This would cause bug: shrink login form field width */ width: fit-content; - height: fit-content; - padding-top: 15px; } /* Success view */ .mfa-success-container { width: fit-content; - height: fit-content; - padding: var(--global-space--section) } - -.mfa-return-button { - margin-top: 50px; - font-size: 1.1rem; +.mfa-success-container button { + margin-top: 30px; /* match .mfa-type-selection */ } diff --git a/libs/tup-components/src/mfa/MfaHeader.tsx b/libs/tup-components/src/mfa/MfaHeader.tsx index 883cc41fb..83acd5e4b 100644 --- a/libs/tup-components/src/mfa/MfaHeader.tsx +++ b/libs/tup-components/src/mfa/MfaHeader.tsx @@ -1,16 +1,24 @@ -import { Link } from 'react-router-dom'; -import styles from './Mfa.module.css'; +import { SectionHeader } from '@tacc/core-components'; import TicketCreateModal from '../tickets/TicketCreateModal'; const MfaHeader: React.FC = () => { + const Actions = ( + + ); + return ( -
-
Multifactor Authentication Pairing
-
- Get Help |{' '} - Exit Pairing Process -
-
+ + Multifactor Authentication Pairing + ); }; diff --git a/libs/tup-components/src/mfa/MfaPairingView.tsx b/libs/tup-components/src/mfa/MfaPairingView.tsx index b8e814767..ddbc52212 100644 --- a/libs/tup-components/src/mfa/MfaPairingView.tsx +++ b/libs/tup-components/src/mfa/MfaPairingView.tsx @@ -6,12 +6,16 @@ import styles from './Mfa.module.css'; const MfaPairingLayout: React.FC<{ method: 'sms' | 'totp' }> = ({ method }) => { return ( -
- {method === 'totp' && } - {method === 'sms' && } -
- -
+
    +
  1. + {method === 'totp' && } + {method === 'sms' && } +
  2. +
  3. +
  4. + +
  5. +
); }; diff --git a/libs/tup-components/src/mfa/MfaQRPanel.tsx b/libs/tup-components/src/mfa/MfaQRPanel.tsx index beba23b79..e286a5c24 100644 --- a/libs/tup-components/src/mfa/MfaQRPanel.tsx +++ b/libs/tup-components/src/mfa/MfaQRPanel.tsx @@ -1,68 +1,76 @@ import React from 'react'; import { useMfaPairTotp } from '@tacc/tup-hooks'; -import { Button, LoadingSpinner, SectionMessage } from '@tacc/core-components'; +import { + Button, + InlineMessage, + LoadingSpinner, + TextCopyField, +} from '@tacc/core-components'; import { TicketCreateModal } from '../tickets'; import styles from './Mfa.module.css'; const MfaQRPanel: React.FC = () => { const { mutate, isLoading, data, isError } = useMfaPairTotp(); + return ( -
-
- 1. Open an approved{' '} - - MFA pairing app - {' '} - and scan the following QR code: -
-
-
+ <> +
+ +
{!data && !isLoading && ( - )} {!data && isLoading && } {data && ( - Google MFA QR Code + Google MFA QR Code )}
- {data && ( -
- If your mobile device does not have a camera capable of scanning QR - codes, the following text code can be used: -
- {data.otpkey.value_b32}  ( - - ) -
- )} {!data && isError && ( - -
- There was an error generating your QR code. If this error persists, - please{' '} - - submit a ticket - {' '} - and TACC User Services will assist you. + + Unable to display QR code. If this error persists,{' '} + submit a ticket. + + )} + {data && data.otpkey && ( +

+ Can't scan QR code?{' '} + +

+
- +

+ )} + {data && !data.otpkey && ( +

+ Can't scan QR code?{' '} + Submit a ticket. +

)} -
+ ); }; diff --git a/libs/tup-components/src/mfa/MfaSmsPanel.tsx b/libs/tup-components/src/mfa/MfaSmsPanel.tsx index b91a9cb56..9c1ad0a91 100644 --- a/libs/tup-components/src/mfa/MfaSmsPanel.tsx +++ b/libs/tup-components/src/mfa/MfaSmsPanel.tsx @@ -1,6 +1,6 @@ import React, { useState } from 'react'; import { useMfaPairSms } from '@tacc/tup-hooks'; -import { Button, SectionMessage } from '@tacc/core-components'; +import { Button, InlineMessage } from '@tacc/core-components'; import styles from './Mfa.module.css'; import { TicketCreateModal } from '../tickets'; @@ -12,39 +12,31 @@ const MfaSmsPanel: React.FC = () => { smsMutation.mutate({ phoneNumber }); }; return ( -
- 1. Enter your phone number: -
onSubmit(e)} className={styles['mfa-form']}> - + onSubmit(e)} + className={`${styles['mfa-form']} s-form`} + > +
+ setPhoneNumber(e.target.value)} /> -
- -
- - {smsMutation.isError && ( - -
- There was an error generating your SMS pairing. If this error - persists, please{' '} + {smsMutation.isError && ( + + Unable to pair via SMS. If this error persists,{' '} submit a ticket - {' '} - and TACC User Services will assist you. -
-
- )} -
+ + . + + )} +
+ + ); }; diff --git a/libs/tup-components/src/mfa/MfaSuccessView.tsx b/libs/tup-components/src/mfa/MfaSuccessView.tsx index a5fc67a8e..b72bedb91 100644 --- a/libs/tup-components/src/mfa/MfaSuccessView.tsx +++ b/libs/tup-components/src/mfa/MfaSuccessView.tsx @@ -10,11 +10,9 @@ const MfaSuccessView: React.FC = () => { Pairing Successful -
- -
+
); }; diff --git a/libs/tup-components/src/mfa/MfaValidationPanel.tsx b/libs/tup-components/src/mfa/MfaValidationPanel.tsx index e8c0b720a..d9c6eea52 100644 --- a/libs/tup-components/src/mfa/MfaValidationPanel.tsx +++ b/libs/tup-components/src/mfa/MfaValidationPanel.tsx @@ -1,6 +1,7 @@ import React, { useState } from 'react'; import { useMfaVerify } from '@tacc/tup-hooks'; -import { Button, SectionMessage } from '@tacc/core-components'; +import { Button, InlineMessage } from '@tacc/core-components'; +import TicketCreateModal from '../tickets/TicketCreateModal'; import styles from './Mfa.module.css'; const MfaValidationPanel: React.FC<{ tokenType: 'totp' | 'sms' }> = ({ @@ -14,41 +15,40 @@ const MfaValidationPanel: React.FC<{ tokenType: 'totp' | 'sms' }> = ({ }; const pairingMessage = { - totp: '2. Enter the token shown in the app to continue the pairing.', - sms: '2. Enter the token sent to your phone number.', + totp: 'Enter the token shown in the app to continue the pairing.', + sms: 'Enter the token sent to your phone number.', }; return ( -
- {pairingMessage[tokenType]} -
onSubmit(e)} className={styles['mfa-form']}> - - setTokenValue(e.target.value)} - > -
- + <> + onSubmit(e)} + className={`${styles['mfa-form']} s-form`} + > +
+ + setTokenValue(e.target.value)} + /> + {error && ( + + Error validating MFA token: "{error.message}" + + )}
+ {tokenType === 'sms' && ( - - If you do not receive a text message within 5 minutes, please contact - the helpdesk by clicking "Get Help" above. - - )} - {error && ( -
- - Error validating MFA token: {error.message} - -
+

+ Didn't receive a message within 5 minutes?{' '} + Get Help +

)} -
+ ); }; diff --git a/package-lock.json b/package-lock.json index 55f8812ae..2f99c232d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,6 @@ "js-cookie": "^3.0.1", "lodash": "^4.17.21", "react": "18.2.0", - "react-copy-to-clipboard": "^5.1.0", "react-dom": "18.2.0", "react-dropzone": "^14.2.3", "react-resize-detector": "^7.1.2", @@ -42,7 +41,7 @@ "@nrwl/vite": "^15.6.3", "@nrwl/web": "15.6.3", "@nrwl/workspace": "15.6.3", - "@tacc/core-styles": "^2.6.2", + "@tacc/core-styles": "^2.16.2", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "13.4.0", "@testing-library/user-event": "^14.4.3", @@ -5704,9 +5703,9 @@ } }, "node_modules/@tacc/core-styles": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/@tacc/core-styles/-/core-styles-2.6.2.tgz", - "integrity": "sha512-0JjPjbcmSvYg7z2zRWIq3Yhj2I0L8fz+6L66AV8HVQUJ/7fDG1vC34mGR0q+l36kFT3KYCTA2+XOyOhxnc/C3w==", + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/@tacc/core-styles/-/core-styles-2.16.2.tgz", + "integrity": "sha512-fRT1Fd6BVgT+ar+9FfE4FWAIRO+cpk4I8PGflTK4/yxbFwAMgFRvy+mH7UcZElGzX29kYYiQI1tQ9aYo5InYsA==", "dev": true, "bin": { "core-styles": "src/cli.js" @@ -5724,7 +5723,6 @@ "postcss": "^8.4.18", "postcss-banner": "^4.0.1", "postcss-cli": "^10.0.0", - "postcss-env-function": "^4.0.6", "postcss-extend": "^1.0.5", "postcss-import": "^15.0.0", "postcss-preset-env": "^7.8.3", @@ -9278,14 +9276,6 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "dev": true }, - "node_modules/copy-to-clipboard": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", - "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", - "dependencies": { - "toggle-selection": "^1.0.6" - } - }, "node_modules/copy-webpack-plugin": { "version": "10.2.4", "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-10.2.4.tgz", @@ -19472,9 +19462,9 @@ } }, "node_modules/postcss-cli/node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", "dev": true, "peer": true, "dependencies": { @@ -19489,15 +19479,15 @@ } }, "node_modules/postcss-cli/node_modules/globby": { - "version": "13.1.3", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.3.tgz", - "integrity": "sha512-8krCNHXvlCgHDpegPzleMq07yMYTO2sXKASmZmquEYWEmCx6J5UTRbp5RwMJkTJGtcQ44YpiUYUiN0b9mzy8Bw==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", "dev": true, "peer": true, "dependencies": { "dir-glob": "^3.0.1", - "fast-glob": "^3.2.11", - "ignore": "^5.2.0", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", "merge2": "^1.4.1", "slash": "^4.0.0" }, @@ -19552,9 +19542,9 @@ } }, "node_modules/postcss-cli/node_modules/slash": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-5.0.0.tgz", - "integrity": "sha512-n6KkmvKS0623igEVj3FF0OZs1gYYJ0o0Hj939yc1fyxl2xt+xYpLnzJB6xBSqOfV9ZFLEWodBBN/heZJahuIJQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", "dev": true, "peer": true, "engines": { @@ -19565,9 +19555,9 @@ } }, "node_modules/postcss-cli/node_modules/yaml": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.2.1.tgz", - "integrity": "sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz", + "integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==", "dev": true, "peer": true, "engines": { @@ -21194,18 +21184,6 @@ "node": ">=0.10.0" } }, - "node_modules/react-copy-to-clipboard": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/react-copy-to-clipboard/-/react-copy-to-clipboard-5.1.0.tgz", - "integrity": "sha512-k61RsNgAayIJNoy9yDsYzDe/yAZAzEbEgcz3DZMhF686LEyukcE1hzurxe85JandPUG+yTfGVFzuEw3xt8WP/A==", - "dependencies": { - "copy-to-clipboard": "^3.3.1", - "prop-types": "^15.8.1" - }, - "peerDependencies": { - "react": "^15.3.0 || 16 || 17 || 18" - } - }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -23824,11 +23802,6 @@ "node": ">=8.0" } }, - "node_modules/toggle-selection": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", - "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" - }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -29588,9 +29561,9 @@ } }, "@tacc/core-styles": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/@tacc/core-styles/-/core-styles-2.6.2.tgz", - "integrity": "sha512-0JjPjbcmSvYg7z2zRWIq3Yhj2I0L8fz+6L66AV8HVQUJ/7fDG1vC34mGR0q+l36kFT3KYCTA2+XOyOhxnc/C3w==", + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/@tacc/core-styles/-/core-styles-2.16.2.tgz", + "integrity": "sha512-fRT1Fd6BVgT+ar+9FfE4FWAIRO+cpk4I8PGflTK4/yxbFwAMgFRvy+mH7UcZElGzX29kYYiQI1tQ9aYo5InYsA==", "dev": true, "requires": {} }, @@ -32357,14 +32330,6 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "dev": true }, - "copy-to-clipboard": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", - "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", - "requires": { - "toggle-selection": "^1.0.6" - } - }, "copy-webpack-plugin": { "version": "10.2.4", "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-10.2.4.tgz", @@ -40012,9 +39977,9 @@ }, "dependencies": { "fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", "dev": true, "peer": true, "requires": { @@ -40026,15 +39991,15 @@ } }, "globby": { - "version": "13.1.3", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.3.tgz", - "integrity": "sha512-8krCNHXvlCgHDpegPzleMq07yMYTO2sXKASmZmquEYWEmCx6J5UTRbp5RwMJkTJGtcQ44YpiUYUiN0b9mzy8Bw==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", "dev": true, "peer": true, "requires": { "dir-glob": "^3.0.1", - "fast-glob": "^3.2.11", - "ignore": "^5.2.0", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", "merge2": "^1.4.1", "slash": "^4.0.0" }, @@ -40060,16 +40025,16 @@ } }, "slash": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-5.0.0.tgz", - "integrity": "sha512-n6KkmvKS0623igEVj3FF0OZs1gYYJ0o0Hj939yc1fyxl2xt+xYpLnzJB6xBSqOfV9ZFLEWodBBN/heZJahuIJQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", "dev": true, "peer": true }, "yaml": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.2.1.tgz", - "integrity": "sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz", + "integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==", "dev": true, "peer": true } @@ -41129,15 +41094,6 @@ "loose-envify": "^1.1.0" } }, - "react-copy-to-clipboard": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/react-copy-to-clipboard/-/react-copy-to-clipboard-5.1.0.tgz", - "integrity": "sha512-k61RsNgAayIJNoy9yDsYzDe/yAZAzEbEgcz3DZMhF686LEyukcE1hzurxe85JandPUG+yTfGVFzuEw3xt8WP/A==", - "requires": { - "copy-to-clipboard": "^3.3.1", - "prop-types": "^15.8.1" - } - }, "react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -43143,11 +43099,6 @@ "is-number": "^7.0.0" } }, - "toggle-selection": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", - "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" - }, "toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", diff --git a/package.json b/package.json index e74ae04c3..3a0c28b3e 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,6 @@ "js-cookie": "^3.0.1", "lodash": "^4.17.21", "react": "18.2.0", - "react-copy-to-clipboard": "^5.1.0", "react-dom": "18.2.0", "react-dropzone": "^14.2.3", "react-resize-detector": "^7.1.2", @@ -42,7 +41,7 @@ "@nrwl/vite": "^15.6.3", "@nrwl/web": "15.6.3", "@nrwl/workspace": "15.6.3", - "@tacc/core-styles": "^2.6.2", + "@tacc/core-styles": "^2.16.2", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "13.4.0", "@testing-library/user-event": "^14.4.3",