From caab97e667df5d305aa1d2e15c0d31eb5f1a84eb Mon Sep 17 00:00:00 2001 From: Csaba Tuncsik Date: Fri, 26 Jan 2024 06:54:49 +0100 Subject: [PATCH] fix(editor): Show pin button on binary output but disable it with tooltip (#8388) --- packages/editor-ui/src/components/RunData.vue | 66 +++------- .../src/components/RunDataPinButton.vue | 68 ++++++++++ .../__tests__/RunDataPinButton.test.ts | 124 ++++++++++++++++++ .../src/plugins/i18n/locales/en.json | 1 + 4 files changed, 212 insertions(+), 47 deletions(-) create mode 100644 packages/editor-ui/src/components/RunDataPinButton.vue create mode 100644 packages/editor-ui/src/components/__tests__/RunDataPinButton.test.ts diff --git a/packages/editor-ui/src/components/RunData.vue b/packages/editor-ui/src/components/RunData.vue index 212027ff3b..1cd3dec8d6 100644 --- a/packages/editor-ui/src/components/RunData.vue +++ b/packages/editor-ui/src/components/RunData.vue @@ -70,48 +70,24 @@ data-test-id="ndv-edit-pinned-data" @click="enterEditMode({ origin: 'editIconButton' })" /> - - - - - +
await import('@/components/RunDataTable.vue'), @@ -649,6 +626,7 @@ export default defineComponent({ RunDataSchema, RunDataHtml, RunDataSearch, + RunDataPinButton, }, props: { node: { @@ -1727,12 +1705,6 @@ export default defineComponent({ max-width: 240px; } -.pinDataButton { - svg { - transition: transform 0.3s ease; - } -} - .spinner { * { color: var(--color-primary); diff --git a/packages/editor-ui/src/components/RunDataPinButton.vue b/packages/editor-ui/src/components/RunDataPinButton.vue new file mode 100644 index 0000000000..9fd3539515 --- /dev/null +++ b/packages/editor-ui/src/components/RunDataPinButton.vue @@ -0,0 +1,68 @@ + + + + + diff --git a/packages/editor-ui/src/components/__tests__/RunDataPinButton.test.ts b/packages/editor-ui/src/components/__tests__/RunDataPinButton.test.ts new file mode 100644 index 0000000000..1e6b7958c8 --- /dev/null +++ b/packages/editor-ui/src/components/__tests__/RunDataPinButton.test.ts @@ -0,0 +1,124 @@ +import { createTestingPinia } from '@pinia/testing'; +import { cleanup, waitFor } from '@testing-library/vue'; +import userEvent from '@testing-library/user-event'; +import { createComponentRenderer } from '@/__tests__/render'; +import RunDataPinButton from '@/components/RunDataPinButton.vue'; +import { STORES } from '@/constants'; + +const renderComponent = createComponentRenderer(RunDataPinButton, { + global: { + stubs: ['font-awesome-icon'], + plugins: [ + createTestingPinia({ + initialState: { + [STORES.SETTINGS]: { + settings: { + templates: { + enabled: true, + host: 'https://api.n8n.io/api/', + }, + }, + }, + }, + }), + ], + }, + props: { + tooltipContentsVisibility: { + binaryDataTooltipContent: false, + pinDataDiscoveryTooltipContent: false, + }, + dataPinningDocsUrl: '', + pinnedData: { + hasData: false, + }, + disabled: false, + }, +}); + +describe('RunDataPinButton.vue', () => { + beforeEach(cleanup); + + it('shows default tooltip content only on button hover', async () => { + const { getByRole, queryByRole, emitted } = renderComponent(); + + expect(queryByRole('tooltip')).not.toBeInTheDocument(); + + expect(getByRole('button')).toBeEnabled(); + await userEvent.hover(getByRole('button')); + + expect(getByRole('tooltip')).toBeVisible(); + expect(getByRole('tooltip')).toHaveTextContent('More info'); + + await userEvent.click(getByRole('button')); + expect(emitted().togglePinData).toBeDefined(); + }); + + it('shows binary data tooltip content only on disabled button hover', async () => { + const { getByRole, queryByRole, emitted } = renderComponent({ + props: { + tooltipContentsVisibility: { + binaryDataTooltipContent: true, + pinDataDiscoveryTooltipContent: false, + }, + disabled: true, + }, + }); + + expect(queryByRole('tooltip')).not.toBeInTheDocument(); + expect(getByRole('button')).toBeDisabled(); + + await userEvent.hover(getByRole('button')); + + expect(getByRole('tooltip')).toBeVisible(); + expect(getByRole('tooltip')).toHaveTextContent('disabled'); + + await userEvent.click(getByRole('button')); + expect(emitted().togglePinData).not.toBeDefined(); + }); + + it('shows pin data discoverability tooltip immediately (not on hover)', async () => { + const { getByRole } = renderComponent({ + props: { + tooltipContentsVisibility: { + binaryDataTooltipContent: false, + pinDataDiscoveryTooltipContent: true, + }, + }, + }); + + await waitFor(() => { + expect(getByRole('tooltip')).toBeVisible(); + expect(getByRole('tooltip')).toHaveTextContent('instead of waiting'); + }); + expect(getByRole('button')).toBeEnabled(); + + await userEvent.hover(getByRole('button')); + + expect(getByRole('tooltip')).toBeVisible(); + expect(getByRole('tooltip')).toHaveTextContent('instead of waiting'); + }); + + it('shows binary data tooltip content even if discoverability tooltip enabled', async () => { + const { getByRole } = renderComponent({ + props: { + tooltipContentsVisibility: { + binaryDataTooltipContent: true, + pinDataDiscoveryTooltipContent: true, + }, + disabled: true, + }, + }); + + await waitFor(() => { + expect(getByRole('tooltip')).toBeVisible(); + expect(getByRole('tooltip')).toHaveTextContent('disabled'); + }); + expect(getByRole('button')).toBeDisabled(); + + await userEvent.hover(getByRole('button')); + + expect(getByRole('tooltip')).toBeVisible(); + expect(getByRole('tooltip')).toHaveTextContent('disabled'); + }); +}); diff --git a/packages/editor-ui/src/plugins/i18n/locales/en.json b/packages/editor-ui/src/plugins/i18n/locales/en.json index 3db1094d1c..b8bf30503a 100644 --- a/packages/editor-ui/src/plugins/i18n/locales/en.json +++ b/packages/editor-ui/src/plugins/i18n/locales/en.json @@ -820,6 +820,7 @@ "ndv.title.renameNode": "Rename node", "ndv.pinData.pin.title": "Pin data", "ndv.pinData.pin.description": "Node will always output this data instead of executing.", + "ndv.pinData.pin.binary": "Pin Data is disabled as this node's output contains binary data.", "ndv.pinData.pin.link": "More info", "ndv.pinData.pin.multipleRuns.title": "Run #{index} was pinned", "ndv.pinData.pin.multipleRuns.description": "This run will be outputted each time the node is run.",