mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-18 10:31:15 +00:00
feat(editor): Params pane collection improvements (#11607)
Co-authored-by: Elias Meire <elsmr@users.noreply.github.com>
This commit is contained in:
@@ -82,6 +82,7 @@
|
||||
"vue-router": "catalog:frontend",
|
||||
"vue-virtual-scroller": "2.0.0-beta.8",
|
||||
"vue3-touch-events": "^4.1.3",
|
||||
"vuedraggable": "4.1.0",
|
||||
"xss": "catalog:"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -152,6 +152,14 @@ const onBlur = (): void => {
|
||||
}"
|
||||
data-test-id="assignment"
|
||||
>
|
||||
<N8nIconButton
|
||||
v-if="!isReadOnly"
|
||||
type="tertiary"
|
||||
text
|
||||
size="mini"
|
||||
icon="grip-vertical"
|
||||
:class="[$style.iconButton, $style.defaultTopPadding, 'drag-handle']"
|
||||
></N8nIconButton>
|
||||
<n8n-icon-button
|
||||
v-if="!isReadOnly"
|
||||
type="tertiary"
|
||||
@@ -159,7 +167,7 @@ const onBlur = (): void => {
|
||||
size="mini"
|
||||
icon="trash"
|
||||
data-test-id="assignment-remove"
|
||||
:class="$style.remove"
|
||||
:class="[$style.iconButton, $style.extraTopPadding]"
|
||||
@click="onRemove"
|
||||
></n8n-icon-button>
|
||||
|
||||
@@ -241,7 +249,7 @@ const onBlur = (): void => {
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.remove {
|
||||
.iconButton {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@@ -269,12 +277,19 @@ const onBlur = (): void => {
|
||||
}
|
||||
}
|
||||
|
||||
.remove {
|
||||
.iconButton {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: var(--spacing-l);
|
||||
opacity: 0;
|
||||
transition: opacity 100ms ease-in;
|
||||
color: var(--icon-base-color);
|
||||
}
|
||||
.extraTopPadding {
|
||||
top: calc(20px + var(--spacing-l));
|
||||
}
|
||||
|
||||
.defaultTopPadding {
|
||||
top: var(--spacing-l);
|
||||
}
|
||||
|
||||
.status {
|
||||
|
||||
@@ -15,6 +15,7 @@ import ParameterOptions from '../ParameterOptions.vue';
|
||||
import Assignment from './Assignment.vue';
|
||||
import { inputDataToAssignments, typeFromExpression } from './utils';
|
||||
import { propertyNameFromExpression } from '@/utils/mappingUtils';
|
||||
import Draggable from 'vuedraggable';
|
||||
|
||||
interface Props {
|
||||
parameter: INodeProperties;
|
||||
@@ -133,19 +134,27 @@ function optionSelected(action: string) {
|
||||
</n8n-input-label>
|
||||
<div :class="$style.content">
|
||||
<div :class="$style.assignments">
|
||||
<div v-for="(assignment, index) of state.paramValue.assignments" :key="assignment.id">
|
||||
<Assignment
|
||||
:model-value="assignment"
|
||||
:index="index"
|
||||
:path="`${path}.${index}`"
|
||||
:issues="getIssues(index)"
|
||||
:class="$style.assignment"
|
||||
:is-read-only="isReadOnly"
|
||||
@update:model-value="(value) => onAssignmentUpdate(index, value)"
|
||||
@remove="() => onAssignmentRemove(index)"
|
||||
>
|
||||
</Assignment>
|
||||
</div>
|
||||
<Draggable
|
||||
v-model="state.paramValue.assignments"
|
||||
item-key="id"
|
||||
handle=".drag-handle"
|
||||
:drag-class="$style.dragging"
|
||||
:ghost-class="$style.ghost"
|
||||
>
|
||||
<template #item="{ index, element: assignment }">
|
||||
<Assignment
|
||||
:model-value="assignment"
|
||||
:index="index"
|
||||
:path="`${path}.${index}`"
|
||||
:issues="getIssues(index)"
|
||||
:class="$style.assignment"
|
||||
:is-read-only="isReadOnly"
|
||||
@update:model-value="(value) => onAssignmentUpdate(index, value)"
|
||||
@remove="() => onAssignmentRemove(index)"
|
||||
>
|
||||
</Assignment>
|
||||
</template>
|
||||
</Draggable>
|
||||
</div>
|
||||
<div
|
||||
v-if="!isReadOnly"
|
||||
@@ -265,4 +274,18 @@ function optionSelected(action: string) {
|
||||
.icon {
|
||||
font-size: var(--font-size-2xl);
|
||||
}
|
||||
.ghost,
|
||||
.dragging {
|
||||
border-radius: var(--border-radius-base);
|
||||
padding-right: var(--spacing-xs);
|
||||
padding-bottom: var(--spacing-xs);
|
||||
}
|
||||
.ghost {
|
||||
background-color: var(--color-background-base);
|
||||
opacity: 0.5;
|
||||
}
|
||||
.dragging {
|
||||
background-color: var(--color-background-xlight);
|
||||
opacity: 0.7;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -33,6 +33,7 @@ interface Props {
|
||||
canRemove?: boolean;
|
||||
readOnly?: boolean;
|
||||
index?: number;
|
||||
canDrag?: boolean;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
@@ -41,6 +42,7 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
fixedLeftValue: false,
|
||||
readOnly: false,
|
||||
index: 0,
|
||||
canDrag: true,
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
@@ -152,6 +154,15 @@ const onBlur = (): void => {
|
||||
}"
|
||||
data-test-id="filter-condition"
|
||||
>
|
||||
<N8nIconButton
|
||||
v-if="canDrag && !readOnly"
|
||||
type="tertiary"
|
||||
text
|
||||
size="mini"
|
||||
icon="grip-vertical"
|
||||
:title="i18n.baseText('filter.dragCondition')"
|
||||
:class="[$style.iconButton, $style.defaultTopPadding, 'drag-handle']"
|
||||
></N8nIconButton>
|
||||
<n8n-icon-button
|
||||
v-if="canRemove && !readOnly"
|
||||
type="tertiary"
|
||||
@@ -160,7 +171,7 @@ const onBlur = (): void => {
|
||||
icon="trash"
|
||||
data-test-id="filter-remove-condition"
|
||||
:title="i18n.baseText('filter.removeCondition')"
|
||||
:class="$style.remove"
|
||||
:class="[$style.iconButton, $style.extraTopPadding]"
|
||||
@click="onRemove"
|
||||
></n8n-icon-button>
|
||||
<InputTriple>
|
||||
@@ -248,7 +259,7 @@ const onBlur = (): void => {
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.remove {
|
||||
.iconButton {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@@ -261,13 +272,21 @@ const onBlur = (): void => {
|
||||
|
||||
.statusIcon {
|
||||
padding-left: var(--spacing-4xs);
|
||||
padding-right: var(--spacing-4xs);
|
||||
}
|
||||
|
||||
.remove {
|
||||
.iconButton {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: var(--spacing-l);
|
||||
opacity: 0;
|
||||
transition: opacity 100ms ease-in;
|
||||
color: var(--icon-base-color);
|
||||
}
|
||||
|
||||
.defaultTopPadding {
|
||||
top: var(--spacing-m);
|
||||
}
|
||||
.extraTopPadding {
|
||||
top: calc(14px + var(--spacing-m));
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -23,6 +23,7 @@ import Condition from './Condition.vue';
|
||||
import CombinatorSelect from './CombinatorSelect.vue';
|
||||
import { resolveParameter } from '@/composables/useWorkflowHelpers';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import Draggable from 'vuedraggable';
|
||||
|
||||
interface Props {
|
||||
parameter: INodeProperties;
|
||||
@@ -161,30 +162,41 @@ function getIssues(index: number): string[] {
|
||||
</n8n-input-label>
|
||||
<div :class="$style.content">
|
||||
<div :class="$style.conditions">
|
||||
<div v-for="(condition, index) of state.paramValue.conditions" :key="condition.id">
|
||||
<CombinatorSelect
|
||||
v-if="index !== 0"
|
||||
:read-only="index !== 1 || readOnly"
|
||||
:options="allowedCombinators"
|
||||
:selected="state.paramValue.combinator"
|
||||
:class="$style.combinator"
|
||||
@combinator-change="onCombinatorChange"
|
||||
/>
|
||||
<Draggable
|
||||
item-key="id"
|
||||
v-model="state.paramValue.conditions"
|
||||
handle=".drag-handle"
|
||||
:drag-class="$style.dragging"
|
||||
:ghost-class="$style.ghost"
|
||||
>
|
||||
<template #item="{ index, element: condition }">
|
||||
<div>
|
||||
<CombinatorSelect
|
||||
v-if="index !== 0"
|
||||
:read-only="index !== 1 || readOnly"
|
||||
:options="allowedCombinators"
|
||||
:selected="state.paramValue.combinator"
|
||||
:class="$style.combinator"
|
||||
@combinator-change="onCombinatorChange"
|
||||
/>
|
||||
|
||||
<Condition
|
||||
:condition="condition"
|
||||
:index="index"
|
||||
:options="state.paramValue.options"
|
||||
:fixed-left-value="!!parameter.typeOptions?.filter?.leftValue"
|
||||
:read-only="readOnly"
|
||||
:can-remove="index !== 0 || state.paramValue.conditions.length > 1"
|
||||
:path="`${path}.${index}`"
|
||||
:issues="getIssues(index)"
|
||||
:class="$style.condition"
|
||||
@update="(value) => onConditionUpdate(index, value)"
|
||||
@remove="() => onConditionRemove(index)"
|
||||
></Condition>
|
||||
</div>
|
||||
<Condition
|
||||
:condition="condition"
|
||||
:index="index"
|
||||
:options="state.paramValue.options"
|
||||
:fixed-left-value="!!parameter.typeOptions?.filter?.leftValue"
|
||||
:read-only="readOnly"
|
||||
:can-remove="index !== 0 || state.paramValue.conditions.length > 1"
|
||||
:can-drag="index !== 0 || state.paramValue.conditions.length > 1"
|
||||
:path="`${path}.${index}`"
|
||||
:issues="getIssues(index)"
|
||||
:class="$style.condition"
|
||||
@update="(value) => onConditionUpdate(index, value)"
|
||||
@remove="() => onConditionRemove(index)"
|
||||
></Condition>
|
||||
</div>
|
||||
</template>
|
||||
</Draggable>
|
||||
</div>
|
||||
<div v-if="!singleCondition && !readOnly" :class="$style.addConditionWrapper">
|
||||
<n8n-button
|
||||
@@ -224,6 +236,7 @@ function getIssues(index: number): string[] {
|
||||
|
||||
.condition {
|
||||
padding-left: var(--spacing-l);
|
||||
padding-bottom: var(--spacing-xs);
|
||||
}
|
||||
|
||||
.single {
|
||||
@@ -266,4 +279,20 @@ function getIssues(index: number): string[] {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
.ghost,
|
||||
.dragging {
|
||||
border-radius: var(--border-radius-base);
|
||||
padding-right: var(--spacing-xs);
|
||||
}
|
||||
.ghost {
|
||||
background-color: var(--color-background-base);
|
||||
opacity: 0.5;
|
||||
}
|
||||
.dragging {
|
||||
background-color: var(--color-background-xlight);
|
||||
opacity: 0.7;
|
||||
}
|
||||
.dragging > .combinator {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
N8nButton,
|
||||
} from 'n8n-design-system';
|
||||
import ParameterInputList from './ParameterInputList.vue';
|
||||
import Draggable from 'vuedraggable';
|
||||
|
||||
const locale = useI18n();
|
||||
|
||||
@@ -126,42 +127,6 @@ const getOptionProperties = (optionName: string) => {
|
||||
return undefined;
|
||||
};
|
||||
|
||||
const moveOptionDown = (optionName: string, index: number) => {
|
||||
if (Array.isArray(mutableValues.value[optionName])) {
|
||||
mutableValues.value[optionName].splice(
|
||||
index + 1,
|
||||
0,
|
||||
mutableValues.value[optionName].splice(index, 1)[0],
|
||||
);
|
||||
}
|
||||
|
||||
const parameterData: ValueChangedEvent = {
|
||||
name: getPropertyPath(optionName),
|
||||
value: mutableValues.value[optionName],
|
||||
type: 'optionsOrderChanged',
|
||||
};
|
||||
|
||||
emit('valueChanged', parameterData);
|
||||
};
|
||||
|
||||
const moveOptionUp = (optionName: string, index: number) => {
|
||||
if (Array.isArray(mutableValues.value[optionName])) {
|
||||
mutableValues.value?.[optionName].splice(
|
||||
index - 1,
|
||||
0,
|
||||
mutableValues.value[optionName].splice(index, 1)[0],
|
||||
);
|
||||
}
|
||||
|
||||
const parameterData: ValueChangedEvent = {
|
||||
name: getPropertyPath(optionName),
|
||||
value: mutableValues.value[optionName],
|
||||
type: 'optionsOrderChanged',
|
||||
};
|
||||
|
||||
emit('valueChanged', parameterData);
|
||||
};
|
||||
|
||||
const optionSelected = (optionName: string) => {
|
||||
const option = getOptionProperties(optionName);
|
||||
if (option === undefined) {
|
||||
@@ -219,6 +184,15 @@ const optionSelected = (optionName: string) => {
|
||||
const valueChanged = (parameterData: IUpdateInformation) => {
|
||||
emit('valueChanged', parameterData);
|
||||
};
|
||||
const onDragChange = (optionName: string) => {
|
||||
const parameterData: ValueChangedEvent = {
|
||||
name: getPropertyPath(optionName),
|
||||
value: mutableValues.value[optionName],
|
||||
type: 'optionsOrderChanged',
|
||||
};
|
||||
|
||||
emit('valueChanged', parameterData);
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -246,59 +220,61 @@ const valueChanged = (parameterData: IUpdateInformation) => {
|
||||
color="text-dark"
|
||||
/>
|
||||
<div v-if="multipleValues">
|
||||
<div
|
||||
v-for="(_, index) in mutableValues[property.name]"
|
||||
:key="property.name + index"
|
||||
class="parameter-item"
|
||||
<Draggable
|
||||
v-model="mutableValues[property.name]"
|
||||
handle=".drag-handle"
|
||||
drag-class="dragging"
|
||||
ghost-class="ghost"
|
||||
chosen-class="chosen"
|
||||
@change="onDragChange(property.name)"
|
||||
>
|
||||
<div
|
||||
:class="index ? 'border-top-dashed parameter-item-wrapper ' : 'parameter-item-wrapper'"
|
||||
>
|
||||
<div v-if="!isReadOnly" class="delete-option">
|
||||
<N8nIconButton
|
||||
type="tertiary"
|
||||
text
|
||||
size="mini"
|
||||
icon="trash"
|
||||
data-test-id="fixed-collection-delete"
|
||||
:title="locale.baseText('fixedCollectionParameter.deleteItem')"
|
||||
@click="deleteOption(property.name, index)"
|
||||
></N8nIconButton>
|
||||
<N8nIconButton
|
||||
v-if="sortable && index !== 0"
|
||||
type="tertiary"
|
||||
text
|
||||
size="mini"
|
||||
icon="angle-up"
|
||||
:title="locale.baseText('fixedCollectionParameter.moveUp')"
|
||||
@click="moveOptionUp(property.name, index)"
|
||||
></N8nIconButton>
|
||||
<N8nIconButton
|
||||
v-if="sortable && index !== mutableValues[property.name].length - 1"
|
||||
type="tertiary"
|
||||
text
|
||||
size="mini"
|
||||
icon="angle-down"
|
||||
:title="locale.baseText('fixedCollectionParameter.moveDown')"
|
||||
@click="moveOptionDown(property.name, index)"
|
||||
></N8nIconButton>
|
||||
<template #item="{ index }">
|
||||
<div :key="property.name + '-' + index" class="parameter-item">
|
||||
<div
|
||||
:class="
|
||||
index ? 'border-top-dashed parameter-item-wrapper ' : 'parameter-item-wrapper'
|
||||
"
|
||||
>
|
||||
<div v-if="!isReadOnly" class="icon-button default-top-padding">
|
||||
<N8nIconButton
|
||||
v-if="sortable"
|
||||
type="tertiary"
|
||||
text
|
||||
size="mini"
|
||||
icon="grip-vertical"
|
||||
:title="locale.baseText('fixedCollectionParameter.dragItem')"
|
||||
class="drag-handle"
|
||||
></N8nIconButton>
|
||||
</div>
|
||||
<div v-if="!isReadOnly" class="icon-button extra-top-padding">
|
||||
<N8nIconButton
|
||||
type="tertiary"
|
||||
text
|
||||
size="mini"
|
||||
icon="trash"
|
||||
data-test-id="fixed-collection-delete"
|
||||
:title="locale.baseText('fixedCollectionParameter.deleteItem')"
|
||||
@click="deleteOption(property.name, index)"
|
||||
></N8nIconButton>
|
||||
</div>
|
||||
<Suspense>
|
||||
<ParameterInputList
|
||||
:parameters="property.values"
|
||||
:node-values="nodeValues"
|
||||
:path="getPropertyPath(property.name, index)"
|
||||
:hide-delete="true"
|
||||
:is-read-only="isReadOnly"
|
||||
@value-changed="valueChanged"
|
||||
/>
|
||||
</Suspense>
|
||||
</div>
|
||||
</div>
|
||||
<Suspense>
|
||||
<ParameterInputList
|
||||
:parameters="property.values"
|
||||
:node-values="nodeValues"
|
||||
:path="getPropertyPath(property.name, index)"
|
||||
:hide-delete="true"
|
||||
:is-read-only="isReadOnly"
|
||||
@value-changed="valueChanged"
|
||||
/>
|
||||
</Suspense>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Draggable>
|
||||
</div>
|
||||
<div v-else class="parameter-item">
|
||||
<div class="parameter-item-wrapper">
|
||||
<div v-if="!isReadOnly" class="delete-option">
|
||||
<div v-if="!isReadOnly" class="icon-button">
|
||||
<N8nIconButton
|
||||
type="tertiary"
|
||||
text
|
||||
@@ -355,7 +331,7 @@ const valueChanged = (parameterData: IUpdateInformation) => {
|
||||
.fixed-collection-parameter {
|
||||
padding-left: var(--spacing-s);
|
||||
|
||||
.delete-option {
|
||||
.icon-button {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
@@ -390,21 +366,36 @@ const valueChanged = (parameterData: IUpdateInformation) => {
|
||||
|
||||
.fixed-collection-parameter-property {
|
||||
margin: var(--spacing-xs) 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.parameter-item:hover > .parameter-item-wrapper > .delete-option {
|
||||
.parameter-item:hover > .parameter-item-wrapper > .icon-button {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.parameter-item {
|
||||
position: relative;
|
||||
padding: 0 0 0 1em;
|
||||
padding: 0 0 var(--spacing-s) var(--spacing-s);
|
||||
|
||||
+ .parameter-item {
|
||||
.parameter-item-wrapper {
|
||||
.delete-option {
|
||||
top: 14px;
|
||||
.default-top-padding {
|
||||
top: calc(1.2 * var(--spacing-s));
|
||||
}
|
||||
.extra-top-padding {
|
||||
top: calc(2.2 * var(--spacing-s));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.parameter-item:first-of-type {
|
||||
.parameter-item-wrapper {
|
||||
.default-top-padding {
|
||||
top: var(--spacing-3xs);
|
||||
}
|
||||
.extra-top-padding {
|
||||
top: var(--spacing-l);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -416,4 +407,20 @@ const valueChanged = (parameterData: IUpdateInformation) => {
|
||||
.no-items-exist {
|
||||
margin: var(--spacing-xs) 0;
|
||||
}
|
||||
.ghost,
|
||||
.dragging {
|
||||
border-radius: var(--border-radius-base);
|
||||
padding-right: var(--spacing-xs);
|
||||
}
|
||||
.ghost {
|
||||
background-color: var(--color-background-base);
|
||||
opacity: 0.5;
|
||||
}
|
||||
.dragging {
|
||||
background-color: var(--color-background-xlight);
|
||||
.parameter-item-wrapper {
|
||||
border: none;
|
||||
}
|
||||
opacity: 0.7;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -531,16 +531,6 @@ function getParameterValue<T extends NodeParameterValueType = NodeParameterValue
|
||||
v-else-if="['collection', 'fixedCollection'].includes(parameter.type)"
|
||||
class="multi-parameter"
|
||||
>
|
||||
<N8nIconButton
|
||||
v-if="hideDelete !== true && !isReadOnly && !parameter.isNodeSetting"
|
||||
type="tertiary"
|
||||
text
|
||||
size="mini"
|
||||
icon="trash"
|
||||
class="delete-option"
|
||||
:title="i18n.baseText('parameterInputList.delete')"
|
||||
@click="deleteOption(parameter.name)"
|
||||
></N8nIconButton>
|
||||
<N8nInputLabel
|
||||
:label="i18n.nodeText().inputLabelDisplayName(parameter, path)"
|
||||
:tooltip-text="i18n.nodeText().inputLabelDescription(parameter, path)"
|
||||
@@ -580,6 +570,16 @@ function getParameterValue<T extends NodeParameterValueType = NodeParameterValue
|
||||
<N8nIcon icon="exclamation-triangle" size="xsmall" />
|
||||
{{ i18n.baseText('parameterInputList.loadingError') }}
|
||||
</N8nText>
|
||||
<N8nIconButton
|
||||
v-if="hideDelete !== true && !isReadOnly && !parameter.isNodeSetting"
|
||||
type="tertiary"
|
||||
text
|
||||
size="mini"
|
||||
icon="trash"
|
||||
class="icon-button"
|
||||
:title="i18n.baseText('parameterInputList.delete')"
|
||||
@click="deleteOption(parameter.name)"
|
||||
></N8nIconButton>
|
||||
</div>
|
||||
<ResourceMapper
|
||||
v-else-if="parameter.type === 'resourceMapper'"
|
||||
@@ -620,7 +620,7 @@ function getParameterValue<T extends NodeParameterValueType = NodeParameterValue
|
||||
text
|
||||
size="mini"
|
||||
icon="trash"
|
||||
class="delete-option"
|
||||
class="icon-button"
|
||||
:title="i18n.baseText('parameterInputList.delete')"
|
||||
@click="deleteOption(parameter.name)"
|
||||
></N8nIconButton>
|
||||
@@ -650,12 +650,18 @@ function getParameterValue<T extends NodeParameterValueType = NodeParameterValue
|
||||
|
||||
<style lang="scss">
|
||||
.parameter-input-list-wrapper {
|
||||
.delete-option {
|
||||
.icon-button {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
top: 0;
|
||||
left: calc(-1 * var(--spacing-2xs));
|
||||
left: calc(-0.5 * var(--spacing-2xs));
|
||||
transition: opacity 100ms ease-in;
|
||||
Button {
|
||||
color: var(--color-icon-base);
|
||||
}
|
||||
}
|
||||
.icon-button > Button:hover {
|
||||
color: var(--color-icon-hover);
|
||||
}
|
||||
|
||||
.indent > div {
|
||||
@@ -675,8 +681,8 @@ function getParameterValue<T extends NodeParameterValueType = NodeParameterValue
|
||||
position: relative;
|
||||
margin: var(--spacing-xs) 0;
|
||||
}
|
||||
.parameter-item:hover > .delete-option,
|
||||
.multi-parameter:hover > .delete-option {
|
||||
.parameter-item:hover > .icon-button,
|
||||
.multi-parameter:hover > .icon-button {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -856,6 +856,7 @@
|
||||
"fixedCollectionParameter.choose": "Choose...",
|
||||
"fixedCollectionParameter.currentlyNoItemsExist": "Currently no items exist",
|
||||
"fixedCollectionParameter.deleteItem": "Delete item",
|
||||
"fixedCollectionParameter.dragItem": "Drag item",
|
||||
"fixedCollectionParameter.moveDown": "Move down",
|
||||
"fixedCollectionParameter.moveUp": "Move up",
|
||||
"forgotPassword": "Forgot my password",
|
||||
@@ -2706,6 +2707,7 @@
|
||||
"filter.combinator.and": "AND",
|
||||
"filter.addCondition": "Add condition",
|
||||
"filter.removeCondition": "Remove condition",
|
||||
"filter.dragCondition": "Drag condition",
|
||||
"filter.maxConditions": "Maximum conditions reached",
|
||||
"filter.condition.resolvedTrue": "This condition is true for the first input item",
|
||||
"filter.condition.resolvedFalse": "This condition is false for the first input item",
|
||||
|
||||
Reference in New Issue
Block a user