diff --git a/etc/plugin-config-ui-lib.api.md b/etc/plugin-config-ui-lib.api.md index 00d07c7b..b5370cf6 100644 --- a/etc/plugin-config-ui-lib.api.md +++ b/etc/plugin-config-ui-lib.api.md @@ -381,14 +381,13 @@ export interface FormFieldResetProps { } // @public -export function FormFooter({ isUpdating, isSubmitting, isTestingConnection, testConnectionError, pluginKind, submitPayload, onCancel, onCancelTestConnection, onDelete, onGoToPreviousStep, onTestConnectionSuccess, submitLabel, submitDisabled, showPreviousStepButton, pluginName, teamName, testConnectionId, }: FormFooterProps): JSX_2.Element; +export function FormFooter({ isUpdating, isSubmitting, isTestingConnection, testConnectionError, pluginKind, submitPayload, onCancelTestConnection, onDelete, onGoToPreviousStep, onTestConnectionSuccess, submitLabel, submitDisabled, showPreviousStepButton, pluginName, teamName, testConnectionId, }: FormFooterProps): JSX_2.Element; // @public (undocumented) export interface FormFooterProps { isSubmitting: boolean; isTestingConnection: boolean; isUpdating: boolean; - onCancel: () => void; onCancelTestConnection: () => void; onDelete: () => Promise; onGoToPreviousStep: () => void; @@ -926,7 +925,6 @@ export function useFormActions({ ge apiBaseUrl?: string; }): { submitError: any; - handleCancel: () => void; handleCancelTestConnection: () => void; handleDelete: () => Promise; handleGoToPreviousStep: () => void; diff --git a/package-lock.json b/package-lock.json index cce2c4ee..24690c2a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@cloudquery/plugin-config-ui-lib", - "version": "7.0.0", + "version": "7.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@cloudquery/plugin-config-ui-lib", - "version": "7.0.0", + "version": "7.0.1", "license": "MPL-2.0", "dependencies": { "@babel/runtime": "^7.26.7", diff --git a/package.json b/package.json index 283f8e6c..e6e03786 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@cloudquery/plugin-config-ui-lib", "description": "Plugin configuration UI library for CloudQuery Cloud App", - "version": "7.0.0", + "version": "7.0.1", "private": false, "main": "dist/index.cjs.js", "module": "dist/index.esm.js", diff --git a/src/components/display/codeSnippet/copyToClipboard.tsx b/src/components/display/codeSnippet/copyToClipboard.tsx index bed3faba..25a52da9 100644 --- a/src/components/display/codeSnippet/copyToClipboard.tsx +++ b/src/components/display/codeSnippet/copyToClipboard.tsx @@ -15,7 +15,20 @@ export function CopyToClipboardButton({ sx, text }: Props) { const [wasCopied, setWasCopied] = useState(false); const handleClick = () => { + // Because the code is running in an iframe but elements + // are rendered in the parent window, we need to create a button + // to focus and click it to establish user activation + const button = document.createElement('button'); + button.style.position = 'fixed'; + button.style.opacity = '0'; + button.style.pointerEvents = 'none'; + document.body.append(button); + button.focus(); + button.click(); + navigator.clipboard.writeText(text); + + button.remove(); setWasCopied(true); }; diff --git a/src/components/display/formFooter/index.tsx b/src/components/display/formFooter/index.tsx index 30508acc..d3319e66 100644 --- a/src/components/display/formFooter/index.tsx +++ b/src/components/display/formFooter/index.tsx @@ -22,8 +22,6 @@ export interface FormFooterProps { pluginKind: 'source' | 'destination'; /** Payload to be submitted, containing form values and connection ID */ submitPayload: (FormValues & { connectionId: string }) | undefined; - /** Callback to cancel the current action */ - onCancel: () => void; /** Callback to cancel the connection test */ onCancelTestConnection: () => void; /** Callback to handle delete action */ @@ -60,7 +58,6 @@ export function FormFooter({ testConnectionError, pluginKind, submitPayload, - onCancel, onCancelTestConnection, onDelete, onGoToPreviousStep, @@ -100,7 +97,7 @@ export function FormFooter({ size="medium" variant="contained" > - Delete this {pluginKind === 'source' ? 'integration' : 'destination'} + Delete {pluginKind === 'source' ? 'integration' : 'destination'} )} {showPreviousStepButton && ( @@ -109,26 +106,15 @@ export function FormFooter({ )} - - - - + {submitLabel || 'Test and save'} + {(isTestingConnection || testConnectionError || submitPayload) && ( >(); const [submitValues, setSubmitValues] = useState>(); - const [errors, setErrors] = useState(''); const searchParams = useMemo(() => new URLSearchParams(window.location.search), []); - const handleSubmit = async () => { - formMessageHandler.sendMessage('validate'); - let unsubscribeValidationPassed: (() => void) | undefined; - let unsubscribeValidationFailed: (() => void) | undefined; - - formMessageHandler.sendMessage('is_busy', { - status: true, - }); - - try { - const values = await new Promise((resolve, reject) => { - unsubscribeValidationPassed = formMessageHandler.subscribeToMessageOnce( - 'validation_passed', - ({ values }) => { - resolve(values); - }, - ); - unsubscribeValidationFailed = formMessageHandler.subscribeToMessageOnce( - 'validation_failed', - ({ errors }) => reject(errors), - ); - }).finally(() => { - unsubscribeValidationPassed?.(); - unsubscribeValidationFailed?.(); - }); - - setErrors(''); - setSubmitValues(values as Record); - } catch (error) { - unsubscribeValidationPassed?.(); - unsubscribeValidationFailed?.(); - - setSubmitValues(undefined); - setErrors(JSON.stringify(error, null, 2)); - } - - formMessageHandler.sendMessage('is_busy', { - status: false, - }); - }; - useEffect(() => { formMessageHandler.sendMessage('init', { initialValues: initialValues @@ -244,18 +201,6 @@ export function CloudAppMock({ > {children} - - - {JSON.stringify(submitValues, null, 2) || '-'} -
Errors:
-
{errors || '-'}
); diff --git a/src/e2e-utils/plugin-ui-e2e-helpers.ts b/src/e2e-utils/plugin-ui-e2e-helpers.ts index 0013cead..2b79263e 100644 --- a/src/e2e-utils/plugin-ui-e2e-helpers.ts +++ b/src/e2e-utils/plugin-ui-e2e-helpers.ts @@ -174,7 +174,7 @@ export const deletePlugin = async ({ }), ).toHaveValue(pluginNewName); - await iframeElement.getByRole('button', { name: `Delete this ${kind}` }).click(); + await iframeElement.getByRole('button', { name: `Delete ${kind}` }).click(); await click(page, page.getByText(`Delete ${kind}`)); await expect(page.getByText(pluginNewName)).toHaveCount(0, { timeout: 15_000 }); diff --git a/src/hooks/useFormActions.ts b/src/hooks/useFormActions.ts index acb9eae7..e17bbb02 100644 --- a/src/hooks/useFormActions.ts +++ b/src/hooks/useFormActions.ts @@ -197,17 +197,12 @@ export function useFormActions({ pluginUiMessageHandler.sendMessage('go_to_previous_step'); }; - const handleCancel = () => { - pluginUiMessageHandler.sendMessage('cancel'); - }; - const handleDelete = async () => { pluginUiMessageHandler.sendMessage('delete'); }; return { submitError, - handleCancel, handleCancelTestConnection, handleDelete, handleGoToPreviousStep,