Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(editor): Add item selector to expression output #9281

Merged
merged 13 commits into from
May 9, 2024
2 changes: 1 addition & 1 deletion cypress/e2e/26-resource-locator.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ describe('Resource Locator', () => {

ndv.actions.setInvalidExpression({ fieldName: 'fieldId' });

ndv.getters.inputDataContainer().click(); // remove focus from input, hide expression preview
ndv.getters.inputPanel().click(); // remove focus from input, hide expression preview

ndv.getters.resourceLocatorInput('rlc').click();

Expand Down
29 changes: 28 additions & 1 deletion cypress/e2e/5-ndv.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ describe('NDV', () => {

ndv.actions.setInvalidExpression({ fieldName: 'fieldId', delay: 200 });

ndv.getters.inputDataContainer().click(); // remove focus from input, hide expression preview
ndv.getters.inputPanel().click(); // remove focus from input, hide expression preview

ndv.getters.parameterInput('remoteOptions').click();

Expand Down Expand Up @@ -712,4 +712,31 @@ describe('NDV', () => {
workflowPage.getters.successToast().should('exist');
});
});

it('should allow selecting item for expressions', () => {
workflowPage.actions.visit();

cy.createFixtureWorkflow('Test_workflow_3.json', `My test workflow`);
workflowPage.actions.openNode('Set');

ndv.actions.typeIntoParameterInput('value', '='); // switch to expressions
ndv.actions.typeIntoParameterInput('value', '{{', {
parseSpecialCharSequences: false,
});
ndv.actions.typeIntoParameterInput('value', '$json.input[0].count');
ndv.getters.inlineExpressionEditorOutput().should('have.text', '0');

ndv.actions.expressionSelectNextItem();
ndv.getters.inlineExpressionEditorOutput().should('have.text', '1');
ndv.getters.inlineExpressionEditorItemInput().should('have.value', '1');
ndv.getters.inlineExpressionEditorItemNextButton().should('be.disabled');

ndv.actions.expressionSelectPrevItem();
ndv.getters.inlineExpressionEditorOutput().should('have.text', '0');
ndv.getters.inlineExpressionEditorItemInput().should('have.value', '0');
ndv.getters.inlineExpressionEditorItemPrevButton().should('be.disabled');

ndv.actions.expressionSelectItem(1);
ndv.getters.inlineExpressionEditorOutput().should('have.text', '1');
});
});
15 changes: 15 additions & 0 deletions cypress/pages/ndv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ export class NDV extends BasePage {
this.getters.inputTableRow(row).find('td').eq(col),
inlineExpressionEditorInput: () => cy.getByTestId('inline-expression-editor-input'),
inlineExpressionEditorOutput: () => cy.getByTestId('inline-expression-editor-output'),
inlineExpressionEditorItemInput: () =>
cy.getByTestId('inline-expression-editor-item-input').find('input'),
inlineExpressionEditorItemPrevButton: () =>
cy.getByTestId('inline-expression-editor-item-prev'),
inlineExpressionEditorItemNextButton: () =>
cy.getByTestId('inline-expression-editor-item-next'),
nodeParameters: () => cy.getByTestId('node-parameters'),
parameterInput: (parameterName: string) => cy.getByTestId(`parameter-input-${parameterName}`),
parameterInputIssues: (parameterName: string) =>
Expand Down Expand Up @@ -290,6 +296,15 @@ export class NDV extends BasePage {
.click({ force: true });
this.getters.parameterInput('operation').find('input').should('have.value', operation);
},
expressionSelectItem: (index: number) => {
this.getters.inlineExpressionEditorItemInput().type(`{selectall}${index}`);
},
expressionSelectNextItem: () => {
this.getters.inlineExpressionEditorItemNextButton().click();
},
expressionSelectPrevItem: () => {
this.getters.inlineExpressionEditorItemPrevButton().click();
},
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,24 @@ Sizes.args = {
placeholder: 'placeholder...',
controls: false,
};

const ControlsTemplate: StoryFn = (args, { argTypes }) => ({
setup: () => ({ args }),
props: Object.keys(argTypes),
components: {
N8nInputNumber,
},
template:
'<div> <n8n-input-number style="margin-bottom:10px" v-bind="args" v-model="val" @update:modelValue="onUpdateModelValue" /> <n8n-input-number style="margin-bottom:10px" v-bind="args" size="medium" v-model="val" @update:modelValue="onUpdateModelValue" /> <n8n-input-number style="margin-bottom:10px" v-bind="args" size="small" v-model="val" @update:modelValue="onUpdateModelValue" /> <n8n-input-number style="margin-bottom:10px" v-bind="args" v-model="val" size="mini" @update:modelValue="onUpdateModelValue" /> <n8n-input-number controls-position="right" style="margin-bottom:10px" v-bind="args" v-model="val" @update:modelValue="onUpdateModelValue" /> <n8n-input-number controls-position="right" style="margin-bottom:10px" v-bind="args" size="medium" v-model="val" @update:modelValue="onUpdateModelValue" /> <n8n-input-number controls-position="right" style="margin-bottom:10px" v-bind="args" size="small" v-model="val" @update:modelValue="onUpdateModelValue" /> <n8n-input-number controls-position="right" style="margin-bottom:10px" v-bind="args" v-model="val" size="mini" @update:modelValue="onUpdateModelValue" /> </div>',
methods,
data() {
return {
val: '',
};
},
});

export const Controls = ControlsTemplate.bind({});
Controls.args = {
placeholder: 'placeholder...',
};
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
<script lang="ts">
<script setup lang="ts">
import type { InputSize } from '@/types';
import { ElInputNumber } from 'element-plus';
import { defineComponent } from 'vue';

export default defineComponent({
name: 'N8nInputNumber',
components: {
ElInputNumber,
},
props: {
...ElInputNumber.props,
},
});
type InputNumberProps = {
size?: InputSize;
min?: number;
max?: number;
step?: number;
precision?: number;
};

defineProps<InputNumberProps>();
</script>

<template>
Expand Down
4 changes: 4 additions & 0 deletions packages/design-system/src/components/N8nText/Text.vue
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ const classes = computed(() => {
color: var(--color-primary);
}

.secondary {
color: var(--color-secondary);
}

.text-dark {
color: var(--color-text-dark);
}
Expand Down
1 change: 1 addition & 0 deletions packages/design-system/src/css/common/var.scss
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@ $input-small-height: 30px !default;
$input-mini-font-size: 12px;
/// height||Other|4
$input-mini-height: 26px !default;
$input-number-control-border-radius: 3px;

/* Cascader
-------------------------- */
Expand Down
66 changes: 32 additions & 34 deletions packages/design-system/src/css/input-number.scss
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,16 @@
}

@include mixins.e((increase, decrease)) {
--disabled-color: var(--color-text-light);
position: absolute;
z-index: 1;
top: 1px;
bottom: 1px;
display: flex;
align-items: center;
justify-content: center;
width: var.$input-height;
height: auto;
text-align: center;
background: var.$background-color-base;
color: var(--color-text-dark);
cursor: pointer;
Expand All @@ -59,13 +63,15 @@

@include mixins.e(increase) {
right: 1px;
border-radius: 0 var(--border-radius-base) var(--border-radius-base) 0;
border-radius: 0 var.$input-number-control-border-radius var.$input-number-control-border-radius
0;
border-left: var(--border-base);
}

@include mixins.e(decrease) {
left: 1px;
border-radius: var(--border-radius-base) 0 0 var(--border-radius-base);
border-radius: var.$input-number-control-border-radius 0 0
var.$input-number-control-border-radius;
border-right: var(--border-base);
}

Expand All @@ -82,7 +88,7 @@
}

@include mixins.m(medium) {
line-height: #{var.$input-medium-height - 2};
line-height: #{var.$input-medium-height - 4};

@include mixins.e((increase, decrease)) {
width: var.$input-medium-height;
Expand Down Expand Up @@ -114,7 +120,7 @@
}

@include mixins.m(mini) {
line-height: #{var.$input-mini-height - 2};
line-height: #{var.$input-mini-height - 4};

@include mixins.e((increase, decrease)) {
width: var.$input-mini-height;
Expand All @@ -134,28 +140,41 @@
@include mixins.when(without-controls) {
.el-input__inner {
text-align: left;
padding-left: 12px;
padding-right: 12px;
padding-left: var(--spacing-2xs);
padding-right: var(--spacing-2xs);
}
}

@include mixins.when(controls-right) {
.el-input__inner {
padding-left: 15px;
padding-right: #{var.$input-height + 10};
padding-left: var(--spacing-2xs);
padding-right: #{var.$input-height + 4};
}

&.el-input-number--medium .el-input__inner {
padding-right: #{var.$input-medium-height + 4};
}

&.el-input-number--small .el-input__inner {
padding-right: #{var.$input-small-height + 4};
}

&.el-input-number--mini .el-input__inner {
padding-left: var(--spacing-4xs);
padding-right: #{var.$input-mini-height + 4};
}

@include mixins.e((increase, decrease)) {
height: auto;
line-height: #{(var.$input-height - 2) * 0.5};
height: calc((100% - 1px) / 2);
bottom: auto;

[class*='el-icon'] {
transform: scale(0.8);
}
}

@include mixins.e(increase) {
border-radius: 0 var(--border-radius-base) 0 0;
border-radius: 0 var.$input-number-control-border-radius 0 0;
border-bottom: var(--border-base);
}

Expand All @@ -166,28 +185,7 @@
left: auto;
border-right: none;
border-left: var(--border-base);
border-radius: 0 0 var(--border-radius-base) 0;
}

&[class*='medium'] {
[class*='increase'],
[class*='decrease'] {
line-height: #{(var.$input-medium-height - 2) * 0.5};
}
}

&[class*='small'] {
[class*='increase'],
[class*='decrease'] {
line-height: #{(var.$input-small-height - 2) * 0.5};
}
}

&[class*='mini'] {
[class*='increase'],
[class*='decrease'] {
line-height: #{(var.$input-mini-height - 2) * 0.5};
}
border-radius: 0 0 var.$input-number-control-border-radius 0;
}
}
}
2 changes: 2 additions & 0 deletions packages/editor-ui/src/Interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1253,6 +1253,7 @@ export interface NDVState {
focusedInputPath: string;
mappingTelemetry: { [key: string]: string | number | boolean };
hoveringItem: null | TargetItem;
expressionOutputItemIndex: number;
draggable: {
isDragging: boolean;
type: string;
Expand All @@ -1261,6 +1262,7 @@ export interface NDVState {
activeTarget: { id: string; stickyPosition: null | XYPosition } | null;
};
isMappingOnboarded: boolean;
isTableHoverOnboarded: boolean;
isAutocompleteOnboarded: boolean;
highlightDraggables: boolean;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ const telemetry = useTelemetry();
const ndvStore = useNDVStore();
const workflowsStore = useWorkflowsStore();

const hoveringItemNumber = computed(() => ndvStore.hoveringItemNumber);
const isDragging = computed(() => ndvStore.isDraggableDragging);
const noInputData = computed(() => ndvStore.hasInputData);

function focus() {
if (inlineInput.value) {
Expand Down Expand Up @@ -166,9 +164,7 @@ defineExpose({ focus });
:editor-state="editorState"
:segments="segments"
:is-read-only="isReadOnly"
:no-input-data="noInputData"
:visible="isFocused"
:hovering-item-number="hoveringItemNumber"
/>
</div>
</template>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ onMounted(() => {
],
}),
});

highlighter.addColor(editor.value as EditorView, resolvedSegments.value);
highlighter.removeColor(editor.value as EditorView, plaintextSegments.value);
});

onBeforeUnmount(() => {
Expand Down
Loading
Loading