From 175f110f866c78a3192c869c6d0cde88a688163c Mon Sep 17 00:00:00 2001 From: RachelElysia <71795832+RachelElysia@users.noreply.github.com> Date: Tue, 13 May 2025 10:24:32 -0400 Subject: [PATCH] Fleet UI: Created consistent UI for the copy button of an input field (#29056) --- changes/28652-copy-button-consistency | 1 + .../AndroidPanel/AndroidPanel.tsx | 1 - .../IosIpadosPanel/IosIpadosPanel.tsx | 1 - .../PlatformWrapper/PlatformWrapper.tsx | 6 ---- .../forms/fields/InputField/InputField.jsx | 36 +++---------------- .../fields/InputField/InputField.stories.jsx | 9 ++--- .../fields/InputField/InputField.stories.tsx | 1 - .../fields/InputField/InputField.tests.tsx | 2 +- .../forms/fields/InputField/_styles.scss | 18 +--------- .../InputFieldHiddenContent.tsx | 1 - .../cards/Calendars/Calendars.tsx | 1 - .../AutoEnrollMdmModal/AutoEnrollMdmModal.tsx | 2 -- 12 files changed, 10 insertions(+), 69 deletions(-) create mode 100644 changes/28652-copy-button-consistency diff --git a/changes/28652-copy-button-consistency b/changes/28652-copy-button-consistency new file mode 100644 index 0000000000..9b898956eb --- /dev/null +++ b/changes/28652-copy-button-consistency @@ -0,0 +1 @@ +Fleet UI: Created consistent UI for the copy button of an input field \ No newline at end of file diff --git a/frontend/components/AddHostsModal/PlatformWrapper/AndroidPanel/AndroidPanel.tsx b/frontend/components/AddHostsModal/PlatformWrapper/AndroidPanel/AndroidPanel.tsx index ec883b3637..d4c8493648 100644 --- a/frontend/components/AddHostsModal/PlatformWrapper/AndroidPanel/AndroidPanel.tsx +++ b/frontend/components/AddHostsModal/PlatformWrapper/AndroidPanel/AndroidPanel.tsx @@ -42,7 +42,6 @@ const AndroidPanel = ({ enrollSecret }: IAndroidPanelProps) => { { @@ -324,7 +323,6 @@ const PlatformWrapper = ({ inputWrapperClass={`${baseClass}__installer-input ${baseClass}__chromeos-url`} name="Installation URL" enableCopy - copyButtonPosition="inside" label="Installation URL" value={CHROME_OS_INFO.installationUrl} /> @@ -333,7 +331,6 @@ const PlatformWrapper = ({ inputWrapperClass={`${baseClass}__installer-input ${baseClass}__chromeos-policy-for-extension`} name="Policy for extension" enableCopy - copyButtonPosition="inside" label="Policy for extension" type="textarea" value={CHROME_OS_INFO.policyForExtension} @@ -360,7 +357,6 @@ const PlatformWrapper = ({ inputWrapperClass={`${baseClass}__installer-input ${baseClass}__installer-input-${packageType}`} name="installer" enableCopy - copyButtonPosition="inside" label={renderLabel(packageType)} type="textarea" value={renderInstallerString(packageType)} @@ -455,7 +451,6 @@ const PlatformWrapper = ({ inputWrapperClass={`${baseClass}__run-osquery-input`} name="run-osquery" enableCopy - copyButtonPosition="inside" label={renderLabel("plain-osquery")} type="text" value="osqueryd --flagfile=flagfile.txt --verbose" @@ -499,7 +494,6 @@ const PlatformWrapper = ({ inputWrapperClass={`${baseClass}__installer-input ${baseClass}__installer-input-${packageType}`} name="installer" enableCopy - copyButtonPosition="inside" label={renderLabel(packageType)} type="textarea" value={renderInstallerString(packageType)} diff --git a/frontend/components/forms/fields/InputField/InputField.jsx b/frontend/components/forms/fields/InputField/InputField.jsx index 4cb76b1b2e..f9f6da8157 100644 --- a/frontend/components/forms/fields/InputField/InputField.jsx +++ b/frontend/components/forms/fields/InputField/InputField.jsx @@ -45,7 +45,6 @@ class InputField extends Component { /** Use in conjunction with type "password" and enableCopy to see eye icon to view */ enableShowSecret: PropTypes.bool, enableCopy: PropTypes.bool, - copyButtonPosition: PropTypes.oneOf(["inside", "outside"]), ignore1password: PropTypes.bool, }; @@ -66,7 +65,6 @@ class InputField extends Component { helpText: "", enableCopy: false, enableShowSecret: false, - copyButtonPosition: "outside", ignore1password: false, }; @@ -124,7 +122,7 @@ class InputField extends Component { }; renderCopyButton = () => { - const { value, copyButtonPosition } = this.props; + const { value } = this.props; const copyValue = (e) => { e.preventDefault(); @@ -136,28 +134,11 @@ class InputField extends Component { }); }; - const copyButtonValue = - copyButtonPosition === "outside" ? ( - <> - - Copy - - ) : ( - - ); - - const wrapperClasses = classnames( - `${baseClass}__copy-wrapper`, - copyButtonPosition === "outside" - ? `${baseClass}__copy-wrapper-outside` - : `${baseClass}__copy-wrapper-inside` - ); + const copyButtonValue = ; + const wrapperClasses = classnames(`${baseClass}__copy-wrapper`); const copiedConfirmationClasses = classnames( - `${baseClass}__copied-confirmation`, - copyButtonPosition === "outside" - ? `${baseClass}__copied-confirmation-outside` - : `${baseClass}__copied-confirmation-inside` + `${baseClass}__copied-confirmation` ); return ( @@ -165,11 +146,7 @@ class InputField extends Component { {this.state.copied && ( Copied! )} - {this.props.enableShowSecret && this.renderShowSecretButton()} @@ -195,7 +172,6 @@ class InputField extends Component { ignore1password, enableCopy, enableShowSecret, - copyButtonPosition, } = this.props; const { onInputChange } = this; @@ -228,8 +204,6 @@ class InputField extends Component { const inputContainerClasses = classnames(`${baseClass}__input-container`, { "copy-enabled": enableCopy, - "copy-outside": enableCopy && copyButtonPosition === "outside", - "copy-inside": enableCopy && copyButtonPosition === "inside", }); if (type === "textarea") { diff --git a/frontend/components/forms/fields/InputField/InputField.stories.jsx b/frontend/components/forms/fields/InputField/InputField.stories.jsx index 7c614a7a82..95a6264a80 100644 --- a/frontend/components/forms/fields/InputField/InputField.stories.jsx +++ b/frontend/components/forms/fields/InputField/InputField.stories.jsx @@ -36,10 +36,6 @@ export default { enableCopy: { control: "boolean", }, - copyButtonPosition: { - control: "radio", - options: ["inside", "outside"], - }, enableShowSecret: { control: "boolean", }, @@ -110,10 +106,9 @@ WithCopyEnabled.args = { value: "This text can be copied", }; -export const WithCopyEnabledInsideInput = Template.bind({}); -WithCopyEnabledInsideInput.args = { +export const WithCopyEnabledInput = Template.bind({}); +WithCopyEnabledInput.args = { ...WithCopyEnabled.args, - copyButtonPosition: "inside", }; export const WithTooltip = Template.bind({}); diff --git a/frontend/components/forms/fields/InputField/InputField.stories.tsx b/frontend/components/forms/fields/InputField/InputField.stories.tsx index 746bae141a..d1f15b74ad 100644 --- a/frontend/components/forms/fields/InputField/InputField.stories.tsx +++ b/frontend/components/forms/fields/InputField/InputField.stories.tsx @@ -113,7 +113,6 @@ export const WithCopyButton: Story = { label: "Input with Copy Button", value: "Click to copy this text", enableCopy: true, - copyButtonPosition: "outside", }, }; diff --git a/frontend/components/forms/fields/InputField/InputField.tests.tsx b/frontend/components/forms/fields/InputField/InputField.tests.tsx index 1aa82607e3..38699a2de0 100644 --- a/frontend/components/forms/fields/InputField/InputField.tests.tsx +++ b/frontend/components/forms/fields/InputField/InputField.tests.tsx @@ -107,7 +107,7 @@ describe("InputField Component", () => { /> ); - expect(screen.getByRole("button", { name: /copy/i })).toBeInTheDocument(); + expect(screen.getByTestId("copy-icon")).toBeInTheDocument(); }); test("calls onBlur when input loses focus", async () => { diff --git a/frontend/components/forms/fields/InputField/_styles.scss b/frontend/components/forms/fields/InputField/_styles.scss index 6b73ec9b4e..092e355b95 100644 --- a/frontend/components/forms/fields/InputField/_styles.scss +++ b/frontend/components/forms/fields/InputField/_styles.scss @@ -101,14 +101,6 @@ display: flex; align-items: center; position: relative; - } - - &__copy-wrapper-outside { - position: relative; - gap: $pad-medium; - } - - &__copy-wrapper-inside { position: absolute; top: 0; right: 0; @@ -117,15 +109,7 @@ } &__input-container.copy-enabled { - &.copy-outside { - display: flex; - align-items: center; - gap: $pad-small; - } - - &.copy-inside { - position: relative; - } + position: relative; } &__copied-confirmation { diff --git a/frontend/components/forms/fields/InputFieldHiddenContent/InputFieldHiddenContent.tsx b/frontend/components/forms/fields/InputFieldHiddenContent/InputFieldHiddenContent.tsx index 8b672bce5d..4317da79fb 100644 --- a/frontend/components/forms/fields/InputFieldHiddenContent/InputFieldHiddenContent.tsx +++ b/frontend/components/forms/fields/InputFieldHiddenContent/InputFieldHiddenContent.tsx @@ -30,7 +30,6 @@ const InputFieldHiddenContent = ({ name={name} enableShowSecret enableCopy - copyButtonPosition="inside" type={"password"} value={value} helpText={helpText} diff --git a/frontend/pages/admin/IntegrationsPage/cards/Calendars/Calendars.tsx b/frontend/pages/admin/IntegrationsPage/cards/Calendars/Calendars.tsx index 523af3f123..7b91200b14 100644 --- a/frontend/pages/admin/IntegrationsPage/cards/Calendars/Calendars.tsx +++ b/frontend/pages/admin/IntegrationsPage/cards/Calendars/Calendars.tsx @@ -358,7 +358,6 @@ const Calendars = (): JSX.Element => { inputWrapperClass={`${baseClass}__oauth-scopes`} name="oauth-scopes" enableCopy - copyButtonPosition="inside" type="textarea" value={OAUTH_SCOPES} /> diff --git a/frontend/pages/hosts/details/DeviceUserPage/AutoEnrollMdmModal/AutoEnrollMdmModal.tsx b/frontend/pages/hosts/details/DeviceUserPage/AutoEnrollMdmModal/AutoEnrollMdmModal.tsx index 46807f15df..8c9294eab1 100644 --- a/frontend/pages/hosts/details/DeviceUserPage/AutoEnrollMdmModal/AutoEnrollMdmModal.tsx +++ b/frontend/pages/hosts/details/DeviceUserPage/AutoEnrollMdmModal/AutoEnrollMdmModal.tsx @@ -49,7 +49,6 @@ const AutoEnrollMdmModal = ({