diff --git a/cypress/e2e/14-mapping.cy.ts b/cypress/e2e/14-mapping.cy.ts index bf0d1d05dcdc3..9dc878402fc96 100644 --- a/cypress/e2e/14-mapping.cy.ts +++ b/cypress/e2e/14-mapping.cy.ts @@ -253,7 +253,6 @@ describe('Data mapping', () => { workflowPage.actions.openNode('Set'); ndv.actions.typeIntoParameterInput('value', 'delete me'); - ndv.actions.dismissMappingTooltip(); ndv.actions.typeIntoParameterInput('name', 'test'); diff --git a/cypress/e2e/16-form-trigger-node.cy.ts b/cypress/e2e/16-form-trigger-node.cy.ts index 8226df6b33a8d..3c6dde5c37d07 100644 --- a/cypress/e2e/16-form-trigger-node.cy.ts +++ b/cypress/e2e/16-form-trigger-node.cy.ts @@ -42,7 +42,8 @@ describe('n8n Form Trigger', () => { ':nth-child(3) > .border-top-dashed > .parameter-input-list-wrapper > :nth-child(1) > .parameter-item', ) .find('input[placeholder*="e.g. What is your name?"]') - .type('Test Field 3'); + .type('Test Field 3') + .blur(); cy.get( ':nth-child(3) > .border-top-dashed > .parameter-input-list-wrapper > :nth-child(2) > .parameter-item', ).click(); @@ -53,7 +54,8 @@ describe('n8n Form Trigger', () => { ':nth-child(4) > .border-top-dashed > .parameter-input-list-wrapper > :nth-child(1) > .parameter-item', ) .find('input[placeholder*="e.g. What is your name?"]') - .type('Test Field 4'); + .type('Test Field 4') + .blur(); cy.get( ':nth-child(4) > .border-top-dashed > .parameter-input-list-wrapper > :nth-child(2) > .parameter-item', ).click(); @@ -65,12 +67,14 @@ describe('n8n Form Trigger', () => { ':nth-child(4) > :nth-child(1) > :nth-child(2) > :nth-child(3) > .multi-parameter > .fixed-collection-parameter > .fixed-collection-parameter-property > :nth-child(1) > :nth-child(1)', ) .find('input') - .type('Option 1'); + .type('Option 1') + .blur(); cy.get( ':nth-child(4) > :nth-child(1) > :nth-child(2) > :nth-child(3) > .multi-parameter > .fixed-collection-parameter > .fixed-collection-parameter-property > :nth-child(1) > :nth-child(2)', ) .find('input') - .type('Option 2'); + .type('Option 2') + .blur(); //add optional submitted message cy.get('.param-options').click(); diff --git a/cypress/e2e/16-webhook-node.cy.ts b/cypress/e2e/16-webhook-node.cy.ts index d753a143755f8..8abb17284dd5c 100644 --- a/cypress/e2e/16-webhook-node.cy.ts +++ b/cypress/e2e/16-webhook-node.cy.ts @@ -182,7 +182,7 @@ describe('Webhook Trigger node', async () => { workflowPage.actions.addNodeToCanvas(EDIT_FIELDS_SET_NODE_NAME); workflowPage.actions.openNode(EDIT_FIELDS_SET_NODE_NAME); ndv.getters.assignmentCollectionAdd('assignments').click(); - ndv.getters.assignmentName('assignments').type('data'); + ndv.getters.assignmentName('assignments').type('data').find('input').blur(); ndv.getters.assignmentType('assignments').click(); ndv.getters.assignmentValue('assignments').paste(cowBase64); @@ -313,7 +313,7 @@ const addEditFields = () => { workflowPage.actions.addNodeToCanvas(EDIT_FIELDS_SET_NODE_NAME); workflowPage.actions.openNode(EDIT_FIELDS_SET_NODE_NAME); ndv.getters.assignmentCollectionAdd('assignments').click(); - ndv.getters.assignmentName('assignments').type('MyValue'); + ndv.getters.assignmentName('assignments').type('MyValue').find('input').blur(); ndv.getters.assignmentType('assignments').click(); getVisibleSelect().find('li').contains('Number').click(); ndv.getters.assignmentValue('assignments').type('1234'); diff --git a/cypress/e2e/24-ndv-paired-item.cy.ts b/cypress/e2e/24-ndv-paired-item.cy.ts index 58fa0fdb63228..382be75bf3d59 100644 --- a/cypress/e2e/24-ndv-paired-item.cy.ts +++ b/cypress/e2e/24-ndv-paired-item.cy.ts @@ -186,6 +186,7 @@ describe('NDV', () => { ndv.getters.inputTableRow(1).invoke('attr', 'data-test-id').should('equal', 'hovering-item'); ndv.getters.inputTableRow(1).realHover(); + cy.wait(100); ndv.getters.outputHoveringItem().should('not.exist'); ndv.getters.parameterExpressionPreview('value').should('include.text', '1111'); @@ -200,6 +201,7 @@ describe('NDV', () => { ndv.actions.selectInputNode('Code'); ndv.getters.inputTableRow(1).realHover(); + cy.wait(100); ndv.getters.inputTableRow(1).should('have.text', '6666'); ndv.getters.inputTableRow(1).invoke('attr', 'data-test-id').should('equal', 'hovering-item'); diff --git a/cypress/pages/ndv.ts b/cypress/pages/ndv.ts index 71e756ec11d67..4eeb27094fc99 100644 --- a/cypress/pages/ndv.ts +++ b/cypress/pages/ndv.ts @@ -167,10 +167,6 @@ export class NDV extends BasePage { selectOptionInParameterDropdown: (parameterName: string, content: string) => { getVisibleSelect().find('.option-headline').contains(content).click(); }, - dismissMappingTooltip: () => { - cy.getByTestId('dismiss-mapping-tooltip').click(); - cy.getByTestId('dismiss-mapping-tooltip').should('not.be.visible'); - }, rename: (newName: string) => { this.getters.nodeNameContainer().click(); this.getters.nodeRenameInput().should('be.visible').type('{selectall}').type(newName); @@ -244,7 +240,7 @@ export class NDV extends BasePage { getVisiblePopper().find('li').last().click(); }, addFilterCondition: (paramName: string) => { - this.getters.filterConditionAdd(paramName).click(); + this.getters.filterConditionAdd(paramName).click({ force: true }); }, removeFilterCondition: (paramName: string, index: number) => { this.getters.filterConditionRemove(paramName, index).click(); diff --git a/packages/design-system/src/css/_tokens.dark.scss b/packages/design-system/src/css/_tokens.dark.scss index 53104dd036479..18cc3eac931ac 100644 --- a/packages/design-system/src/css/_tokens.dark.scss +++ b/packages/design-system/src/css/_tokens.dark.scss @@ -97,7 +97,7 @@ --color-json-brackets: var(--prim-gray-670); --color-json-brackets-hover: var(--prim-color-alt-e); --color-json-line: var(--prim-gray-200); - --color-json-highlight: var(--prim-gray-70); + --color-json-highlight: var(--color-background-base); --color-code-background: var(--prim-gray-800); --color-code-background-readonly: var(--prim-gray-740); --color-code-lineHighlight: var(--prim-gray-740); diff --git a/packages/editor-ui/public/static/json-mapping-gif.gif b/packages/editor-ui/public/static/json-mapping-gif.gif deleted file mode 100644 index 9d42a88bdc176..0000000000000 Binary files a/packages/editor-ui/public/static/json-mapping-gif.gif and /dev/null differ diff --git a/packages/editor-ui/public/static/schema-mapping-gif.gif b/packages/editor-ui/public/static/schema-mapping-gif.gif deleted file mode 100644 index 6d3d79fd9e45a..0000000000000 Binary files a/packages/editor-ui/public/static/schema-mapping-gif.gif and /dev/null differ diff --git a/packages/editor-ui/src/Interface.ts b/packages/editor-ui/src/Interface.ts index 545a7bd202b64..21e54474e05f8 100644 --- a/packages/editor-ui/src/Interface.ts +++ b/packages/editor-ui/src/Interface.ts @@ -1245,6 +1245,7 @@ export interface NDVState { activeTarget: { id: string; stickyPosition: null | XYPosition } | null; }; isMappingOnboarded: boolean; + isAutocompleteOnboarded: boolean; } export interface NotificationOptions extends Partial { diff --git a/packages/editor-ui/src/components/AssignmentCollection/Assignment.vue b/packages/editor-ui/src/components/AssignmentCollection/Assignment.vue index 9684c2c7275cf..c1ee16976b52e 100644 --- a/packages/editor-ui/src/components/AssignmentCollection/Assignment.vue +++ b/packages/editor-ui/src/components/AssignmentCollection/Assignment.vue @@ -58,7 +58,7 @@ const assignmentTypeToNodeProperty = ( const nameParameter = computed(() => ({ name: 'name', - displayName: '', + displayName: 'Name', default: '', requiresDataPath: 'single', placeholder: 'name', @@ -68,7 +68,7 @@ const nameParameter = computed(() => ({ const valueParameter = computed(() => { return { name: 'value', - displayName: '', + displayName: 'Value', default: '', placeholder: 'value', ...assignmentTypeToNodeProperty(assignment.value.type ?? 'string'), diff --git a/packages/editor-ui/src/components/ExpressionParameterInput.vue b/packages/editor-ui/src/components/ExpressionParameterInput.vue index 754f35ed71651..a61ff037c11b3 100644 --- a/packages/editor-ui/src/components/ExpressionParameterInput.vue +++ b/packages/editor-ui/src/components/ExpressionParameterInput.vue @@ -22,6 +22,7 @@ :rows="rows" :additional-data="additionalExpressionData" :path="path" + :event-bus="eventBus" @focus="onFocus" @blur="onBlur" @change="onChange" @@ -64,6 +65,7 @@ import type { Segment } from '@/types/expressions'; import type { TargetItem } from '@/Interface'; import type { IDataObject } from 'n8n-workflow'; import { useDebounce } from '@/composables/useDebounce'; +import { type EventBus, createEventBus } from 'n8n-design-system/utils'; type InlineExpressionEditorInputRef = InstanceType; @@ -97,6 +99,10 @@ export default defineComponent({ type: Object as PropType, default: () => ({}), }, + eventBus: { + type: Object as PropType, + default: () => createEventBus(), + }, }, setup() { const { callDebounced } = useDebounce(); diff --git a/packages/editor-ui/src/components/InlineExpressionEditor/InlineExpressionEditorInput.vue b/packages/editor-ui/src/components/InlineExpressionEditor/InlineExpressionEditorInput.vue index 70ad317ff9b9c..7f11ae73007ad 100644 --- a/packages/editor-ui/src/components/InlineExpressionEditor/InlineExpressionEditorInput.vue +++ b/packages/editor-ui/src/components/InlineExpressionEditor/InlineExpressionEditorInput.vue @@ -3,27 +3,30 @@ diff --git a/packages/editor-ui/src/components/InlineExpressionEditor/InlineExpressionEditorOutput.vue b/packages/editor-ui/src/components/InlineExpressionEditor/InlineExpressionEditorOutput.vue index 1e2a304625bd4..6fc0a63e01a2b 100644 --- a/packages/editor-ui/src/components/InlineExpressionEditor/InlineExpressionEditorOutput.vue +++ b/packages/editor-ui/src/components/InlineExpressionEditor/InlineExpressionEditorOutput.vue @@ -7,130 +7,111 @@
- - {{ i18n.baseText('parameterInput.anythingInside') }} - -
- - {{ i18n.baseText('parameterInput.isJavaScript') }} - - {{ ' ' }} - - {{ i18n.baseText('parameterInput.learnMore') }} - +
- @@ -157,11 +138,14 @@ export default defineComponent({ } .header, - .body, - .footer { + .body { padding: var(--spacing-3xs); } + .footer { + border-top: var(--border-base); + } + .header { color: var(--color-text-dark); font-weight: var(--font-weight-bold); @@ -178,28 +162,5 @@ export default defineComponent({ padding-top: var(--spacing-2xs); } } - - .footer { - border-top: var(--border-base); - padding: var(--spacing-4xs); - padding-left: var(--spacing-2xs); - padding-top: 0; - line-height: var(--font-line-height-regular); - color: var(--color-text-base); - - .expression-syntax-example { - display: inline-block; - font-size: var(--font-size-2xs); - height: var(--font-size-m); - background-color: var(--color-expression-syntax-example); - margin-left: var(--spacing-5xs); - margin-right: var(--spacing-5xs); - } - - .learn-more { - line-height: 1; - white-space: nowrap; - } - } } diff --git a/packages/editor-ui/src/components/InlineExpressionEditor/InlineExpressionTip.vue b/packages/editor-ui/src/components/InlineExpressionEditor/InlineExpressionTip.vue new file mode 100644 index 0000000000000..ed28105dd0d31 --- /dev/null +++ b/packages/editor-ui/src/components/InlineExpressionEditor/InlineExpressionTip.vue @@ -0,0 +1,127 @@ + + + + + diff --git a/packages/editor-ui/src/components/ParameterInput.vue b/packages/editor-ui/src/components/ParameterInput.vue index 90d7f5d8fea57..c977df6626e50 100644 --- a/packages/editor-ui/src/components/ParameterInput.vue +++ b/packages/editor-ui/src/components/ParameterInput.vue @@ -51,6 +51,7 @@ :path="path" :additional-expression-data="additionalExpressionData" :class="{ 'ph-no-capture': shouldRedactValue }" + :event-bus="eventBus" @update:model-value="expressionUpdated" @modalOpenerClick="openExpressionEditorModal" @focus="setFocus" diff --git a/packages/editor-ui/src/components/ParameterInputFull.vue b/packages/editor-ui/src/components/ParameterInputFull.vue index 370d130eee87f..2d573ffe0b3f1 100644 --- a/packages/editor-ui/src/components/ParameterInputFull.vue +++ b/packages/editor-ui/src/components/ParameterInputFull.vue @@ -29,46 +29,34 @@ @drop="onDrop" > +
+ +
.wrapper { position: relative; @@ -388,6 +352,20 @@ export default defineComponent({ } } } + +.tip { + position: absolute; + z-index: 2; + top: 100%; + background: var(--color-code-background); + border: var(--border-base); + border-top: none; + width: 100%; + box-shadow: 0 2px 6px 0 rgba(#441c17, 0.1); + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; +} + .options { position: absolute; bottom: -22px; diff --git a/packages/editor-ui/src/components/RunDataJson.vue b/packages/editor-ui/src/components/RunDataJson.vue index c81a7a4183e8c..0c978cb027126 100644 --- a/packages/editor-ui/src/components/RunDataJson.vue +++ b/packages/editor-ui/src/components/RunDataJson.vue @@ -1,5 +1,5 @@