2019-06-23 03:35:23 -07:00
|
|
|
<template>
|
|
|
|
<div @keydown.stop :class="parameterInputClasses">
|
2022-07-20 04:32:51 -07:00
|
|
|
<expression-edit
|
|
|
|
:dialogVisible="expressionEditDialogVisible"
|
2022-12-14 01:04:10 -08:00
|
|
|
:value="
|
|
|
|
isResourceLocatorParameter && typeof value !== 'string' ? (value ? value.value : '') : value
|
|
|
|
"
|
2022-07-20 04:32:51 -07:00
|
|
|
:parameter="parameter"
|
|
|
|
:path="path"
|
|
|
|
:eventSource="eventSource || 'ndv'"
|
2022-12-01 04:26:22 -08:00
|
|
|
:isReadOnly="isReadOnly"
|
2022-07-20 04:32:51 -07:00
|
|
|
@closeDialog="closeExpressionEditDialog"
|
|
|
|
@valueChanged="expressionUpdated"
|
|
|
|
></expression-edit>
|
2022-12-14 05:43:02 -08:00
|
|
|
<div class="parameter-input ignore-key-press" :style="parameterInputWrapperStyle">
|
2022-09-21 06:44:45 -07:00
|
|
|
<resource-locator
|
|
|
|
v-if="isResourceLocatorParameter"
|
|
|
|
ref="resourceLocator"
|
|
|
|
:parameter="parameter"
|
|
|
|
:value="value"
|
|
|
|
:displayTitle="displayTitle"
|
|
|
|
:expressionDisplayValue="expressionDisplayValue"
|
2022-10-12 05:06:28 -07:00
|
|
|
:expressionComputedValue="expressionEvaluated"
|
2022-09-21 06:44:45 -07:00
|
|
|
:isValueExpression="isValueExpression"
|
|
|
|
:isReadOnly="isReadOnly"
|
|
|
|
:parameterIssues="getIssues"
|
|
|
|
:droppable="droppable"
|
|
|
|
:node="node"
|
|
|
|
:path="path"
|
|
|
|
@input="valueChanged"
|
2022-12-14 05:43:02 -08:00
|
|
|
@modalOpenerClick="openExpressionEditorModal"
|
2022-09-21 06:44:45 -07:00
|
|
|
@focus="setFocus"
|
|
|
|
@blur="onBlur"
|
|
|
|
@drop="onResourceLocatorDrop"
|
|
|
|
/>
|
2022-12-14 05:43:02 -08:00
|
|
|
<ExpressionParameterInput
|
|
|
|
v-else-if="isValueExpression || forceShowExpression"
|
2022-10-12 05:06:28 -07:00
|
|
|
:value="expressionDisplayValue"
|
2022-07-20 04:32:51 -07:00
|
|
|
:title="displayTitle"
|
2022-12-14 05:43:02 -08:00
|
|
|
:isReadOnly="isReadOnly"
|
2023-02-02 03:35:38 -08:00
|
|
|
:path="path"
|
2022-12-14 05:43:02 -08:00
|
|
|
@valueChanged="expressionUpdated"
|
|
|
|
@modalOpenerClick="openExpressionEditorModal"
|
|
|
|
@focus="setFocus"
|
|
|
|
@blur="onBlur"
|
|
|
|
ref="inputField"
|
2022-07-20 04:32:51 -07:00
|
|
|
/>
|
|
|
|
<div
|
|
|
|
v-else-if="
|
|
|
|
['json', 'string'].includes(parameter.type) ||
|
|
|
|
remoteParameterOptionsLoadingIssues !== null
|
|
|
|
"
|
|
|
|
>
|
|
|
|
<code-edit
|
|
|
|
v-if="codeEditDialogVisible"
|
|
|
|
:value="value"
|
|
|
|
:parameter="parameter"
|
|
|
|
:type="editorType"
|
|
|
|
:codeAutocomplete="codeAutocomplete"
|
|
|
|
:path="path"
|
2022-09-07 00:18:18 -07:00
|
|
|
:readonly="isReadOnly"
|
2022-07-20 04:32:51 -07:00
|
|
|
@closeDialog="closeCodeEditDialog"
|
|
|
|
@valueChanged="expressionUpdated"
|
|
|
|
></code-edit>
|
|
|
|
<text-edit
|
|
|
|
:dialogVisible="textEditDialogVisible"
|
|
|
|
:value="value"
|
|
|
|
:parameter="parameter"
|
|
|
|
:path="path"
|
2022-10-24 11:17:25 -07:00
|
|
|
:isReadOnly="isReadOnly"
|
2022-07-20 04:32:51 -07:00
|
|
|
@closeDialog="closeTextEditDialog"
|
|
|
|
@valueChanged="expressionUpdated"
|
|
|
|
></text-edit>
|
|
|
|
|
2022-10-13 05:28:02 -07:00
|
|
|
<code-node-editor
|
|
|
|
v-if="getArgument('editor') === 'codeNodeEditor' && isCodeNode(node)"
|
|
|
|
:mode="node.parameters.mode"
|
|
|
|
:jsCode="node.parameters.jsCode"
|
|
|
|
:isReadOnly="isReadOnly"
|
2022-10-20 06:45:58 -07:00
|
|
|
@valueChanged="valueChangedDebounced"
|
2022-10-13 05:28:02 -07:00
|
|
|
/>
|
|
|
|
|
2023-01-26 01:03:13 -08:00
|
|
|
<html-editor
|
|
|
|
v-else-if="getArgument('editor') === 'htmlEditor' && isHtmlNode(node)"
|
|
|
|
:html="node.parameters.html"
|
|
|
|
:isReadOnly="isReadOnly"
|
|
|
|
@valueChanged="valueChangedDebounced"
|
|
|
|
/>
|
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
<div
|
|
|
|
v-else-if="isEditor === true"
|
|
|
|
class="code-edit clickable ph-no-capture"
|
|
|
|
@click="displayEditDialog()"
|
|
|
|
>
|
2022-07-20 04:32:51 -07:00
|
|
|
<prism-editor
|
|
|
|
v-if="!codeEditDialogVisible"
|
|
|
|
:lineNumbers="true"
|
|
|
|
:readonly="true"
|
|
|
|
:code="displayValue"
|
|
|
|
language="js"
|
|
|
|
></prism-editor>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<n8n-input
|
|
|
|
v-else
|
|
|
|
v-model="tempValue"
|
|
|
|
ref="inputField"
|
2022-12-14 05:43:02 -08:00
|
|
|
class="input-with-opener"
|
2022-07-20 04:32:51 -07:00
|
|
|
:size="inputSize"
|
|
|
|
:type="getStringInputType"
|
|
|
|
:rows="getArgument('rows')"
|
|
|
|
:value="displayValue"
|
|
|
|
:disabled="isReadOnly"
|
|
|
|
@input="onTextInputChange"
|
|
|
|
@change="valueChanged"
|
|
|
|
@keydown.stop
|
|
|
|
@focus="setFocus"
|
|
|
|
@blur="onBlur"
|
|
|
|
:title="displayTitle"
|
|
|
|
:placeholder="getPlaceholder()"
|
|
|
|
>
|
2022-11-18 05:59:31 -08:00
|
|
|
<template #suffix>
|
2022-12-14 05:43:02 -08:00
|
|
|
<n8n-icon
|
2022-12-15 05:31:06 -08:00
|
|
|
v-if="!isReadOnly && !isSecretParameter"
|
2022-12-14 05:43:02 -08:00
|
|
|
icon="external-link-alt"
|
|
|
|
size="xsmall"
|
|
|
|
class="edit-window-button textarea-modal-opener"
|
|
|
|
:class="{
|
|
|
|
focused: isFocused,
|
|
|
|
invalid: !isFocused && getIssues.length > 0 && !isValueExpression,
|
|
|
|
}"
|
|
|
|
:title="$locale.baseText('parameterInput.openEditWindow')"
|
|
|
|
@click="displayEditDialog()"
|
|
|
|
@focus="setFocus"
|
|
|
|
/>
|
2022-11-18 05:59:31 -08:00
|
|
|
</template>
|
2022-07-20 04:32:51 -07:00
|
|
|
</n8n-input>
|
2019-09-04 09:22:06 -07:00
|
|
|
</div>
|
|
|
|
|
2022-07-20 04:32:51 -07:00
|
|
|
<div v-else-if="parameter.type === 'color'" ref="inputField" class="color-input">
|
|
|
|
<el-color-picker
|
|
|
|
size="small"
|
|
|
|
class="color-picker"
|
|
|
|
:value="displayValue"
|
|
|
|
:disabled="isReadOnly"
|
|
|
|
@focus="setFocus"
|
|
|
|
@blur="onBlur"
|
|
|
|
@change="valueChanged"
|
|
|
|
:title="displayTitle"
|
|
|
|
:show-alpha="getArgument('showAlpha')"
|
|
|
|
/>
|
|
|
|
<n8n-input
|
|
|
|
v-model="tempValue"
|
|
|
|
:size="inputSize"
|
|
|
|
type="text"
|
|
|
|
:value="tempValue"
|
|
|
|
:disabled="isReadOnly"
|
|
|
|
@change="valueChanged"
|
|
|
|
@keydown.stop
|
|
|
|
@focus="setFocus"
|
|
|
|
@blur="onBlur"
|
|
|
|
:title="displayTitle"
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<el-date-picker
|
|
|
|
v-else-if="parameter.type === 'dateTime'"
|
2019-06-23 03:35:23 -07:00
|
|
|
v-model="tempValue"
|
|
|
|
ref="inputField"
|
2022-07-20 04:32:51 -07:00
|
|
|
type="datetime"
|
2021-08-29 04:36:17 -07:00
|
|
|
:size="inputSize"
|
2019-06-23 03:35:23 -07:00
|
|
|
:value="displayValue"
|
2022-07-20 04:32:51 -07:00
|
|
|
:title="displayTitle"
|
2019-06-23 03:35:23 -07:00
|
|
|
:disabled="isReadOnly"
|
2022-07-20 04:32:51 -07:00
|
|
|
:placeholder="
|
|
|
|
parameter.placeholder
|
|
|
|
? getPlaceholder()
|
|
|
|
: $locale.baseText('parameterInput.selectDateAndTime')
|
|
|
|
"
|
|
|
|
:picker-options="dateTimePickerOptions"
|
2019-06-23 03:35:23 -07:00
|
|
|
@change="valueChanged"
|
2021-08-29 04:36:17 -07:00
|
|
|
@focus="setFocus"
|
2021-09-11 01:15:36 -07:00
|
|
|
@blur="onBlur"
|
2022-07-20 04:32:51 -07:00
|
|
|
@keydown.stop
|
|
|
|
/>
|
2019-06-23 03:35:23 -07:00
|
|
|
|
2022-07-20 04:32:51 -07:00
|
|
|
<n8n-input-number
|
|
|
|
v-else-if="parameter.type === 'number'"
|
|
|
|
ref="inputField"
|
|
|
|
:size="inputSize"
|
2021-08-29 04:36:17 -07:00
|
|
|
:value="displayValue"
|
2022-07-20 04:32:51 -07:00
|
|
|
:controls="false"
|
|
|
|
:max="getArgument('maxValue')"
|
|
|
|
:min="getArgument('minValue')"
|
|
|
|
:precision="getArgument('numberPrecision')"
|
2021-08-29 04:36:17 -07:00
|
|
|
:disabled="isReadOnly"
|
2022-07-20 04:32:51 -07:00
|
|
|
@change="valueChanged"
|
|
|
|
@input="onTextInputChange"
|
2021-08-29 04:36:17 -07:00
|
|
|
@focus="setFocus"
|
2021-09-11 01:15:36 -07:00
|
|
|
@blur="onBlur"
|
2022-07-20 04:32:51 -07:00
|
|
|
@keydown.stop
|
2021-08-29 04:36:17 -07:00
|
|
|
:title="displayTitle"
|
2022-07-20 04:32:51 -07:00
|
|
|
:placeholder="parameter.placeholder"
|
2021-08-29 04:36:17 -07:00
|
|
|
/>
|
2022-07-20 04:32:51 -07:00
|
|
|
|
|
|
|
<credentials-select
|
2022-12-14 01:04:10 -08:00
|
|
|
v-else-if="parameter.type === 'credentialsSelect' || parameter.name === 'genericAuthType'"
|
2022-07-20 04:32:51 -07:00
|
|
|
ref="inputField"
|
|
|
|
:parameter="parameter"
|
|
|
|
:node="node"
|
|
|
|
:activeCredentialType="activeCredentialType"
|
|
|
|
:inputSize="inputSize"
|
|
|
|
:displayValue="displayValue"
|
|
|
|
:isReadOnly="isReadOnly"
|
|
|
|
:displayTitle="displayTitle"
|
|
|
|
@credentialSelected="credentialSelected"
|
|
|
|
@valueChanged="valueChanged"
|
|
|
|
@setFocus="setFocus"
|
|
|
|
@onBlur="onBlur"
|
|
|
|
>
|
2022-11-18 05:59:31 -08:00
|
|
|
<template #issues-and-options>
|
2022-07-20 04:32:51 -07:00
|
|
|
<parameter-issues :issues="getIssues" />
|
|
|
|
</template>
|
|
|
|
</credentials-select>
|
|
|
|
|
|
|
|
<n8n-select
|
|
|
|
v-else-if="parameter.type === 'options'"
|
|
|
|
ref="inputField"
|
2021-08-29 04:36:17 -07:00
|
|
|
:size="inputSize"
|
2022-07-20 04:32:51 -07:00
|
|
|
filterable
|
|
|
|
:value="displayValue"
|
|
|
|
:placeholder="
|
|
|
|
parameter.placeholder ? getPlaceholder() : $locale.baseText('parameterInput.select')
|
|
|
|
"
|
|
|
|
:loading="remoteParameterOptionsLoading"
|
|
|
|
:disabled="isReadOnly || remoteParameterOptionsLoading"
|
|
|
|
:title="displayTitle"
|
2021-08-29 04:36:17 -07:00
|
|
|
@change="valueChanged"
|
|
|
|
@keydown.stop
|
|
|
|
@focus="setFocus"
|
2021-09-11 01:15:36 -07:00
|
|
|
@blur="onBlur"
|
2022-07-20 04:32:51 -07:00
|
|
|
>
|
|
|
|
<n8n-option
|
|
|
|
v-for="option in parameterOptions"
|
|
|
|
:value="option.value"
|
|
|
|
:key="option.value"
|
|
|
|
:label="getOptionsOptionDisplayName(option)"
|
|
|
|
>
|
|
|
|
<div class="list-option">
|
2022-08-19 06:35:39 -07:00
|
|
|
<div
|
2022-09-21 01:20:29 -07:00
|
|
|
class="option-headline ph-no-capture"
|
2022-08-19 06:35:39 -07:00
|
|
|
:class="{ 'remote-parameter-option': isRemoteParameterOption(option) }"
|
|
|
|
>
|
2022-07-20 04:32:51 -07:00
|
|
|
{{ getOptionsOptionDisplayName(option) }}
|
|
|
|
</div>
|
|
|
|
<div
|
|
|
|
v-if="option.description"
|
|
|
|
class="option-description"
|
|
|
|
v-html="getOptionsOptionDescription(option)"
|
|
|
|
></div>
|
|
|
|
</div>
|
|
|
|
</n8n-option>
|
|
|
|
</n8n-select>
|
2019-06-23 03:35:23 -07:00
|
|
|
|
2022-07-20 04:32:51 -07:00
|
|
|
<n8n-select
|
|
|
|
v-else-if="parameter.type === 'multiOptions'"
|
|
|
|
ref="inputField"
|
|
|
|
:size="inputSize"
|
|
|
|
filterable
|
|
|
|
multiple
|
|
|
|
:value="displayValue"
|
|
|
|
:loading="remoteParameterOptionsLoading"
|
|
|
|
:disabled="isReadOnly || remoteParameterOptionsLoading"
|
|
|
|
:title="displayTitle"
|
|
|
|
:placeholder="$locale.baseText('parameterInput.select')"
|
|
|
|
@change="valueChanged"
|
|
|
|
@keydown.stop
|
|
|
|
@focus="setFocus"
|
|
|
|
@blur="onBlur"
|
2019-06-23 03:35:23 -07:00
|
|
|
>
|
2022-07-20 04:32:51 -07:00
|
|
|
<n8n-option
|
|
|
|
v-for="option in parameterOptions"
|
|
|
|
:value="option.value"
|
|
|
|
:key="option.value"
|
|
|
|
:label="getOptionsOptionDisplayName(option)"
|
|
|
|
>
|
|
|
|
<div class="list-option">
|
|
|
|
<div class="option-headline">{{ getOptionsOptionDisplayName(option) }}</div>
|
|
|
|
<div
|
|
|
|
v-if="option.description"
|
|
|
|
class="option-description"
|
|
|
|
v-html="getOptionsOptionDescription(option)"
|
|
|
|
></div>
|
2021-11-15 02:19:43 -08:00
|
|
|
</div>
|
2022-07-20 04:32:51 -07:00
|
|
|
</n8n-option>
|
|
|
|
</n8n-select>
|
2019-06-23 03:35:23 -07:00
|
|
|
|
2022-07-20 04:32:51 -07:00
|
|
|
<el-switch
|
|
|
|
v-else-if="parameter.type === 'boolean'"
|
|
|
|
class="switch-input"
|
|
|
|
ref="inputField"
|
|
|
|
active-color="#13ce66"
|
|
|
|
:value="displayValue"
|
|
|
|
:disabled="isReadOnly"
|
|
|
|
@change="valueChanged"
|
|
|
|
/>
|
|
|
|
</div>
|
2021-08-29 04:36:17 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
<parameter-issues
|
|
|
|
v-if="parameter.type !== 'credentialsSelect' && !isResourceLocatorParameter"
|
|
|
|
:issues="getIssues"
|
|
|
|
/>
|
2019-06-23 03:35:23 -07:00
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script lang="ts">
|
2022-09-23 07:14:28 -07:00
|
|
|
/* eslint-disable prefer-spread */
|
|
|
|
|
2020-01-04 20:28:09 -08:00
|
|
|
import { get } from 'lodash';
|
2019-06-23 03:35:23 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
import { INodeUi, INodeUpdatePropertiesInformation } from '@/Interface';
|
2019-06-23 03:35:23 -07:00
|
|
|
import {
|
|
|
|
NodeHelpers,
|
|
|
|
NodeParameterValue,
|
2022-02-05 13:55:43 -08:00
|
|
|
ILoadOptions,
|
2019-12-16 18:27:56 -08:00
|
|
|
INodeParameters,
|
2019-06-23 03:35:23 -07:00
|
|
|
INodePropertyOptions,
|
|
|
|
Workflow,
|
2022-10-12 05:06:28 -07:00
|
|
|
INodeProperties,
|
|
|
|
INodePropertyCollection,
|
2022-09-22 10:04:26 -07:00
|
|
|
NodeParameterValueType,
|
2019-06-23 03:35:23 -07:00
|
|
|
} from 'n8n-workflow';
|
|
|
|
|
2019-09-04 09:22:06 -07:00
|
|
|
import CodeEdit from '@/components/CodeEdit.vue';
|
2022-05-24 02:36:19 -07:00
|
|
|
import CredentialsSelect from '@/components/CredentialsSelect.vue';
|
2022-09-29 14:28:02 -07:00
|
|
|
import ImportParameter from '@/components/ImportParameter.vue';
|
2019-06-23 03:35:23 -07:00
|
|
|
import ExpressionEdit from '@/components/ExpressionEdit.vue';
|
2022-05-24 02:36:19 -07:00
|
|
|
import NodeCredentials from '@/components/NodeCredentials.vue';
|
|
|
|
import ScopesNotice from '@/components/ScopesNotice.vue';
|
|
|
|
import ParameterOptions from '@/components/ParameterOptions.vue';
|
|
|
|
import ParameterIssues from '@/components/ParameterIssues.vue';
|
2022-09-21 06:44:45 -07:00
|
|
|
import ResourceLocator from '@/components/ResourceLocator/ResourceLocator.vue';
|
2022-12-14 05:43:02 -08:00
|
|
|
import ExpressionParameterInput from '@/components/ExpressionParameterInput.vue';
|
2019-09-04 09:22:06 -07:00
|
|
|
// @ts-ignore
|
|
|
|
import PrismEditor from 'vue-prism-editor';
|
2019-06-23 03:35:23 -07:00
|
|
|
import TextEdit from '@/components/TextEdit.vue';
|
2022-10-13 05:28:02 -07:00
|
|
|
import CodeNodeEditor from '@/components/CodeNodeEditor/CodeNodeEditor.vue';
|
2023-01-26 01:03:13 -08:00
|
|
|
import HtmlEditor from '@/components/HtmlEditor/HtmlEditor.vue';
|
2022-11-23 04:41:53 -08:00
|
|
|
import { externalHooks } from '@/mixins/externalHooks';
|
|
|
|
import { nodeHelpers } from '@/mixins/nodeHelpers';
|
|
|
|
import { showMessage } from '@/mixins/showMessage';
|
|
|
|
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
|
|
|
import { hasExpressionMapping, isValueExpression, isResourceLocatorValue } from '@/utils';
|
2019-06-23 03:35:23 -07:00
|
|
|
|
|
|
|
import mixins from 'vue-typed-mixins';
|
2022-05-24 02:36:19 -07:00
|
|
|
import { CUSTOM_API_CALL_KEY } from '@/constants';
|
2023-01-26 01:03:13 -08:00
|
|
|
import { CODE_NODE_TYPE, HTML_NODE_TYPE } from '@/constants';
|
2022-10-12 05:06:28 -07:00
|
|
|
import { PropType } from 'vue';
|
2022-11-23 04:41:53 -08:00
|
|
|
import { debounceHelper } from '@/mixins/debounce';
|
2022-11-04 06:04:31 -07:00
|
|
|
import { mapStores } from 'pinia';
|
|
|
|
import { useWorkflowsStore } from '@/stores/workflows';
|
|
|
|
import { useNDVStore } from '@/stores/ndv';
|
|
|
|
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
2022-11-09 01:01:50 -08:00
|
|
|
import { useCredentialsStore } from '@/stores/credentials';
|
2023-01-26 01:03:13 -08:00
|
|
|
import { htmlEditorEventBus } from '@/event-bus/html-editor-event-bus';
|
2019-06-23 03:35:23 -07:00
|
|
|
|
|
|
|
export default mixins(
|
2021-08-13 03:01:12 -07:00
|
|
|
externalHooks,
|
2019-06-23 03:35:23 -07:00
|
|
|
nodeHelpers,
|
|
|
|
showMessage,
|
|
|
|
workflowHelpers,
|
2022-10-20 06:45:58 -07:00
|
|
|
debounceHelper,
|
2022-12-14 01:04:10 -08:00
|
|
|
).extend({
|
|
|
|
name: 'parameter-input',
|
|
|
|
components: {
|
|
|
|
CodeEdit,
|
|
|
|
CodeNodeEditor,
|
2023-01-26 01:03:13 -08:00
|
|
|
HtmlEditor,
|
2022-12-14 01:04:10 -08:00
|
|
|
ExpressionEdit,
|
2022-12-14 05:43:02 -08:00
|
|
|
ExpressionParameterInput,
|
2022-12-14 01:04:10 -08:00
|
|
|
NodeCredentials,
|
|
|
|
CredentialsSelect,
|
|
|
|
PrismEditor,
|
|
|
|
ScopesNotice,
|
|
|
|
ParameterOptions,
|
|
|
|
ParameterIssues,
|
|
|
|
ResourceLocator,
|
|
|
|
TextEdit,
|
|
|
|
ImportParameter,
|
|
|
|
},
|
|
|
|
props: {
|
|
|
|
isReadOnly: {
|
|
|
|
type: Boolean,
|
2019-06-23 03:35:23 -07:00
|
|
|
},
|
2022-12-14 01:04:10 -08:00
|
|
|
parameter: {
|
|
|
|
type: Object as PropType<INodeProperties>,
|
2022-10-12 05:06:28 -07:00
|
|
|
},
|
2022-12-14 01:04:10 -08:00
|
|
|
path: {
|
|
|
|
type: String,
|
|
|
|
},
|
|
|
|
value: {
|
|
|
|
type: [String, Number, Boolean, Array, Object] as PropType<NodeParameterValueType>,
|
|
|
|
},
|
|
|
|
hideLabel: {
|
|
|
|
type: Boolean,
|
|
|
|
},
|
|
|
|
droppable: {
|
|
|
|
type: Boolean,
|
|
|
|
},
|
|
|
|
activeDrop: {
|
|
|
|
type: Boolean,
|
|
|
|
},
|
|
|
|
forceShowExpression: {
|
|
|
|
type: Boolean,
|
|
|
|
},
|
|
|
|
hint: {
|
|
|
|
type: String as PropType<string | undefined>,
|
|
|
|
},
|
|
|
|
inputSize: {
|
|
|
|
type: String,
|
|
|
|
},
|
|
|
|
hideIssues: {
|
|
|
|
type: Boolean,
|
|
|
|
},
|
|
|
|
documentationUrl: {
|
|
|
|
type: String as PropType<string | undefined>,
|
|
|
|
},
|
|
|
|
errorHighlight: {
|
|
|
|
type: Boolean,
|
|
|
|
},
|
|
|
|
isForCredential: {
|
|
|
|
type: Boolean,
|
|
|
|
},
|
|
|
|
eventSource: {
|
|
|
|
type: String,
|
|
|
|
},
|
|
|
|
expressionEvaluated: {
|
|
|
|
type: String as PropType<string | undefined>,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
codeEditDialogVisible: false,
|
|
|
|
nodeName: '',
|
|
|
|
expressionAddOperation: 'set' as 'add' | 'set',
|
|
|
|
expressionEditDialogVisible: false,
|
|
|
|
remoteParameterOptions: [] as INodePropertyOptions[],
|
|
|
|
remoteParameterOptionsLoading: false,
|
|
|
|
remoteParameterOptionsLoadingIssues: null as string | null,
|
|
|
|
textEditDialogVisible: false,
|
|
|
|
tempValue: '', // el-date-picker and el-input does not seem to work without v-model so add one
|
|
|
|
CUSTOM_API_CALL_KEY,
|
|
|
|
activeCredentialType: '',
|
|
|
|
dateTimePickerOptions: {
|
|
|
|
shortcuts: [
|
|
|
|
{
|
|
|
|
text: 'Today', // TODO
|
2022-12-15 05:06:00 -08:00
|
|
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
2022-12-14 01:04:10 -08:00
|
|
|
onClick(picker: any) {
|
|
|
|
picker.$emit('pick', new Date());
|
2019-06-23 03:35:23 -07:00
|
|
|
},
|
2022-12-14 01:04:10 -08:00
|
|
|
},
|
|
|
|
{
|
|
|
|
text: 'Yesterday', // TODO
|
2022-12-15 05:06:00 -08:00
|
|
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
2022-12-14 01:04:10 -08:00
|
|
|
onClick(picker: any) {
|
|
|
|
const date = new Date();
|
|
|
|
date.setTime(date.getTime() - 3600 * 1000 * 24);
|
|
|
|
picker.$emit('pick', date);
|
2019-06-23 03:35:23 -07:00
|
|
|
},
|
2022-12-14 01:04:10 -08:00
|
|
|
},
|
|
|
|
{
|
|
|
|
text: 'A week ago', // TODO
|
2022-12-15 05:06:00 -08:00
|
|
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
2022-12-14 01:04:10 -08:00
|
|
|
onClick(picker: any) {
|
|
|
|
const date = new Date();
|
|
|
|
date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
|
|
|
|
picker.$emit('pick', date);
|
2019-06-23 03:35:23 -07:00
|
|
|
},
|
2022-12-14 01:04:10 -08:00
|
|
|
},
|
|
|
|
],
|
2019-06-23 03:35:23 -07:00
|
|
|
},
|
2022-12-14 05:43:02 -08:00
|
|
|
isFocused: false,
|
2022-12-14 01:04:10 -08:00
|
|
|
};
|
|
|
|
},
|
|
|
|
watch: {
|
|
|
|
dependentParametersValues() {
|
|
|
|
// Reload the remote parameters whenever a parameter
|
|
|
|
// on which the current field depends on changes
|
|
|
|
this.loadRemoteParameterOptions();
|
2019-06-23 03:35:23 -07:00
|
|
|
},
|
2022-12-14 01:04:10 -08:00
|
|
|
value() {
|
|
|
|
if (this.parameter.type === 'color' && this.getArgument('showAlpha') === true) {
|
|
|
|
// Do not set for color with alpha else wrong value gets displayed in field
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.tempValue = this.displayValue as string;
|
|
|
|
},
|
|
|
|
},
|
|
|
|
computed: {
|
|
|
|
...mapStores(useCredentialsStore, useNodeTypesStore, useNDVStore, useWorkflowsStore),
|
|
|
|
expressionDisplayValue(): string {
|
2022-12-20 07:23:57 -08:00
|
|
|
if (this.forceShowExpression) {
|
2022-12-14 01:04:10 -08:00
|
|
|
return '';
|
|
|
|
}
|
2020-01-04 20:28:09 -08:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
const value = isResourceLocatorValue(this.value) ? this.value.value : this.value;
|
|
|
|
if (typeof value === 'string' && value.startsWith('=')) {
|
|
|
|
return value.slice(1);
|
|
|
|
}
|
2020-01-04 20:28:09 -08:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
return `${this.displayValue ?? ''}`;
|
|
|
|
},
|
|
|
|
isValueExpression(): boolean {
|
|
|
|
return isValueExpression(this.parameter, this.value);
|
|
|
|
},
|
|
|
|
codeAutocomplete(): string | undefined {
|
|
|
|
return this.getArgument('codeAutocomplete') as string | undefined;
|
|
|
|
},
|
|
|
|
dependentParametersValues(): string | null {
|
|
|
|
const loadOptionsDependsOn = this.getArgument('loadOptionsDependsOn') as string[] | undefined;
|
2020-01-04 20:28:09 -08:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
if (loadOptionsDependsOn === undefined) {
|
|
|
|
return null;
|
|
|
|
}
|
2019-06-23 03:35:23 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
// Get the resolved parameter values of the current node
|
|
|
|
const currentNodeParameters = this.ndvStore.activeNode?.parameters;
|
|
|
|
try {
|
|
|
|
const resolvedNodeParameters = this.resolveParameter(currentNodeParameters);
|
2019-06-23 03:35:23 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
const returnValues: string[] = [];
|
|
|
|
for (const parameterPath of loadOptionsDependsOn) {
|
|
|
|
returnValues.push(get(resolvedNodeParameters, parameterPath) as string);
|
2019-06-23 03:35:23 -07:00
|
|
|
}
|
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
return returnValues.join('|');
|
|
|
|
} catch (error) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
node(): INodeUi | null {
|
|
|
|
return this.ndvStore.activeNode;
|
|
|
|
},
|
|
|
|
displayTitle(): string {
|
|
|
|
const interpolation = { interpolate: { shortPath: this.shortPath } };
|
|
|
|
|
|
|
|
if (this.getIssues.length && this.isValueExpression) {
|
|
|
|
return this.$locale.baseText(
|
|
|
|
'parameterInput.parameterHasIssuesAndExpression',
|
|
|
|
interpolation,
|
|
|
|
);
|
|
|
|
} else if (this.getIssues.length && !this.isValueExpression) {
|
|
|
|
return this.$locale.baseText('parameterInput.parameterHasIssues', interpolation);
|
|
|
|
} else if (!this.getIssues.length && this.isValueExpression) {
|
|
|
|
return this.$locale.baseText('parameterInput.parameterHasExpression', interpolation);
|
|
|
|
}
|
2022-05-24 02:36:19 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
return this.$locale.baseText('parameterInput.parameter', interpolation);
|
|
|
|
},
|
|
|
|
displayValue(): string | number | boolean | null {
|
|
|
|
if (this.remoteParameterOptionsLoading === true) {
|
|
|
|
// If it is loading options from server display
|
|
|
|
// to user that the data is loading. If not it would
|
|
|
|
// display the user the key instead of the value it
|
|
|
|
// represents
|
|
|
|
return this.$locale.baseText('parameterInput.loadingOptions');
|
|
|
|
}
|
2020-11-09 02:26:46 -08:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
let returnValue;
|
|
|
|
if (this.isValueExpression === false) {
|
|
|
|
returnValue = this.isResourceLocatorParameter
|
|
|
|
? isResourceLocatorValue(this.value)
|
|
|
|
? this.value.value
|
|
|
|
: ''
|
|
|
|
: this.value;
|
|
|
|
} else {
|
|
|
|
returnValue = this.expressionEvaluated;
|
|
|
|
}
|
2020-11-09 02:26:46 -08:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
if (this.parameter.type === 'credentialsSelect' && typeof this.value === 'string') {
|
|
|
|
const credType = this.credentialsStore.getCredentialTypeByName(this.value);
|
|
|
|
if (credType) {
|
|
|
|
returnValue = credType.displayName;
|
2019-06-23 03:35:23 -07:00
|
|
|
}
|
2022-12-14 01:04:10 -08:00
|
|
|
}
|
2019-06-23 03:35:23 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
if (
|
|
|
|
Array.isArray(returnValue) &&
|
|
|
|
this.parameter.type === 'color' &&
|
|
|
|
this.getArgument('showAlpha') === true &&
|
|
|
|
returnValue.charAt(0) === '#'
|
|
|
|
) {
|
|
|
|
// Convert the value to rgba that el-color-picker can display it correctly
|
|
|
|
const bigint = parseInt(returnValue.slice(1), 16);
|
|
|
|
const h = [];
|
|
|
|
h.push((bigint >> 24) & 255);
|
|
|
|
h.push((bigint >> 16) & 255);
|
|
|
|
h.push((bigint >> 8) & 255);
|
|
|
|
h.push(((255 - bigint) & 255) / 255);
|
|
|
|
|
|
|
|
returnValue = 'rgba(' + h.join() + ')';
|
|
|
|
}
|
2019-06-23 03:35:23 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
if (returnValue !== undefined && returnValue !== null && this.parameter.type === 'string') {
|
2019-06-23 03:35:23 -07:00
|
|
|
const rows = this.getArgument('rows');
|
2022-12-14 01:04:10 -08:00
|
|
|
if (rows === undefined || rows === 1) {
|
|
|
|
returnValue = returnValue.toString().replace(/\n/, '|');
|
2019-06-23 03:35:23 -07:00
|
|
|
}
|
2022-12-14 01:04:10 -08:00
|
|
|
}
|
2019-06-23 03:35:23 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
return returnValue;
|
|
|
|
},
|
|
|
|
getStringInputType() {
|
|
|
|
if (this.getArgument('password') === true) {
|
|
|
|
return 'password';
|
|
|
|
}
|
2022-05-24 02:36:19 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
const rows = this.getArgument('rows');
|
|
|
|
if (rows !== undefined && rows > 1) {
|
|
|
|
return 'textarea';
|
|
|
|
}
|
2022-05-24 02:36:19 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
if (this.parameter.typeOptions && this.parameter.typeOptions.editor === 'code') {
|
|
|
|
return 'textarea';
|
|
|
|
}
|
2019-06-23 03:35:23 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
return 'text';
|
|
|
|
},
|
|
|
|
getIssues(): string[] {
|
|
|
|
if (this.hideIssues === true || this.node === null) {
|
|
|
|
return [];
|
|
|
|
}
|
2022-05-24 02:36:19 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
const newPath = this.shortPath.split('.');
|
|
|
|
newPath.pop();
|
|
|
|
|
|
|
|
const issues = NodeHelpers.getParameterIssues(
|
|
|
|
this.parameter,
|
|
|
|
this.node.parameters,
|
|
|
|
newPath.join('.'),
|
|
|
|
this.node,
|
|
|
|
);
|
|
|
|
|
|
|
|
if (this.parameter.type === 'credentialsSelect' && this.displayValue === '') {
|
|
|
|
issues.parameters = issues.parameters || {};
|
|
|
|
|
|
|
|
const issue = this.$locale.baseText('parameterInput.selectACredentialTypeFromTheDropdown');
|
|
|
|
|
|
|
|
issues.parameters[this.parameter.name] = [issue];
|
|
|
|
} else if (
|
|
|
|
['options', 'multiOptions'].includes(this.parameter.type) &&
|
|
|
|
this.remoteParameterOptionsLoading === false &&
|
|
|
|
this.remoteParameterOptionsLoadingIssues === null &&
|
|
|
|
this.parameterOptions
|
|
|
|
) {
|
|
|
|
// Check if the value resolves to a valid option
|
|
|
|
// Currently it only displays an error in the node itself in
|
|
|
|
// case the value is not valid. The workflow can still be executed
|
|
|
|
// and the error is not displayed on the node in the workflow
|
|
|
|
const validOptions = this.parameterOptions.map(
|
|
|
|
(options) => (options as INodePropertyOptions).value,
|
|
|
|
);
|
|
|
|
|
|
|
|
const checkValues: string[] = [];
|
|
|
|
|
|
|
|
if (!this.skipCheck(this.displayValue)) {
|
|
|
|
if (Array.isArray(this.displayValue)) {
|
|
|
|
checkValues.push.apply(checkValues, this.displayValue);
|
|
|
|
} else {
|
|
|
|
checkValues.push(this.displayValue as string);
|
2019-11-21 15:07:38 -08:00
|
|
|
}
|
2022-12-14 01:04:10 -08:00
|
|
|
}
|
2019-11-21 15:07:38 -08:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
for (const checkValue of checkValues) {
|
|
|
|
if (checkValue === null || !validOptions.includes(checkValue)) {
|
|
|
|
if (issues.parameters === undefined) {
|
|
|
|
issues.parameters = {};
|
|
|
|
}
|
2022-05-24 02:36:19 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
const issue = this.$locale.baseText('parameterInput.theValueIsNotSupported', {
|
|
|
|
interpolate: { checkValue },
|
|
|
|
});
|
2022-05-24 02:36:19 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
issues.parameters[this.parameter.name] = [issue];
|
2019-06-23 03:35:23 -07:00
|
|
|
}
|
|
|
|
}
|
2022-12-14 01:04:10 -08:00
|
|
|
} else if (this.remoteParameterOptionsLoadingIssues !== null) {
|
|
|
|
if (issues.parameters === undefined) {
|
|
|
|
issues.parameters = {};
|
2019-06-23 03:35:23 -07:00
|
|
|
}
|
2022-12-14 01:04:10 -08:00
|
|
|
issues.parameters[this.parameter.name] = [
|
|
|
|
`There was a problem loading the parameter options from server: "${this.remoteParameterOptionsLoadingIssues}"`,
|
|
|
|
];
|
|
|
|
}
|
2019-06-23 03:35:23 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
if (
|
|
|
|
issues !== undefined &&
|
|
|
|
issues.parameters !== undefined &&
|
|
|
|
issues.parameters[this.parameter.name] !== undefined
|
|
|
|
) {
|
|
|
|
return issues.parameters[this.parameter.name];
|
|
|
|
}
|
2022-07-20 04:32:51 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
return [];
|
|
|
|
},
|
|
|
|
isEditor(): boolean {
|
|
|
|
return ['code', 'json'].includes(this.editorType);
|
|
|
|
},
|
|
|
|
editorType(): string {
|
|
|
|
return this.getArgument('editor') as string;
|
|
|
|
},
|
|
|
|
parameterOptions():
|
|
|
|
| Array<INodePropertyOptions | INodeProperties | INodePropertyCollection>
|
|
|
|
| undefined {
|
|
|
|
if (this.hasRemoteMethod === false) {
|
|
|
|
// Options are already given
|
|
|
|
return this.parameter.options;
|
|
|
|
}
|
2021-08-29 04:36:17 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
// Options get loaded from server
|
|
|
|
return this.remoteParameterOptions;
|
|
|
|
},
|
|
|
|
parameterInputClasses() {
|
|
|
|
const classes: { [c: string]: boolean } = {
|
|
|
|
droppable: this.droppable,
|
|
|
|
activeDrop: this.activeDrop,
|
|
|
|
};
|
2022-07-20 04:32:51 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
const rows = this.getArgument('rows');
|
|
|
|
const isTextarea = this.parameter.type === 'string' && rows !== undefined;
|
|
|
|
const isSwitch = this.parameter.type === 'boolean' && !this.isValueExpression;
|
2022-07-20 04:32:51 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
if (!isTextarea && !isSwitch) {
|
|
|
|
classes['parameter-value-container'] = true;
|
|
|
|
}
|
2019-06-23 03:35:23 -07:00
|
|
|
|
2022-12-14 05:43:02 -08:00
|
|
|
if (
|
|
|
|
!this.droppable &&
|
|
|
|
!this.activeDrop &&
|
|
|
|
(this.getIssues.length > 0 || this.errorHighlight) &&
|
|
|
|
!this.isValueExpression
|
|
|
|
) {
|
2022-12-14 01:04:10 -08:00
|
|
|
classes['has-issues'] = true;
|
|
|
|
}
|
2019-06-23 03:35:23 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
return classes;
|
2019-06-23 03:35:23 -07:00
|
|
|
},
|
2022-12-14 01:04:10 -08:00
|
|
|
parameterInputWrapperStyle() {
|
|
|
|
let deductWidth = 0;
|
|
|
|
const styles = {
|
|
|
|
width: '100%',
|
|
|
|
};
|
|
|
|
if (this.parameter.type === 'credentialsSelect' || this.isResourceLocatorParameter) {
|
|
|
|
return styles;
|
|
|
|
}
|
|
|
|
if (this.getIssues.length) {
|
|
|
|
deductWidth += 20;
|
|
|
|
}
|
2022-05-24 02:36:19 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
if (deductWidth !== 0) {
|
|
|
|
styles.width = `calc(100% - ${deductWidth}px)`;
|
|
|
|
}
|
2022-05-24 02:36:19 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
return styles;
|
|
|
|
},
|
|
|
|
hasRemoteMethod(): boolean {
|
|
|
|
return !!this.getArgument('loadOptionsMethod') || !!this.getArgument('loadOptions');
|
|
|
|
},
|
|
|
|
shortPath(): string {
|
|
|
|
const shortPath = this.path.split('.');
|
|
|
|
shortPath.shift();
|
|
|
|
return shortPath.join('.');
|
|
|
|
},
|
|
|
|
workflow(): Workflow {
|
|
|
|
return this.getCurrentWorkflow();
|
|
|
|
},
|
|
|
|
isResourceLocatorParameter(): boolean {
|
|
|
|
return this.parameter.type === 'resourceLocator';
|
|
|
|
},
|
2022-12-15 05:31:06 -08:00
|
|
|
isSecretParameter(): boolean {
|
|
|
|
return this.getArgument('password') === true;
|
|
|
|
},
|
2022-12-14 01:04:10 -08:00
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
isRemoteParameterOption(option: INodePropertyOptions) {
|
|
|
|
return this.remoteParameterOptions.map((o) => o.name).includes(option.name);
|
|
|
|
},
|
|
|
|
credentialSelected(updateInformation: INodeUpdatePropertiesInformation) {
|
|
|
|
// Update the values on the node
|
|
|
|
this.workflowsStore.updateNodeProperties(updateInformation);
|
2022-05-24 02:36:19 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
const node = this.workflowsStore.getNodeByName(updateInformation.name);
|
2021-11-15 02:19:43 -08:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
if (node) {
|
|
|
|
// Update the issues
|
|
|
|
this.updateNodeCredentialIssues(node);
|
|
|
|
}
|
2022-08-01 13:43:50 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
this.$externalHooks().run('nodeSettings.credentialSelected', { updateInformation });
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* Check whether a param value must be skipped when collecting node param issues for validation.
|
|
|
|
*/
|
|
|
|
skipCheck(value: string | number | boolean | null) {
|
|
|
|
return typeof value === 'string' && value.includes(CUSTOM_API_CALL_KEY);
|
|
|
|
},
|
|
|
|
getPlaceholder(): string {
|
|
|
|
return this.isForCredential
|
|
|
|
? this.$locale.credText().placeholder(this.parameter)
|
|
|
|
: this.$locale.nodeText().placeholder(this.parameter, this.path);
|
|
|
|
},
|
|
|
|
getOptionsOptionDisplayName(option: INodePropertyOptions): string {
|
|
|
|
return this.isForCredential
|
|
|
|
? this.$locale.credText().optionsOptionDisplayName(this.parameter, option)
|
|
|
|
: this.$locale.nodeText().optionsOptionDisplayName(this.parameter, option, this.path);
|
|
|
|
},
|
|
|
|
getOptionsOptionDescription(option: INodePropertyOptions): string {
|
|
|
|
return this.isForCredential
|
|
|
|
? this.$locale.credText().optionsOptionDescription(this.parameter, option)
|
|
|
|
: this.$locale.nodeText().optionsOptionDescription(this.parameter, option, this.path);
|
|
|
|
},
|
2019-06-23 03:35:23 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
async loadRemoteParameterOptions() {
|
|
|
|
if (
|
|
|
|
this.node === null ||
|
|
|
|
this.hasRemoteMethod === false ||
|
|
|
|
this.remoteParameterOptionsLoading
|
|
|
|
) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.remoteParameterOptionsLoadingIssues = null;
|
|
|
|
this.remoteParameterOptionsLoading = true;
|
|
|
|
this.remoteParameterOptions.length = 0;
|
|
|
|
|
|
|
|
// Get the resolved parameter values of the current node
|
|
|
|
|
|
|
|
try {
|
|
|
|
const currentNodeParameters = (this.ndvStore.activeNode as INodeUi).parameters;
|
|
|
|
const resolvedNodeParameters = this.resolveParameter(
|
|
|
|
currentNodeParameters,
|
|
|
|
) as INodeParameters;
|
|
|
|
const loadOptionsMethod = this.getArgument('loadOptionsMethod') as string | undefined;
|
|
|
|
const loadOptions = this.getArgument('loadOptions') as ILoadOptions | undefined;
|
|
|
|
|
|
|
|
const options = await this.nodeTypesStore.getNodeParameterOptions({
|
|
|
|
nodeTypeAndVersion: {
|
|
|
|
name: this.node.type,
|
|
|
|
version: this.node.typeVersion,
|
|
|
|
},
|
|
|
|
path: this.path,
|
|
|
|
methodName: loadOptionsMethod,
|
|
|
|
loadOptions,
|
|
|
|
currentNodeParameters: resolvedNodeParameters,
|
|
|
|
credentials: this.node.credentials,
|
|
|
|
});
|
2021-10-18 20:57:49 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
this.remoteParameterOptions.push.apply(this.remoteParameterOptions, options);
|
|
|
|
} catch (error) {
|
|
|
|
this.remoteParameterOptionsLoadingIssues = error.message;
|
|
|
|
}
|
2019-06-23 03:35:23 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
this.remoteParameterOptionsLoading = false;
|
|
|
|
},
|
|
|
|
closeCodeEditDialog() {
|
|
|
|
this.codeEditDialogVisible = false;
|
|
|
|
},
|
|
|
|
closeExpressionEditDialog() {
|
|
|
|
this.expressionEditDialogVisible = false;
|
|
|
|
},
|
|
|
|
trackExpressionEditOpen() {
|
|
|
|
if (!this.node) {
|
|
|
|
return;
|
|
|
|
}
|
2019-06-23 03:35:23 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
if ((this.node.type as string).startsWith('n8n-nodes-base')) {
|
|
|
|
this.$telemetry.track('User opened Expression Editor', {
|
|
|
|
node_type: this.node.type,
|
|
|
|
parameter_name: this.parameter.displayName,
|
|
|
|
parameter_field_type: this.parameter.type,
|
|
|
|
new_expression: !this.isValueExpression,
|
|
|
|
workflow_id: this.workflowsStore.workflowId,
|
|
|
|
session_id: this.ndvStore.sessionId,
|
|
|
|
source: this.eventSource || 'ndv',
|
|
|
|
});
|
|
|
|
}
|
|
|
|
},
|
|
|
|
closeTextEditDialog() {
|
|
|
|
this.textEditDialogVisible = false;
|
|
|
|
},
|
|
|
|
displayEditDialog() {
|
|
|
|
if (this.isEditor) {
|
|
|
|
this.codeEditDialogVisible = true;
|
|
|
|
} else {
|
|
|
|
this.textEditDialogVisible = true;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
getArgument(argumentName: string): string | number | boolean | undefined {
|
|
|
|
if (this.parameter.typeOptions === undefined) {
|
|
|
|
return undefined;
|
|
|
|
}
|
2019-06-23 03:35:23 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
if (this.parameter.typeOptions[argumentName] === undefined) {
|
|
|
|
return undefined;
|
|
|
|
}
|
2019-06-23 03:35:23 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
return this.parameter.typeOptions[argumentName];
|
|
|
|
},
|
|
|
|
expressionUpdated(value: string) {
|
|
|
|
const val: NodeParameterValueType = this.isResourceLocatorParameter
|
|
|
|
? { __rl: true, value, mode: this.value.mode }
|
|
|
|
: value;
|
|
|
|
this.valueChanged(val);
|
|
|
|
},
|
2022-12-14 05:43:02 -08:00
|
|
|
openExpressionEditorModal() {
|
|
|
|
if (!this.isValueExpression) return;
|
|
|
|
|
|
|
|
this.expressionEditDialogVisible = true;
|
|
|
|
this.trackExpressionEditOpen();
|
2022-12-14 01:04:10 -08:00
|
|
|
},
|
|
|
|
onBlur() {
|
|
|
|
this.$emit('blur');
|
2022-12-14 05:43:02 -08:00
|
|
|
this.isFocused = false;
|
2022-12-14 01:04:10 -08:00
|
|
|
},
|
|
|
|
onResourceLocatorDrop(data: string) {
|
|
|
|
this.$emit('drop', data);
|
|
|
|
},
|
|
|
|
setFocus() {
|
|
|
|
if (['json'].includes(this.parameter.type) && this.getArgument('alwaysOpenEditWindow')) {
|
|
|
|
this.displayEditDialog();
|
|
|
|
return;
|
|
|
|
}
|
2021-10-27 12:55:37 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
if (this.node !== null) {
|
|
|
|
// When an event like mouse-click removes the active node while
|
|
|
|
// editing is active it does not know where to save the value to.
|
|
|
|
// For that reason do we save the node-name here. We could probably
|
|
|
|
// also just do that once on load but if Vue decides for some reason to
|
|
|
|
// reuse the input it could have the wrong value so lets set it everytime
|
|
|
|
// just to be sure
|
|
|
|
this.nodeName = this.node.name;
|
|
|
|
}
|
2021-09-11 01:15:36 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
// Set focus on field
|
|
|
|
setTimeout(() => {
|
|
|
|
// @ts-ignore
|
|
|
|
if (this.$refs.inputField && this.$refs.inputField.$el) {
|
|
|
|
// @ts-ignore
|
|
|
|
this.$refs.inputField.focus();
|
2022-12-14 05:43:02 -08:00
|
|
|
this.isFocused = true;
|
2022-05-24 02:36:19 -07:00
|
|
|
}
|
2022-12-14 01:04:10 -08:00
|
|
|
});
|
2022-05-24 02:36:19 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
this.$emit('focus');
|
|
|
|
},
|
|
|
|
isCodeNode(node: INodeUi): boolean {
|
|
|
|
return node.type === CODE_NODE_TYPE;
|
|
|
|
},
|
2023-01-26 01:03:13 -08:00
|
|
|
isHtmlNode(node: INodeUi): boolean {
|
|
|
|
return node.type === HTML_NODE_TYPE;
|
|
|
|
},
|
2022-12-14 01:04:10 -08:00
|
|
|
rgbaToHex(value: string): string | null {
|
|
|
|
// Convert rgba to hex from: https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
|
|
|
|
const valueMatch = (value as string).match(
|
|
|
|
/^rgba\((\d+),\s*(\d+),\s*(\d+),\s*(\d+(\.\d+)?)\)$/,
|
|
|
|
);
|
|
|
|
if (valueMatch === null) {
|
|
|
|
// TODO: Display something if value is not valid
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
const [r, g, b, a] = valueMatch.splice(1, 4).map((v) => Number(v));
|
|
|
|
return (
|
|
|
|
'#' +
|
|
|
|
((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1) +
|
|
|
|
((1 << 8) + Math.floor((1 - a) * 255)).toString(16).slice(1)
|
|
|
|
);
|
|
|
|
},
|
|
|
|
onTextInputChange(value: string) {
|
|
|
|
const parameterData = {
|
|
|
|
node: this.node !== null ? this.node.name : this.nodeName,
|
|
|
|
name: this.path,
|
|
|
|
value,
|
|
|
|
};
|
2019-06-23 03:35:23 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
this.$emit('textInput', parameterData);
|
|
|
|
},
|
|
|
|
valueChangedDebounced(value: NodeParameterValueType | {} | Date) {
|
|
|
|
this.callDebounced('valueChanged', { debounceTime: 100 }, value);
|
|
|
|
},
|
|
|
|
valueChanged(value: NodeParameterValueType | {} | Date) {
|
|
|
|
if (this.parameter.name === 'nodeCredentialType') {
|
|
|
|
this.activeCredentialType = value as string;
|
|
|
|
}
|
2020-11-09 02:26:46 -08:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
if (value instanceof Date) {
|
|
|
|
value = value.toISOString();
|
|
|
|
}
|
2019-06-23 03:35:23 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
if (
|
|
|
|
this.parameter.type === 'color' &&
|
|
|
|
this.getArgument('showAlpha') === true &&
|
|
|
|
value !== null &&
|
|
|
|
value !== undefined &&
|
|
|
|
value.toString().charAt(0) !== '#'
|
|
|
|
) {
|
|
|
|
const newValue = this.rgbaToHex(value as string);
|
|
|
|
if (newValue !== null) {
|
|
|
|
this.tempValue = newValue;
|
|
|
|
value = newValue;
|
2022-07-09 23:53:04 -07:00
|
|
|
}
|
2022-12-14 01:04:10 -08:00
|
|
|
}
|
2022-07-20 04:32:51 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
const parameterData = {
|
|
|
|
node: this.node !== null ? this.node.name : this.nodeName,
|
|
|
|
name: this.path,
|
|
|
|
value,
|
|
|
|
};
|
2021-08-29 04:36:17 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
this.$emit('valueChanged', parameterData);
|
2022-04-14 22:35:51 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
if (this.parameter.name === 'operation' || this.parameter.name === 'mode') {
|
|
|
|
this.$telemetry.track('User set node operation or mode', {
|
|
|
|
workflow_id: this.workflowsStore.workflowId,
|
|
|
|
node_type: this.node && this.node.type,
|
|
|
|
resource: this.node && this.node.parameters.resource,
|
|
|
|
is_custom: value === CUSTOM_API_CALL_KEY,
|
|
|
|
session_id: this.ndvStore.sessionId,
|
|
|
|
parameter: this.parameter.name,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
},
|
|
|
|
optionSelected(command: string) {
|
|
|
|
const prevValue = this.value;
|
|
|
|
|
|
|
|
if (command === 'resetValue') {
|
|
|
|
this.valueChanged(this.parameter.default);
|
|
|
|
} else if (command === 'addExpression') {
|
|
|
|
if (this.isResourceLocatorParameter) {
|
|
|
|
if (isResourceLocatorValue(this.value)) {
|
|
|
|
this.valueChanged({ __rl: true, value: `=${this.value.value}`, mode: this.value.mode });
|
|
|
|
} else {
|
|
|
|
this.valueChanged({ __rl: true, value: `=${this.value}`, mode: '' });
|
2022-04-14 22:35:51 -07:00
|
|
|
}
|
2022-12-14 05:43:02 -08:00
|
|
|
} else if (
|
|
|
|
this.parameter.type === 'number' &&
|
|
|
|
(!this.value || this.value === '[Object: null]')
|
|
|
|
) {
|
|
|
|
this.valueChanged('={{ 0 }}');
|
2022-12-14 01:04:10 -08:00
|
|
|
} else if (this.parameter.type === 'number' || this.parameter.type === 'boolean') {
|
2022-12-14 05:43:02 -08:00
|
|
|
this.valueChanged(`={{ ${this.value} }}`);
|
2022-12-14 01:04:10 -08:00
|
|
|
} else {
|
|
|
|
this.valueChanged(`=${this.value}`);
|
|
|
|
}
|
2022-04-14 22:35:51 -07:00
|
|
|
|
2022-12-14 05:43:02 -08:00
|
|
|
this.setFocus();
|
2022-12-14 01:04:10 -08:00
|
|
|
} else if (command === 'removeExpression') {
|
|
|
|
let value: NodeParameterValueType = this.expressionEvaluated;
|
|
|
|
|
2022-12-14 05:43:02 -08:00
|
|
|
this.isFocused = false;
|
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
if (this.parameter.type === 'multiOptions' && typeof value === 'string') {
|
|
|
|
value = (value || '')
|
|
|
|
.split(',')
|
|
|
|
.filter((value) =>
|
|
|
|
(this.parameterOptions || []).find(
|
|
|
|
(option) => (option as INodePropertyOptions).value === value,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
2022-11-15 04:55:53 -08:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
if (this.isResourceLocatorParameter && isResourceLocatorValue(this.value)) {
|
|
|
|
this.valueChanged({ __rl: true, value, mode: this.value.mode });
|
|
|
|
} else {
|
|
|
|
let newValue = typeof value !== 'undefined' ? value : null;
|
2022-11-15 04:55:53 -08:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
if (this.parameter.type === 'string') {
|
|
|
|
// Strip the '=' from the beginning
|
|
|
|
newValue = this.value ? this.value.toString().substring(1) : null;
|
2022-09-21 06:44:45 -07:00
|
|
|
}
|
2022-07-20 04:32:51 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
this.valueChanged(newValue);
|
2022-07-20 04:32:51 -07:00
|
|
|
}
|
2022-12-14 01:04:10 -08:00
|
|
|
} else if (command === 'refreshOptions') {
|
|
|
|
if (this.isResourceLocatorParameter) {
|
|
|
|
const resourceLocator = this.$refs.resourceLocator;
|
|
|
|
if (resourceLocator) {
|
|
|
|
(resourceLocator as Vue).$emit('refreshList');
|
|
|
|
}
|
2022-08-19 06:35:39 -07:00
|
|
|
}
|
2022-12-14 01:04:10 -08:00
|
|
|
this.loadRemoteParameterOptions();
|
2023-01-26 01:03:13 -08:00
|
|
|
} else if (command === 'formatHtml') {
|
|
|
|
htmlEditorEventBus.$emit('format-html');
|
2019-06-23 03:35:23 -07:00
|
|
|
}
|
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
if (this.node && (command === 'addExpression' || command === 'removeExpression')) {
|
|
|
|
const telemetryPayload = {
|
|
|
|
node_type: this.node.type,
|
|
|
|
parameter: this.path,
|
|
|
|
old_mode: command === 'addExpression' ? 'fixed' : 'expression',
|
|
|
|
new_mode: command === 'removeExpression' ? 'fixed' : 'expression',
|
|
|
|
was_parameter_empty: prevValue === '' || prevValue === undefined,
|
|
|
|
had_mapping: hasExpressionMapping(prevValue),
|
|
|
|
had_parameter: typeof prevValue === 'string' && prevValue.includes('$parameter'),
|
|
|
|
};
|
|
|
|
this.$telemetry.track('User switched parameter mode', telemetryPayload);
|
|
|
|
this.$externalHooks().run('parameterInput.modeSwitch', telemetryPayload);
|
2022-05-24 02:36:19 -07:00
|
|
|
}
|
2022-12-14 01:04:10 -08:00
|
|
|
},
|
|
|
|
},
|
|
|
|
updated() {
|
|
|
|
this.$nextTick(() => {
|
|
|
|
const remoteParameterOptions = this.$el.querySelectorAll('.remote-parameter-option');
|
2022-05-24 02:36:19 -07:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
if (remoteParameterOptions.length > 0) {
|
|
|
|
this.$externalHooks().run('parameterInput.updated', { remoteParameterOptions });
|
2020-11-09 02:26:46 -08:00
|
|
|
}
|
2022-12-14 01:04:10 -08:00
|
|
|
});
|
|
|
|
},
|
|
|
|
mounted() {
|
|
|
|
this.$on('optionSelected', this.optionSelected);
|
|
|
|
|
|
|
|
this.tempValue = this.displayValue as string;
|
|
|
|
if (this.node !== null) {
|
|
|
|
this.nodeName = this.node.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.node && this.node.parameters.authentication === 'predefinedCredentialType') {
|
|
|
|
this.activeCredentialType = this.node.parameters.nodeCredentialType as string;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (
|
|
|
|
this.parameter.type === 'color' &&
|
|
|
|
this.getArgument('showAlpha') === true &&
|
|
|
|
this.displayValue !== null &&
|
|
|
|
this.displayValue.toString().charAt(0) !== '#'
|
|
|
|
) {
|
|
|
|
const newValue = this.rgbaToHex(this.displayValue as string);
|
|
|
|
if (newValue !== null) {
|
|
|
|
this.tempValue = newValue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.hasRemoteMethod === true && this.node !== null) {
|
|
|
|
// Make sure to load the parameter options
|
|
|
|
// directly and whenever the credentials change
|
|
|
|
this.$watch(
|
|
|
|
() => this.node!.credentials,
|
|
|
|
() => {
|
2019-06-23 03:35:23 -07:00
|
|
|
this.loadRemoteParameterOptions();
|
2022-12-14 01:04:10 -08:00
|
|
|
},
|
|
|
|
{ deep: true, immediate: true },
|
|
|
|
);
|
|
|
|
|
|
|
|
// Reload function on change element from
|
|
|
|
// displayOptions.typeOptions.reloadOnChange parameters
|
|
|
|
if (this.parameter.typeOptions && this.parameter.typeOptions.reloadOnChange) {
|
|
|
|
// Get all parameter in reloadOnChange property
|
|
|
|
// This reload when parameters in reloadOnChange is updated
|
|
|
|
const parametersOnChange: string[] = this.parameter.typeOptions.reloadOnChange;
|
|
|
|
for (let i = 0; i < parametersOnChange.length; i++) {
|
|
|
|
const parameter = parametersOnChange[i] as string;
|
|
|
|
if (parameter in this.node.parameters) {
|
|
|
|
this.$watch(
|
|
|
|
() => {
|
2019-10-20 11:55:49 -07:00
|
|
|
if (this.node && this.node.parameters && this.node.parameters[parameter]) {
|
|
|
|
return this.node.parameters![parameter];
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
2022-12-14 01:04:10 -08:00
|
|
|
},
|
|
|
|
() => {
|
2019-10-20 11:55:49 -07:00
|
|
|
this.loadRemoteParameterOptions();
|
2022-12-14 01:04:10 -08:00
|
|
|
},
|
|
|
|
{ deep: true, immediate: true },
|
|
|
|
);
|
2019-10-20 11:55:49 -07:00
|
|
|
}
|
|
|
|
}
|
2019-06-23 03:35:23 -07:00
|
|
|
}
|
2022-12-14 01:04:10 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
this.$externalHooks().run('parameterInput.mount', {
|
|
|
|
parameter: this.parameter,
|
|
|
|
inputFieldRef: this.$refs['inputField'],
|
|
|
|
});
|
|
|
|
},
|
|
|
|
});
|
2019-06-23 03:35:23 -07:00
|
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
2021-10-27 12:55:37 -07:00
|
|
|
.code-edit {
|
|
|
|
font-size: var(--font-size-xs);
|
|
|
|
}
|
|
|
|
|
2021-08-29 04:36:17 -07:00
|
|
|
.switch-input {
|
2022-08-24 05:47:42 -07:00
|
|
|
margin: var(--spacing-5xs) 0 var(--spacing-2xs) 0;
|
2021-08-29 04:36:17 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
.parameter-value-container {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
}
|
|
|
|
|
|
|
|
.parameter-actions {
|
|
|
|
display: inline-flex;
|
|
|
|
align-items: center;
|
|
|
|
}
|
|
|
|
|
2019-06-23 03:35:23 -07:00
|
|
|
.parameter-input {
|
|
|
|
display: inline-block;
|
|
|
|
}
|
|
|
|
|
2021-08-29 04:36:17 -07:00
|
|
|
::v-deep .color-input {
|
|
|
|
display: flex;
|
2019-06-23 03:35:23 -07:00
|
|
|
|
2021-08-29 04:36:17 -07:00
|
|
|
.el-color-picker__trigger {
|
|
|
|
border: none;
|
2019-06-23 03:35:23 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
</style>
|
|
|
|
|
|
|
|
<style lang="scss">
|
|
|
|
.ql-editor {
|
|
|
|
padding: 6px;
|
|
|
|
line-height: 26px;
|
2021-08-29 04:36:17 -07:00
|
|
|
background-color: #f0f0f0;
|
2019-06-23 03:35:23 -07:00
|
|
|
}
|
|
|
|
|
2022-07-20 04:32:51 -07:00
|
|
|
.droppable {
|
2022-12-06 03:50:06 -08:00
|
|
|
--input-border-color: var(--color-secondary);
|
2021-08-29 04:36:17 -07:00
|
|
|
--input-border-style: dashed;
|
2022-12-06 03:50:06 -08:00
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
textarea,
|
2022-12-14 05:43:02 -08:00
|
|
|
input,
|
|
|
|
.cm-editor {
|
2022-12-06 03:50:06 -08:00
|
|
|
border-width: 1.5px;
|
|
|
|
}
|
2022-07-20 04:32:51 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
.activeDrop {
|
|
|
|
--input-border-color: var(--color-success);
|
2022-12-06 03:50:06 -08:00
|
|
|
--input-background-color: var(--color-foreground-xlight);
|
2022-07-20 04:32:51 -07:00
|
|
|
--input-border-style: solid;
|
|
|
|
|
2022-12-14 01:04:10 -08:00
|
|
|
textarea,
|
|
|
|
input {
|
2022-07-20 04:32:51 -07:00
|
|
|
cursor: grabbing !important;
|
2022-12-06 03:50:06 -08:00
|
|
|
border-width: 1px;
|
2022-07-20 04:32:51 -07:00
|
|
|
}
|
2019-06-23 03:35:23 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
.has-issues {
|
2021-08-29 04:36:17 -07:00
|
|
|
--input-border-color: var(--color-danger);
|
2019-06-23 03:35:23 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
.el-dropdown {
|
2022-07-26 03:45:55 -07:00
|
|
|
color: var(--color-text-light);
|
2019-06-23 03:35:23 -07:00
|
|
|
}
|
|
|
|
|
2021-08-29 04:36:17 -07:00
|
|
|
.list-option {
|
|
|
|
margin: 6px 0;
|
2019-06-23 03:35:23 -07:00
|
|
|
white-space: normal;
|
2021-09-22 02:02:38 -07:00
|
|
|
padding-right: 20px;
|
2021-08-29 04:36:17 -07:00
|
|
|
|
|
|
|
.option-headline {
|
|
|
|
font-weight: var(--font-weight-bold);
|
|
|
|
line-height: var(--font-line-height-regular);
|
|
|
|
overflow-wrap: break-word;
|
|
|
|
}
|
|
|
|
|
|
|
|
.option-description {
|
|
|
|
margin-top: 2px;
|
|
|
|
font-size: var(--font-size-2xs);
|
|
|
|
font-weight: var(--font-weight-regular);
|
|
|
|
line-height: var(--font-line-height-xloose);
|
2022-09-23 07:14:28 -07:00
|
|
|
color: $custom-font-very-light;
|
2021-08-29 04:36:17 -07:00
|
|
|
}
|
2019-06-23 03:35:23 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
.edit-window-button {
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
|
|
|
|
.parameter-input:hover .edit-window-button {
|
|
|
|
display: inline;
|
|
|
|
}
|
|
|
|
|
2021-08-29 04:36:17 -07:00
|
|
|
.expand-input-icon-container {
|
|
|
|
display: flex;
|
|
|
|
height: 100%;
|
|
|
|
align-items: center;
|
|
|
|
}
|
2022-12-14 05:43:02 -08:00
|
|
|
|
|
|
|
.input-with-opener > .el-input__suffix {
|
|
|
|
right: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
.textarea-modal-opener {
|
|
|
|
position: absolute;
|
|
|
|
right: 0;
|
|
|
|
bottom: 0;
|
|
|
|
background-color: white;
|
|
|
|
padding: 3px;
|
|
|
|
line-height: 9px;
|
|
|
|
border: var(--border-base);
|
|
|
|
border-top-left-radius: var(--border-radius-base);
|
|
|
|
border-bottom-right-radius: var(--border-radius-base);
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
|
|
svg {
|
|
|
|
width: 9px !important;
|
|
|
|
height: 9px;
|
|
|
|
transform: rotate(270deg);
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
color: var(--color-primary);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.focused {
|
|
|
|
border-color: var(--color-secondary);
|
|
|
|
}
|
|
|
|
|
|
|
|
.invalid {
|
|
|
|
border-color: var(--color-danger);
|
|
|
|
}
|
2019-06-23 03:35:23 -07:00
|
|
|
</style>
|