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-09-22 10:04:26 -07: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'"
@ closeDialog = "closeExpressionEditDialog"
@ valueChanged = "expressionUpdated"
> < / e x p r e s s i o n - e d i t >
< div
class = "parameter-input ignore-key-press"
: style = "parameterInputWrapperStyle"
@ click = "openExpressionEdit"
>
2022-09-21 06:44:45 -07:00
< resource -locator
v - if = "isResourceLocatorParameter"
ref = "resourceLocator"
: parameter = "parameter"
: value = "value"
: displayTitle = "displayTitle"
: expressionDisplayValue = "expressionDisplayValue"
: isValueExpression = "isValueExpression"
: isReadOnly = "isReadOnly"
: parameterIssues = "getIssues"
: droppable = "droppable"
: node = "node"
: path = "path"
@ input = "valueChanged"
@ focus = "setFocus"
@ blur = "onBlur"
@ drop = "onResourceLocatorDrop"
/ >
2022-07-20 04:32:51 -07:00
< n8n -input
2022-09-21 06:44:45 -07:00
v - else - if = "isValueExpression || droppable || forceShowExpression"
2022-07-20 04:32:51 -07:00
: size = "inputSize"
: type = "getStringInputType"
: rows = "getArgument('rows')"
: value = "activeDrop || forceShowExpression? '': expressionDisplayValue"
: title = "displayTitle"
@ keydown . stop
/ >
< 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"
> < / c o d e - e d i t >
< text -edit
: dialogVisible = "textEditDialogVisible"
: value = "value"
: parameter = "parameter"
: path = "path"
@ closeDialog = "closeTextEditDialog"
@ valueChanged = "expressionUpdated"
> < / t e x t - e d i t >
2022-09-21 01:20:29 -07:00
< div v-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"
> < / p r i s m - e d i t o r >
< / div >
< n8n -input
v - else
v - model = "tempValue"
ref = "inputField"
: 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()"
>
< div slot = "suffix" class = "expand-input-icon-container" >
< font -awesome -icon
v - if = "!isReadOnly"
2022-09-21 06:44:45 -07:00
icon = "expand-alt"
2022-07-20 04:32:51 -07:00
class = "edit-window-button clickable"
: title = "$locale.baseText('parameterInput.openEditWindow')"
@ click = "displayEditDialog()"
/ >
< / div >
< / n 8 n - i n p u t >
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
v - else - if = "
parameter . type === 'credentialsSelect' || parameter . name === 'genericAuthType'
"
ref = "inputField"
: parameter = "parameter"
: node = "node"
: activeCredentialType = "activeCredentialType"
: inputSize = "inputSize"
: displayValue = "displayValue"
: isReadOnly = "isReadOnly"
: displayTitle = "displayTitle"
@ credentialSelected = "credentialSelected"
@ valueChanged = "valueChanged"
@ setFocus = "setFocus"
@ onBlur = "onBlur"
>
< template v -slot : issues -and -options >
< parameter -issues :issues ="getIssues" / >
< / template >
< / c r e d e n t i a l s - s e l e c t >
< 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 >
< / n 8 n - o p t i o n >
< / n 8 n - s e l e c t >
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
< / n 8 n - o p t i o n >
< / n 8 n - s e l e c t >
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-09-21 06:44:45 -07:00
< parameter -issues v -if = " parameter.type ! = = ' credentialsSelect ' & & ! isResourceLocatorParameter " :issues ="getIssues" / >
2019-06-23 03:35:23 -07:00
< / div >
< / template >
< script lang = "ts" >
2020-01-04 20:28:09 -08:00
import { get } from 'lodash' ;
2019-06-23 03:35:23 -07:00
import {
INodeUi ,
2022-05-24 02:36:19 -07:00
INodeUpdatePropertiesInformation ,
2019-06-23 03:35:23 -07:00
} from '@/Interface' ;
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-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' ;
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' ;
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' ;
2021-08-13 03:01:12 -07:00
import { externalHooks } from '@/components/mixins/externalHooks' ;
2019-06-23 03:35:23 -07:00
import { nodeHelpers } from '@/components/mixins/nodeHelpers' ;
import { showMessage } from '@/components/mixins/showMessage' ;
import { workflowHelpers } from '@/components/mixins/workflowHelpers' ;
import mixins from 'vue-typed-mixins' ;
2022-05-24 02:36:19 -07:00
import { CUSTOM _API _CALL _KEY } from '@/constants' ;
import { mapGetters } from 'vuex' ;
2022-09-21 06:44:45 -07:00
import { hasExpressionMapping , isValueExpression } from './helpers' ;
import { isResourceLocatorValue } from '@/typeGuards' ;
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 ,
)
. extend ( {
2022-09-21 06:44:45 -07:00
name : 'parameter-input' ,
2019-06-23 03:35:23 -07:00
components : {
2019-09-04 09:22:06 -07:00
CodeEdit ,
2019-06-23 03:35:23 -07:00
ExpressionEdit ,
2022-05-24 02:36:19 -07:00
NodeCredentials ,
CredentialsSelect ,
2019-09-04 09:22:06 -07:00
PrismEditor ,
2022-05-24 02:36:19 -07:00
ScopesNotice ,
ParameterOptions ,
ParameterIssues ,
2022-09-21 06:44:45 -07:00
ResourceLocator ,
2019-06-23 03:35:23 -07:00
TextEdit ,
} ,
props : [
2021-09-11 01:15:36 -07:00
'inputSize' ,
'isReadOnly' ,
'documentationUrl' ,
2019-06-23 03:35:23 -07:00
'parameter' , // NodeProperties
'path' , // string
'value' ,
2021-09-11 01:15:36 -07:00
'hideIssues' , // boolean
'errorHighlight' ,
2021-11-15 02:19:43 -08:00
'isForCredential' , // boolean
2022-05-23 08:56:15 -07:00
'eventSource' , // string
2022-07-20 04:32:51 -07:00
'activeDrop' ,
'droppable' ,
'forceShowExpression' ,
2019-06-23 03:35:23 -07:00
] ,
data ( ) {
return {
2019-09-04 09:22:06 -07:00
codeEditDialogVisible : false ,
2019-06-23 03:35:23 -07:00
nodeName : '' ,
expressionAddOperation : 'set' as 'add' | 'set' ,
expressionEditDialogVisible : false ,
remoteParameterOptions : [ ] as INodePropertyOptions [ ] ,
remoteParameterOptionsLoading : false ,
remoteParameterOptionsLoadingIssues : null as string | null ,
textEditDialogVisible : false ,
2019-12-29 21:04:51 -08:00
tempValue : '' , // el-date-picker and el-input does not seem to work without v-model so add one
2022-05-24 02:36:19 -07:00
CUSTOM _API _CALL _KEY ,
activeCredentialType : '' ,
2019-06-23 03:35:23 -07:00
dateTimePickerOptions : {
shortcuts : [
{
2021-11-15 02:19:43 -08:00
text : 'Today' , // TODO
2019-06-23 03:35:23 -07:00
// tslint:disable-next-line:no-any
onClick ( picker : any ) {
picker . $emit ( 'pick' , new Date ( ) ) ;
} ,
} ,
{
2021-11-15 02:19:43 -08:00
text : 'Yesterday' , // TODO
2019-06-23 03:35:23 -07:00
// tslint:disable-next-line:no-any
onClick ( picker : any ) {
const date = new Date ( ) ;
date . setTime ( date . getTime ( ) - 3600 * 1000 * 24 ) ;
picker . $emit ( 'pick' , date ) ;
} ,
} ,
{
2021-11-15 02:19:43 -08:00
text : 'A week ago' , // TODO
2019-06-23 03:35:23 -07:00
// tslint:disable-next-line:no-any
onClick ( picker : any ) {
const date = new Date ( ) ;
date . setTime ( date . getTime ( ) - 3600 * 1000 * 24 * 7 ) ;
picker . $emit ( 'pick' , date ) ;
} ,
} ,
] ,
} ,
} ;
} ,
watch : {
2020-01-04 20:28:09 -08:00
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
value ( ) {
2020-11-09 02:26:46 -08:00
if ( this . parameter . type === 'color' && this . getArgument ( 'showAlpha' ) === true ) {
// Do not set for color with alpha else wrong value gets displayed in field
return ;
}
2019-06-23 03:35:23 -07:00
this . tempValue = this . displayValue as string ;
} ,
} ,
computed : {
2022-05-24 02:36:19 -07:00
... mapGetters ( 'credentials' , [ 'allCredentialTypes' ] ) ,
2022-09-21 06:44:45 -07:00
isValueExpression ( ) : boolean {
return isValueExpression ( this . parameter , this . value ) ;
} ,
:sparkles: Add Templates (#2720)
* Templates Bugs / Fixed Various Bugs / Multiply Api Request, Carousel Gradient, Core Nodes Filters ...
* Updated MainSidebar Paddings
* N8N-Templates Bugfixing - Remove Unnecesairy Icon (Shape), Refatctor infiniteScrollEnabled Prop + updated infiniterScroll functinality
* N8N-2853 Fixed Carousel Arrows Bug after Cleaning the SearchBar
* fix telemetry init
* fix search tracking issues
* N8N-2853 Created FilterTemplateNode Constant Array, Filter PlayButton and WebhookRespond from Nodes, Added Box for showing more nodes inside TemplateList, Updated NewWorkflowButton to primary, Fixed Markdown issue with Code
* N8N-2853 Removed Placeholder if Workflows Or Collections are not found, Updated the Logic
* fix telemetry events
* clean up session id
* update user inserted event
* N8N-2853 Fixed Categories to Moving if the names are long
* Add todos
* Update Routes on loading
* fix spacing
* Update Border Color
* Update Border Readius
* fix filter fn
* fix constant, console error
* N8N-2853 PR Fixes, Refactoring, Removing unnecesairy code ..
* N8N-2853 PR Fixes - Editor-ui Fixes, Refactoring, Removing Dead Code ...
* N8N-2853 Refactor Card to LongCard
* clean up spacing, replace css var
* clean up spacing
* set categories as optional in node
* replace vars
* refactor store
* remove unnesssary import
* fix error
* fix templates view to start
* add to cache
* fix coll view data
* fix categories
* fix category event
* fix collections carousel
* fix initial load and search
* fix infinite load
* fix query param
* fix scrolling issues
* fix scroll to top
* fix search
* fix collections search
* fix navigation bug
* rename view
* update package lock
* rename workflow view
* rename coll view
* update routes
* add wrapper component
* set session id
* fix search tracking
* fix session tracking
* remove deleted mutation
* remove check for unsupported nodes
* refactor filters
* lazy load template
* clean up types
* refactor infinte scroll
* fix end of search
* Fix spacing
* fix coll loading
* fix types
* fix coll view list
* fix navigation
* rename types
* rename state
* fix search responsiveness
* fix coll view spacing
* fix search view spacing
* clean up views
* set background color
* center page not vert
* fix workflow view
* remove import
* fix background color
* fix background
* clean props
* clean up imports
* refactor button
* update background color
* fix spacing issue
* rename event
* update telemetry event
* update endpoints, add loading view, check for endpoint health
* remove conolse log
* N8N-2853 Fixed Menu Items Padding
* replace endpoints
* fix type issues
* fix categories
* N8N-2853 Fixed ParameterInput Placeholder after ElementUI Upgrade
* update createdAt
* :zap: Fix placeholder in creds config modal
* :pencil2: Adjust docstring to `credText` placeholder version
* N8N-2853 Optimized
* N8N-2853 Optimized code
* :zap: Add deployment type to FE settings
* :zap: Add deployment type to interfaces
* N8N-2853 Removed Animated prop from components
* :zap: Add deployment type to store module
* :sparkles: Create hiring banner
* :zap: Display hiring banner
* :rewind: Undo unrelated change
* N8N-2853 Refactor TemplateFilters
* :zap: Fix indentation
* N8N-2853 Reorder items / TemplateList
* :shirt: Fix lint
* N8N-2853 Refactor TemplateFilters Component
* N8N-2853 Reorder TemplateList
* refactor template card
* update timeout
* fix removelistener
* fix spacing
* split enabled from offline
* add spacing to go back
* N8N-2853 Fixed Screens for Tablet & Mobile
* N8N-2853 Update Stores Order
* remove image componet
* remove placeholder changes
* N8N-2853 Fixed Chinnese Placeholders for El Select Component that comes from the Library Upgrade
* N8N-2853 Fixed Vue Agile Console Warnings
* N8N-2853 Update Collection Route
* :pencil2: Update jobs URL
* :truck: Move logging to root component
* :zap: Refactor `deploymentType` to `isInternalUser`
* :zap: Improve syntax
* fix cut bug in readonly view
* N8N-3012 Fixed Details section in templates with lots of description, Fixed Mardown Block with overflox-x
* N8N-3012 Increased Font-size, Spacing and Line-height of the Categories Items
* N8N-3012 Fixed Vue-agile client width error on resize
* only delay redirect for root path
* N8N-3012 Fixed Carousel Arrows that Disappear
* N8N-3012 Make Loading Screen same color as Templates
* N8N-3012 Markdown renders inline block as block code
* add offline warning
* hide log from workflow iframe
* update text
* make search button larger
* N8N-3012 Categories / Tags extended all the way in details section
* load data in cred modals
* remove deleted message
* add external hook
* remove import
* update env variable description
* fix markdown width issue
* disable telemetry for demo, add session id to template pages
* fix telemetery bugs
* N8N-3012 Not found Collections/Wokrkflow
* N8N-3012 Checkboxes change order when categories are changed
* N8N-3012 Refactor SortedCategories inside TemplateFilters component
* fix firefox bug
* add telemetry requirements
* add error check
* N8N-3012 Update GoBackButton to check if Route History is present
* N8N-3012 Fixed WF Nodes Icons
* hide workflow screenshots
* remove unnessary mixins
* rename prop
* fix design a bit
* rename data
* clear workspace on destroy
* fix copy paste bug
* fix disabled state
* N8N-3012 Fixed Saving/Leave without saving Modal
* fix telemetry issue
* fix telemetry issues, error bug
* fix error notification
* disable workflow menu items on templates
* fix i18n elementui issue
* Remove Emit - NodeType from HoverableNodeIcon component
* TechnicalFixes: NavigateTo passed down as function should be helper
* TechnicalFixes: Update NavigateTo function
* TechnicalFixes: Add FilterCoreNodes directly as function
* check for empty connecitions
* fix titles
* respect new lines
* increase categories to be sliced
* rename prop
* onUseWorkflow
* refactor click event
* fix bug, refactor
* fix loading story
* add default
* fix styles at right level of abstraction
* add wrapper with width
* remove loading blocks component
* add story
* rename prop
* fix spacing
* refactor tag, add story
* move margin to container
* fix tag redirect, remove unnessary check
* make version optional
* rename view
* move from workflows to templates store
* remove unnessary change
* remove unnessary css
* rename component
* refactor collection card
* add boolean to prevent shrink
* clean up carousel
* fix redirection bug on save
* remove listeners to fix multiple listeners bug
* remove unnessary types
* clean up boolean set
* fix node select bug
* rename component
* remove unnessary class
* fix redirection bug
* remove unnessary error
* fix typo
* fix blockquotes, pre
* refactor markdown rendering
* remove console log
* escape markdown
* fix safari bug
* load active workflows to fix modal bug
* :arrow_up: Update package-lock.json file
* :zap: Add n8n version as header
Co-authored-by: Mutasem Aldmour <4711238+mutdmour@users.noreply.github.com>
Co-authored-by: Mutasem <mutdmour@gmail.com>
Co-authored-by: Iván Ovejero <ivov.src@gmail.com>
Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
2022-02-28 01:57:44 -08:00
areExpressionsDisabled ( ) : boolean {
return this . $store . getters [ 'ui/areExpressionsDisabled' ] ;
} ,
2021-12-23 02:41:46 -08:00
codeAutocomplete ( ) : string | undefined {
return this . getArgument ( 'codeAutocomplete' ) as string | undefined ;
} ,
2020-01-04 20:28:09 -08:00
dependentParametersValues ( ) : string | null {
const loadOptionsDependsOn = this . getArgument ( 'loadOptionsDependsOn' ) as string [ ] | undefined ;
if ( loadOptionsDependsOn === undefined ) {
return null ;
}
// Get the resolved parameter values of the current node
const currentNodeParameters = this . $store . getters . activeNode . parameters ;
2022-06-03 08:25:07 -07:00
try {
const resolvedNodeParameters = this . resolveParameter ( currentNodeParameters ) ;
2020-01-04 20:28:09 -08:00
2022-06-03 08:25:07 -07:00
const returnValues : string [ ] = [ ] ;
for ( const parameterPath of loadOptionsDependsOn ) {
returnValues . push ( get ( resolvedNodeParameters , parameterPath ) as string ) ;
}
2020-01-04 20:28:09 -08:00
2022-06-03 08:25:07 -07:00
return returnValues . join ( '|' ) ;
} catch ( error ) {
return null ;
}
2020-01-04 20:28:09 -08:00
} ,
2019-06-23 03:35:23 -07:00
node ( ) : INodeUi | null {
return this . $store . getters . activeNode ;
} ,
displayTitle ( ) : string {
2021-11-15 02:19:43 -08:00
const interpolation = { interpolate : { shortPath : this . shortPath } } ;
if ( this . getIssues . length && this . isValueExpression ) {
2021-12-15 04:16:53 -08:00
return this . $locale . baseText (
2021-11-15 02:19:43 -08:00
'parameterInput.parameterHasIssuesAndExpression' ,
interpolation ,
) ;
} else if ( this . getIssues . length && ! this . isValueExpression ) {
2021-12-15 04:16:53 -08:00
return this . $locale . baseText (
2021-11-15 02:19:43 -08:00
'parameterInput.parameterHasIssues' ,
interpolation ,
) ;
} else if ( ! this . getIssues . length && this . isValueExpression ) {
2021-12-15 04:16:53 -08:00
return this . $locale . baseText (
2021-11-15 02:19:43 -08:00
'parameterInput.parameterHasExpression' ,
interpolation ,
) ;
2019-06-23 03:35:23 -07:00
}
2021-12-15 04:16:53 -08:00
return this . $locale . baseText ( 'parameterInput.parameter' , interpolation ) ;
2019-06-23 03:35:23 -07:00
} ,
displayValue ( ) : string | number | boolean | null {
2020-04-06 01:15:46 -07:00
if ( this . remoteParameterOptionsLoading === true ) {
2019-06-23 03:35:23 -07:00
// 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
2021-12-15 04:16:53 -08:00
return this . $locale . baseText ( 'parameterInput.loadingOptions' ) ;
2019-06-23 03:35:23 -07:00
}
let returnValue ;
if ( this . isValueExpression === false ) {
2022-09-21 06:44:45 -07:00
returnValue = this . isResourceLocatorParameter ? ( this . value ? this . value . value : '' ) : this . value ;
2019-06-23 03:35:23 -07:00
} else {
returnValue = this . expressionValueComputed ;
}
2022-05-24 02:36:19 -07:00
if ( this . parameter . type === 'credentialsSelect' ) {
const credType = this . $store . getters [ 'credentials/getCredentialTypeByName' ] ( this . value ) ;
if ( credType ) {
returnValue = credType . displayName ;
}
}
2020-11-09 02:26:46 -08:00
if ( 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 ( ) + ')' ;
}
2020-02-07 17:06:36 -08:00
if ( returnValue !== undefined && returnValue !== null && this . parameter . type === 'string' ) {
2019-06-23 03:35:23 -07:00
const rows = this . getArgument ( 'rows' ) ;
if ( rows === undefined || rows === 1 ) {
returnValue = returnValue . toString ( ) . replace ( /\n/ , '|' ) ;
}
}
return returnValue ;
} ,
2021-08-29 04:36:17 -07:00
expressionDisplayValue ( ) : string {
const value = this . displayValue ;
// address type errors for text input
if ( typeof value === 'number' || typeof value === 'boolean' ) {
return JSON . stringify ( value ) ;
}
if ( value === null ) {
return '' ;
}
return value ;
} ,
2022-04-14 22:35:51 -07:00
expressionValueComputed ( ) : NodeParameterValue | string [ ] | null {
:sparkles: Add Templates (#2720)
* Templates Bugs / Fixed Various Bugs / Multiply Api Request, Carousel Gradient, Core Nodes Filters ...
* Updated MainSidebar Paddings
* N8N-Templates Bugfixing - Remove Unnecesairy Icon (Shape), Refatctor infiniteScrollEnabled Prop + updated infiniterScroll functinality
* N8N-2853 Fixed Carousel Arrows Bug after Cleaning the SearchBar
* fix telemetry init
* fix search tracking issues
* N8N-2853 Created FilterTemplateNode Constant Array, Filter PlayButton and WebhookRespond from Nodes, Added Box for showing more nodes inside TemplateList, Updated NewWorkflowButton to primary, Fixed Markdown issue with Code
* N8N-2853 Removed Placeholder if Workflows Or Collections are not found, Updated the Logic
* fix telemetry events
* clean up session id
* update user inserted event
* N8N-2853 Fixed Categories to Moving if the names are long
* Add todos
* Update Routes on loading
* fix spacing
* Update Border Color
* Update Border Readius
* fix filter fn
* fix constant, console error
* N8N-2853 PR Fixes, Refactoring, Removing unnecesairy code ..
* N8N-2853 PR Fixes - Editor-ui Fixes, Refactoring, Removing Dead Code ...
* N8N-2853 Refactor Card to LongCard
* clean up spacing, replace css var
* clean up spacing
* set categories as optional in node
* replace vars
* refactor store
* remove unnesssary import
* fix error
* fix templates view to start
* add to cache
* fix coll view data
* fix categories
* fix category event
* fix collections carousel
* fix initial load and search
* fix infinite load
* fix query param
* fix scrolling issues
* fix scroll to top
* fix search
* fix collections search
* fix navigation bug
* rename view
* update package lock
* rename workflow view
* rename coll view
* update routes
* add wrapper component
* set session id
* fix search tracking
* fix session tracking
* remove deleted mutation
* remove check for unsupported nodes
* refactor filters
* lazy load template
* clean up types
* refactor infinte scroll
* fix end of search
* Fix spacing
* fix coll loading
* fix types
* fix coll view list
* fix navigation
* rename types
* rename state
* fix search responsiveness
* fix coll view spacing
* fix search view spacing
* clean up views
* set background color
* center page not vert
* fix workflow view
* remove import
* fix background color
* fix background
* clean props
* clean up imports
* refactor button
* update background color
* fix spacing issue
* rename event
* update telemetry event
* update endpoints, add loading view, check for endpoint health
* remove conolse log
* N8N-2853 Fixed Menu Items Padding
* replace endpoints
* fix type issues
* fix categories
* N8N-2853 Fixed ParameterInput Placeholder after ElementUI Upgrade
* update createdAt
* :zap: Fix placeholder in creds config modal
* :pencil2: Adjust docstring to `credText` placeholder version
* N8N-2853 Optimized
* N8N-2853 Optimized code
* :zap: Add deployment type to FE settings
* :zap: Add deployment type to interfaces
* N8N-2853 Removed Animated prop from components
* :zap: Add deployment type to store module
* :sparkles: Create hiring banner
* :zap: Display hiring banner
* :rewind: Undo unrelated change
* N8N-2853 Refactor TemplateFilters
* :zap: Fix indentation
* N8N-2853 Reorder items / TemplateList
* :shirt: Fix lint
* N8N-2853 Refactor TemplateFilters Component
* N8N-2853 Reorder TemplateList
* refactor template card
* update timeout
* fix removelistener
* fix spacing
* split enabled from offline
* add spacing to go back
* N8N-2853 Fixed Screens for Tablet & Mobile
* N8N-2853 Update Stores Order
* remove image componet
* remove placeholder changes
* N8N-2853 Fixed Chinnese Placeholders for El Select Component that comes from the Library Upgrade
* N8N-2853 Fixed Vue Agile Console Warnings
* N8N-2853 Update Collection Route
* :pencil2: Update jobs URL
* :truck: Move logging to root component
* :zap: Refactor `deploymentType` to `isInternalUser`
* :zap: Improve syntax
* fix cut bug in readonly view
* N8N-3012 Fixed Details section in templates with lots of description, Fixed Mardown Block with overflox-x
* N8N-3012 Increased Font-size, Spacing and Line-height of the Categories Items
* N8N-3012 Fixed Vue-agile client width error on resize
* only delay redirect for root path
* N8N-3012 Fixed Carousel Arrows that Disappear
* N8N-3012 Make Loading Screen same color as Templates
* N8N-3012 Markdown renders inline block as block code
* add offline warning
* hide log from workflow iframe
* update text
* make search button larger
* N8N-3012 Categories / Tags extended all the way in details section
* load data in cred modals
* remove deleted message
* add external hook
* remove import
* update env variable description
* fix markdown width issue
* disable telemetry for demo, add session id to template pages
* fix telemetery bugs
* N8N-3012 Not found Collections/Wokrkflow
* N8N-3012 Checkboxes change order when categories are changed
* N8N-3012 Refactor SortedCategories inside TemplateFilters component
* fix firefox bug
* add telemetry requirements
* add error check
* N8N-3012 Update GoBackButton to check if Route History is present
* N8N-3012 Fixed WF Nodes Icons
* hide workflow screenshots
* remove unnessary mixins
* rename prop
* fix design a bit
* rename data
* clear workspace on destroy
* fix copy paste bug
* fix disabled state
* N8N-3012 Fixed Saving/Leave without saving Modal
* fix telemetry issue
* fix telemetry issues, error bug
* fix error notification
* disable workflow menu items on templates
* fix i18n elementui issue
* Remove Emit - NodeType from HoverableNodeIcon component
* TechnicalFixes: NavigateTo passed down as function should be helper
* TechnicalFixes: Update NavigateTo function
* TechnicalFixes: Add FilterCoreNodes directly as function
* check for empty connecitions
* fix titles
* respect new lines
* increase categories to be sliced
* rename prop
* onUseWorkflow
* refactor click event
* fix bug, refactor
* fix loading story
* add default
* fix styles at right level of abstraction
* add wrapper with width
* remove loading blocks component
* add story
* rename prop
* fix spacing
* refactor tag, add story
* move margin to container
* fix tag redirect, remove unnessary check
* make version optional
* rename view
* move from workflows to templates store
* remove unnessary change
* remove unnessary css
* rename component
* refactor collection card
* add boolean to prevent shrink
* clean up carousel
* fix redirection bug on save
* remove listeners to fix multiple listeners bug
* remove unnessary types
* clean up boolean set
* fix node select bug
* rename component
* remove unnessary class
* fix redirection bug
* remove unnessary error
* fix typo
* fix blockquotes, pre
* refactor markdown rendering
* remove console log
* escape markdown
* fix safari bug
* load active workflows to fix modal bug
* :arrow_up: Update package-lock.json file
* :zap: Add n8n version as header
Co-authored-by: Mutasem Aldmour <4711238+mutdmour@users.noreply.github.com>
Co-authored-by: Mutasem <mutdmour@gmail.com>
Co-authored-by: Iván Ovejero <ivov.src@gmail.com>
Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
2022-02-28 01:57:44 -08:00
if ( this . areExpressionsDisabled ) {
return this . value ;
}
2021-01-24 04:33:57 -08:00
if ( this . node === null ) {
2019-06-23 03:35:23 -07:00
return null ;
}
let computedValue : NodeParameterValue ;
try {
2022-09-21 06:44:45 -07:00
computedValue = this . resolveExpression ( this . value . value || this . value ) as NodeParameterValue ;
2019-06-23 03:35:23 -07:00
} catch ( error ) {
2021-12-15 04:16:53 -08:00
computedValue = ` [ ${ this . $locale . baseText ( 'parameterInput.error' ) } }: ${ error . message } ] ` ;
2019-06-23 03:35:23 -07:00
}
return computedValue ;
} ,
getStringInputType ( ) {
if ( this . getArgument ( 'password' ) === true ) {
return 'password' ;
}
const rows = this . getArgument ( 'rows' ) ;
if ( rows !== undefined && rows > 1 ) {
return 'textarea' ;
}
2022-07-20 04:32:51 -07:00
if ( this . parameter . type === 'code' ) {
return 'textarea' ;
}
2019-06-23 03:35:23 -07:00
return 'text' ;
} ,
getIssues ( ) : string [ ] {
2021-09-11 01:15:36 -07:00
if ( this . hideIssues === true || this . node === null ) {
2019-06-23 03:35:23 -07:00
return [ ] ;
}
const newPath = this . shortPath . split ( '.' ) ;
newPath . pop ( ) ;
2022-04-28 10:04:09 -07:00
const issues = NodeHelpers . getParameterIssues ( this . parameter , this . node . parameters , newPath . join ( '.' ) , this . node ) ;
2019-06-23 03:35:23 -07:00
2022-05-24 02:36:19 -07:00
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
) {
2019-06-23 03:35:23 -07:00
// 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 : INodePropertyOptions ) => options . value ) ;
2019-11-21 15:07:38 -08:00
const checkValues : string [ ] = [ ] ;
2022-05-24 02:36:19 -07:00
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
}
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
const issue = this . $locale . baseText (
'parameterInput.theValueIsNotSupported' ,
{ interpolate : { checkValue } } ,
) ;
issues . parameters [ this . parameter . name ] = [ issue ] ;
2019-06-23 03:35:23 -07:00
}
}
} else if ( this . remoteParameterOptionsLoadingIssues !== null ) {
if ( issues . parameters === undefined ) {
issues . parameters = { } ;
}
issues . parameters [ this . parameter . name ] = [ ` There was a problem loading the parameter options from server: " ${ this . remoteParameterOptionsLoadingIssues } " ` ] ;
}
if ( issues !== undefined &&
issues . parameters !== undefined &&
issues . parameters [ this . parameter . name ] !== undefined ) {
return issues . parameters [ this . parameter . name ] ;
}
return [ ] ;
} ,
2019-09-04 09:22:06 -07:00
isEditor ( ) : boolean {
2021-12-23 02:41:46 -08:00
return [ 'code' , 'json' ] . includes ( this . editorType ) ;
2019-09-04 09:22:06 -07:00
} ,
2021-12-23 02:41:46 -08:00
editorType ( ) : string {
return this . getArgument ( 'editor' ) as string ;
} ,
2019-06-23 03:35:23 -07:00
parameterOptions ( ) : INodePropertyOptions [ ] {
2022-02-05 13:55:43 -08:00
if ( this . hasRemoteMethod === false ) {
2019-06-23 03:35:23 -07:00
// Options are already given
return this . parameter . options ;
}
// Options get loaded from server
return this . remoteParameterOptions ;
} ,
parameterInputClasses ( ) {
2022-07-20 04:32:51 -07:00
const classes : { [ c : string ] : boolean } = {
droppable : this . droppable ,
activeDrop : this . activeDrop ,
} ;
2021-08-29 04:36:17 -07:00
const rows = this . getArgument ( 'rows' ) ;
const isTextarea = this . parameter . type === 'string' && rows !== undefined ;
2021-10-27 12:55:37 -07:00
const isSwitch = this . parameter . type === 'boolean' && ! this . isValueExpression ;
2021-08-29 04:36:17 -07:00
2021-10-27 12:55:37 -07:00
if ( ! isTextarea && ! isSwitch ) {
2022-07-20 04:32:51 -07:00
classes [ 'parameter-value-container' ] = true ;
2021-08-29 04:36:17 -07:00
}
2022-07-20 04:32:51 -07:00
if ( this . isValueExpression || this . forceShowExpression ) {
classes [ 'expression' ] = true ;
2019-06-23 03:35:23 -07:00
}
2022-07-20 04:32:51 -07:00
if ( ! this . droppable && ! this . activeDrop && ( this . getIssues . length || this . errorHighlight ) ) {
classes [ 'has-issues' ] = true ;
2019-06-23 03:35:23 -07:00
}
2022-07-20 04:32:51 -07:00
2019-06-23 03:35:23 -07:00
return classes ;
} ,
parameterInputWrapperStyle ( ) {
let deductWidth = 0 ;
const styles = {
width : '100%' ,
} ;
2022-09-21 06:44:45 -07:00
if ( this . parameter . type === 'credentialsSelect' || this . isResourceLocatorParameter ) {
2022-05-24 02:36:19 -07:00
return styles ;
}
2019-06-23 03:35:23 -07:00
if ( this . getIssues . length ) {
deductWidth += 20 ;
}
if ( deductWidth !== 0 ) {
styles . width = ` calc(100% - ${ deductWidth } px) ` ;
}
return styles ;
} ,
2022-02-05 13:55:43 -08:00
hasRemoteMethod ( ) : boolean {
return ! ! this . getArgument ( 'loadOptionsMethod' ) || ! ! this . getArgument ( 'loadOptions' ) ;
2019-06-23 03:35:23 -07:00
} ,
shortPath ( ) : string {
const shortPath = this . path . split ( '.' ) ;
shortPath . shift ( ) ;
return shortPath . join ( '.' ) ;
} ,
workflow ( ) : Workflow {
2022-08-12 07:06:57 -07:00
return this . getCurrentWorkflow ( ) ;
2019-06-23 03:35:23 -07:00
} ,
2022-09-21 06:44:45 -07:00
isResourceLocatorParameter ( ) : boolean {
return this . parameter . type === 'resourceLocator' ;
} ,
2019-06-23 03:35:23 -07:00
} ,
methods : {
2022-08-19 06:35:39 -07:00
isRemoteParameterOption ( option : INodePropertyOptions ) {
return this . remoteParameterOptions . map ( o => o . name ) . includes ( option . name ) ;
} ,
2022-05-24 02:36:19 -07:00
credentialSelected ( updateInformation : INodeUpdatePropertiesInformation ) {
// Update the values on the node
this . $store . commit ( 'updateNodeProperties' , updateInformation ) ;
const node = this . $store . getters . getNodeByName ( updateInformation . name ) ;
// Update the issues
this . updateNodeCredentialIssues ( node ) ;
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 ) ;
} ,
2021-11-15 02:19:43 -08:00
getPlaceholder ( ) : string {
return this . isForCredential
2021-12-15 04:16:53 -08:00
? this . $locale . credText ( ) . placeholder ( this . parameter )
2022-01-07 13:02:21 -08:00
: this . $locale . nodeText ( ) . placeholder ( this . parameter , this . path ) ;
2021-11-15 02:19:43 -08:00
} ,
getOptionsOptionDisplayName ( option : { value : string ; name : string } ) : string {
return this . isForCredential
2021-12-15 04:16:53 -08:00
? this . $locale . credText ( ) . optionsOptionDisplayName ( this . parameter , option )
2022-01-07 13:02:21 -08:00
: this . $locale . nodeText ( ) . optionsOptionDisplayName ( this . parameter , option , this . path ) ;
2021-11-15 02:19:43 -08:00
} ,
getOptionsOptionDescription ( option : { value : string ; description : string } ) : string {
return this . isForCredential
2021-12-15 04:16:53 -08:00
? this . $locale . credText ( ) . optionsOptionDescription ( this . parameter , option )
2022-01-07 13:02:21 -08:00
: this . $locale . nodeText ( ) . optionsOptionDescription ( this . parameter , option , this . path ) ;
2021-11-15 02:19:43 -08:00
} ,
2019-06-23 03:35:23 -07:00
async loadRemoteParameterOptions ( ) {
2022-02-05 13:55:43 -08:00
if ( this . node === null || this . hasRemoteMethod === false || this . remoteParameterOptionsLoading ) {
2019-06-23 03:35:23 -07:00
return ;
}
this . remoteParameterOptionsLoadingIssues = null ;
this . remoteParameterOptionsLoading = true ;
this . remoteParameterOptions . length = 0 ;
2019-12-16 18:27:56 -08:00
// Get the resolved parameter values of the current node
2019-06-23 03:35:23 -07:00
try {
2022-09-21 06:44:45 -07:00
const currentNodeParameters = ( this . $store . getters . activeNode as INodeUi ) . parameters ;
2022-06-03 08:25:07 -07:00
const resolvedNodeParameters = this . resolveParameter ( currentNodeParameters ) as INodeParameters ;
2022-02-05 13:55:43 -08:00
const loadOptionsMethod = this . getArgument ( 'loadOptionsMethod' ) as string | undefined ;
const loadOptions = this . getArgument ( 'loadOptions' ) as ILoadOptions | undefined ;
2022-08-01 13:43:50 -07:00
const options = await this . $store . dispatch ( 'nodeTypes/getNodeParameterOptions' ,
{
nodeTypeAndVersion : {
name : this . node . type ,
version : this . node . typeVersion ,
} ,
path : this . path ,
methodName : loadOptionsMethod ,
loadOptions ,
currentNodeParameters : resolvedNodeParameters ,
credentials : this . node . credentials ,
} ,
) ;
2019-06-23 03:35:23 -07:00
this . remoteParameterOptions . push . apply ( this . remoteParameterOptions , options ) ;
} catch ( error ) {
this . remoteParameterOptionsLoadingIssues = error . message ;
}
this . remoteParameterOptionsLoading = false ;
} ,
2019-09-04 09:22:06 -07:00
closeCodeEditDialog ( ) {
this . codeEditDialogVisible = false ;
} ,
2019-06-23 03:35:23 -07:00
closeExpressionEditDialog ( ) {
this . expressionEditDialogVisible = false ;
} ,
2021-10-18 20:57:49 -07:00
trackExpressionEditOpen ( ) {
if ( ! this . node ) {
return ;
}
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 . $store . getters . workflowId ,
2022-05-23 08:56:15 -07:00
session _id : this . $store . getters [ 'ui/ndvSessionId' ] ,
source : this . eventSource || 'ndv' ,
2021-10-27 12:55:37 -07:00
} ) ;
2021-10-18 20:57:49 -07:00
}
} ,
2019-06-23 03:35:23 -07:00
closeTextEditDialog ( ) {
this . textEditDialogVisible = false ;
} ,
2019-09-04 09:22:06 -07:00
displayEditDialog ( ) {
if ( this . isEditor ) {
this . codeEditDialogVisible = true ;
} else {
this . textEditDialogVisible = true ;
}
} ,
2019-06-23 03:35:23 -07:00
getArgument ( argumentName : string ) : string | number | boolean | undefined {
if ( this . parameter . typeOptions === undefined ) {
return undefined ;
}
if ( this . parameter . typeOptions [ argumentName ] === undefined ) {
return undefined ;
}
return this . parameter . typeOptions [ argumentName ] ;
} ,
expressionUpdated ( value : string ) {
2022-09-22 10:04:26 -07:00
const val : NodeParameterValueType = this . isResourceLocatorParameter ? { _ _rl : true , value , mode : this . value . mode } : value ;
2022-09-21 06:44:45 -07:00
this . valueChanged ( val ) ;
2019-06-23 03:35:23 -07:00
} ,
2021-08-29 04:36:17 -07:00
openExpressionEdit ( ) {
:sparkles: Add Templates (#2720)
* Templates Bugs / Fixed Various Bugs / Multiply Api Request, Carousel Gradient, Core Nodes Filters ...
* Updated MainSidebar Paddings
* N8N-Templates Bugfixing - Remove Unnecesairy Icon (Shape), Refatctor infiniteScrollEnabled Prop + updated infiniterScroll functinality
* N8N-2853 Fixed Carousel Arrows Bug after Cleaning the SearchBar
* fix telemetry init
* fix search tracking issues
* N8N-2853 Created FilterTemplateNode Constant Array, Filter PlayButton and WebhookRespond from Nodes, Added Box for showing more nodes inside TemplateList, Updated NewWorkflowButton to primary, Fixed Markdown issue with Code
* N8N-2853 Removed Placeholder if Workflows Or Collections are not found, Updated the Logic
* fix telemetry events
* clean up session id
* update user inserted event
* N8N-2853 Fixed Categories to Moving if the names are long
* Add todos
* Update Routes on loading
* fix spacing
* Update Border Color
* Update Border Readius
* fix filter fn
* fix constant, console error
* N8N-2853 PR Fixes, Refactoring, Removing unnecesairy code ..
* N8N-2853 PR Fixes - Editor-ui Fixes, Refactoring, Removing Dead Code ...
* N8N-2853 Refactor Card to LongCard
* clean up spacing, replace css var
* clean up spacing
* set categories as optional in node
* replace vars
* refactor store
* remove unnesssary import
* fix error
* fix templates view to start
* add to cache
* fix coll view data
* fix categories
* fix category event
* fix collections carousel
* fix initial load and search
* fix infinite load
* fix query param
* fix scrolling issues
* fix scroll to top
* fix search
* fix collections search
* fix navigation bug
* rename view
* update package lock
* rename workflow view
* rename coll view
* update routes
* add wrapper component
* set session id
* fix search tracking
* fix session tracking
* remove deleted mutation
* remove check for unsupported nodes
* refactor filters
* lazy load template
* clean up types
* refactor infinte scroll
* fix end of search
* Fix spacing
* fix coll loading
* fix types
* fix coll view list
* fix navigation
* rename types
* rename state
* fix search responsiveness
* fix coll view spacing
* fix search view spacing
* clean up views
* set background color
* center page not vert
* fix workflow view
* remove import
* fix background color
* fix background
* clean props
* clean up imports
* refactor button
* update background color
* fix spacing issue
* rename event
* update telemetry event
* update endpoints, add loading view, check for endpoint health
* remove conolse log
* N8N-2853 Fixed Menu Items Padding
* replace endpoints
* fix type issues
* fix categories
* N8N-2853 Fixed ParameterInput Placeholder after ElementUI Upgrade
* update createdAt
* :zap: Fix placeholder in creds config modal
* :pencil2: Adjust docstring to `credText` placeholder version
* N8N-2853 Optimized
* N8N-2853 Optimized code
* :zap: Add deployment type to FE settings
* :zap: Add deployment type to interfaces
* N8N-2853 Removed Animated prop from components
* :zap: Add deployment type to store module
* :sparkles: Create hiring banner
* :zap: Display hiring banner
* :rewind: Undo unrelated change
* N8N-2853 Refactor TemplateFilters
* :zap: Fix indentation
* N8N-2853 Reorder items / TemplateList
* :shirt: Fix lint
* N8N-2853 Refactor TemplateFilters Component
* N8N-2853 Reorder TemplateList
* refactor template card
* update timeout
* fix removelistener
* fix spacing
* split enabled from offline
* add spacing to go back
* N8N-2853 Fixed Screens for Tablet & Mobile
* N8N-2853 Update Stores Order
* remove image componet
* remove placeholder changes
* N8N-2853 Fixed Chinnese Placeholders for El Select Component that comes from the Library Upgrade
* N8N-2853 Fixed Vue Agile Console Warnings
* N8N-2853 Update Collection Route
* :pencil2: Update jobs URL
* :truck: Move logging to root component
* :zap: Refactor `deploymentType` to `isInternalUser`
* :zap: Improve syntax
* fix cut bug in readonly view
* N8N-3012 Fixed Details section in templates with lots of description, Fixed Mardown Block with overflox-x
* N8N-3012 Increased Font-size, Spacing and Line-height of the Categories Items
* N8N-3012 Fixed Vue-agile client width error on resize
* only delay redirect for root path
* N8N-3012 Fixed Carousel Arrows that Disappear
* N8N-3012 Make Loading Screen same color as Templates
* N8N-3012 Markdown renders inline block as block code
* add offline warning
* hide log from workflow iframe
* update text
* make search button larger
* N8N-3012 Categories / Tags extended all the way in details section
* load data in cred modals
* remove deleted message
* add external hook
* remove import
* update env variable description
* fix markdown width issue
* disable telemetry for demo, add session id to template pages
* fix telemetery bugs
* N8N-3012 Not found Collections/Wokrkflow
* N8N-3012 Checkboxes change order when categories are changed
* N8N-3012 Refactor SortedCategories inside TemplateFilters component
* fix firefox bug
* add telemetry requirements
* add error check
* N8N-3012 Update GoBackButton to check if Route History is present
* N8N-3012 Fixed WF Nodes Icons
* hide workflow screenshots
* remove unnessary mixins
* rename prop
* fix design a bit
* rename data
* clear workspace on destroy
* fix copy paste bug
* fix disabled state
* N8N-3012 Fixed Saving/Leave without saving Modal
* fix telemetry issue
* fix telemetry issues, error bug
* fix error notification
* disable workflow menu items on templates
* fix i18n elementui issue
* Remove Emit - NodeType from HoverableNodeIcon component
* TechnicalFixes: NavigateTo passed down as function should be helper
* TechnicalFixes: Update NavigateTo function
* TechnicalFixes: Add FilterCoreNodes directly as function
* check for empty connecitions
* fix titles
* respect new lines
* increase categories to be sliced
* rename prop
* onUseWorkflow
* refactor click event
* fix bug, refactor
* fix loading story
* add default
* fix styles at right level of abstraction
* add wrapper with width
* remove loading blocks component
* add story
* rename prop
* fix spacing
* refactor tag, add story
* move margin to container
* fix tag redirect, remove unnessary check
* make version optional
* rename view
* move from workflows to templates store
* remove unnessary change
* remove unnessary css
* rename component
* refactor collection card
* add boolean to prevent shrink
* clean up carousel
* fix redirection bug on save
* remove listeners to fix multiple listeners bug
* remove unnessary types
* clean up boolean set
* fix node select bug
* rename component
* remove unnessary class
* fix redirection bug
* remove unnessary error
* fix typo
* fix blockquotes, pre
* refactor markdown rendering
* remove console log
* escape markdown
* fix safari bug
* load active workflows to fix modal bug
* :arrow_up: Update package-lock.json file
* :zap: Add n8n version as header
Co-authored-by: Mutasem Aldmour <4711238+mutdmour@users.noreply.github.com>
Co-authored-by: Mutasem <mutdmour@gmail.com>
Co-authored-by: Iván Ovejero <ivov.src@gmail.com>
Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
2022-02-28 01:57:44 -08:00
if ( this . areExpressionsDisabled ) {
return ;
}
2021-08-29 04:36:17 -07:00
if ( this . isValueExpression ) {
this . expressionEditDialogVisible = true ;
2021-10-18 20:57:49 -07:00
this . trackExpressionEditOpen ( ) ;
2021-09-11 01:15:36 -07:00
return ;
2021-08-29 04:36:17 -07:00
}
} ,
2021-09-11 01:15:36 -07:00
onBlur ( ) {
this . $emit ( 'blur' ) ;
} ,
2022-09-21 06:44:45 -07:00
onResourceLocatorDrop ( data : string ) {
this . $emit ( 'drop' , data ) ;
} ,
2019-06-23 03:35:23 -07:00
setFocus ( ) {
if ( this . isValueExpression ) {
this . expressionEditDialogVisible = true ;
2021-10-18 20:57:49 -07:00
this . trackExpressionEditOpen ( ) ;
2019-06-23 03:35:23 -07:00
return ;
}
2019-11-03 13:06:03 -08:00
if ( [ 'json' , 'string' ] . includes ( this . parameter . type ) && this . getArgument ( 'alwaysOpenEditWindow' ) ) {
2019-09-04 09:22:06 -07:00
this . displayEditDialog ( ) ;
2019-06-23 03:35:23 -07:00
return ;
}
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 ;
}
// Set focus on field
setTimeout ( ( ) => {
2019-10-15 14:19:20 -07:00
// @ts-ignore
2022-09-21 06:44:45 -07:00
if ( this . $refs . inputField && this . $refs . inputField . $el ) {
2020-11-09 02:26:46 -08:00
// @ts-ignore
2022-08-05 06:03:24 -07:00
this . $refs . inputField . focus ( ) ;
2020-11-09 02:26:46 -08:00
}
2019-06-23 03:35:23 -07:00
} ) ;
2021-10-27 12:55:37 -07:00
this . $emit ( 'focus' ) ;
2019-06-23 03:35:23 -07:00
} ,
2020-11-09 02:26:46 -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 ) ;
} ,
2021-09-11 01:15:36 -07:00
onTextInputChange ( value : string ) {
const parameterData = {
node : this . node !== null ? this . node . name : this . nodeName ,
name : this . path ,
value ,
} ;
this . $emit ( 'textInput' , parameterData ) ;
} ,
2022-09-21 06:44:45 -07:00
valueChanged ( value : string [ ] | string | number | boolean | Date | { } | null ) {
2022-05-24 02:36:19 -07:00
if ( this . parameter . name === 'nodeCredentialType' ) {
this . activeCredentialType = value as string ;
}
2019-06-23 03:35:23 -07:00
if ( value instanceof Date ) {
value = value . toISOString ( ) ;
}
2020-11-09 02:26:46 -08:00
if ( this . parameter . type === 'color' && this . getArgument ( 'showAlpha' ) === true && value !== null && value . toString ( ) . charAt ( 0 ) !== '#' ) {
const newValue = this . rgbaToHex ( value as string ) ;
if ( newValue !== null ) {
this . tempValue = newValue ;
value = newValue ;
}
}
2019-06-23 03:35:23 -07:00
const parameterData = {
node : this . node !== null ? this . node . name : this . nodeName ,
name : this . path ,
value ,
} ;
this . $emit ( 'valueChanged' , parameterData ) ;
2022-07-09 23:53:04 -07:00
if ( this . parameter . name === 'operation' || this . parameter . name === 'mode' ) {
this . $telemetry . track ( 'User set node operation or mode' , {
workflow _id : this . $store . getters . 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 . $store . getters [ 'ui/ndvSessionId' ] ,
parameter : this . parameter . name ,
} ) ;
}
2019-06-23 03:35:23 -07:00
} ,
optionSelected ( command : string ) {
2022-07-20 04:32:51 -07:00
const prevValue = this . value ;
2019-06-23 03:35:23 -07:00
if ( command === 'resetValue' ) {
this . valueChanged ( this . parameter . default ) ;
2022-07-20 04:32:51 -07:00
} else if ( command === 'openExpression' ) {
this . expressionEditDialogVisible = true ;
2019-06-23 03:35:23 -07:00
} else if ( command === 'addExpression' ) {
2022-09-22 03:31:49 -07:00
if ( this . isResourceLocatorParameter ) {
2022-09-21 06:44:45 -07:00
if ( isResourceLocatorValue ( this . value ) ) {
2022-09-22 10:04:26 -07:00
this . valueChanged ( { _ _rl : true , value : ` = ${ this . value . value } ` , mode : this . value . mode } ) ;
2022-09-21 06:44:45 -07:00
} else {
2022-09-22 10:04:26 -07:00
this . valueChanged ( { _ _rl : true , value : ` = ${ this . value } ` , mode : '' } ) ;
2022-09-21 06:44:45 -07:00
}
2022-09-22 03:31:49 -07:00
}
else if ( this . parameter . type === 'number' || this . parameter . type === 'boolean' ) {
this . valueChanged ( ` ={{ ${ this . value } }} ` ) ;
}
else {
2021-08-29 04:36:17 -07:00
this . valueChanged ( ` = ${ this . value } ` ) ;
}
2022-07-20 04:32:51 -07:00
setTimeout ( ( ) => {
this . expressionEditDialogVisible = true ;
this . trackExpressionEditOpen ( ) ;
} , 375 ) ;
2019-06-23 03:35:23 -07:00
} else if ( command === 'removeExpression' ) {
2022-04-14 22:35:51 -07:00
let value = this . expressionValueComputed ;
if ( this . parameter . type === 'multiOptions' && typeof value === 'string' ) {
value = ( value || '' ) . split ( ',' )
. filter ( ( value ) => ( this . parameterOptions || [ ] ) . find ( ( option ) => option . value === value ) ) ;
}
2022-09-21 06:44:45 -07:00
if ( this . isResourceLocatorParameter ) {
2022-09-22 10:04:26 -07:00
this . valueChanged ( { _ _rl : true , value , mode : this . value . mode } ) ;
2022-09-21 06:44:45 -07:00
} else {
this . valueChanged ( typeof value !== 'undefined' ? value : null ) ;
}
2021-07-23 08:52:25 -07:00
} else if ( command === 'refreshOptions' ) {
2022-09-21 06:44:45 -07:00
if ( this . isResourceLocatorParameter ) {
const resourceLocator = this . $refs . resourceLocator ;
if ( resourceLocator ) {
( resourceLocator as Vue ) . $emit ( 'refreshList' ) ;
}
}
2021-08-29 04:36:17 -07:00
this . loadRemoteParameterOptions ( ) ;
2019-06-23 03:35:23 -07:00
}
2022-07-20 04:32:51 -07:00
if ( this . node && ( command === 'addExpression' || command === 'removeExpression' ) ) {
2022-08-19 06:35:39 -07:00
const telemetryPayload = {
2022-07-20 04:32:51 -07:00
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' ) ,
2022-08-19 06:35:39 -07:00
} ;
this . $telemetry . track ( 'User switched parameter mode' , telemetryPayload ) ;
this . $externalHooks ( ) . run ( 'parameterInput.modeSwitch' , telemetryPayload ) ;
2022-07-20 04:32:51 -07:00
}
2019-06-23 03:35:23 -07:00
} ,
} ,
2022-08-19 06:35:39 -07:00
updated ( ) {
this . $nextTick ( ( ) => {
const remoteParameterOptions = this . $el . querySelectorAll ( '.remote-parameter-option' ) ;
if ( remoteParameterOptions . length > 0 ) {
this . $externalHooks ( ) . run ( 'parameterInput.updated' , { remoteParameterOptions } ) ;
}
} ) ;
} ,
2019-06-23 03:35:23 -07:00
mounted ( ) {
2022-07-20 04:32:51 -07:00
this . $on ( 'optionSelected' , this . optionSelected ) ;
2019-06-23 03:35:23 -07:00
this . tempValue = this . displayValue as string ;
if ( this . node !== null ) {
this . nodeName = this . node . name ;
}
2022-05-24 02:36:19 -07:00
if ( this . node && this . node . parameters . authentication === 'predefinedCredentialType' ) {
this . activeCredentialType = this . node . parameters . nodeCredentialType as string ;
}
2020-11-09 02:26:46 -08:00
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 ;
}
}
2022-02-05 13:55:43 -08:00
if ( this . hasRemoteMethod === true && this . node !== null ) {
2019-06-23 03:35:23 -07:00
// Make sure to load the parameter options
// directly and whenever the credentials change
this . $watch ( ( ) => this . node ! . credentials , ( ) => {
this . loadRemoteParameterOptions ( ) ;
} , { deep : true , immediate : true } ) ;
2019-10-20 11:55:49 -07:00
// Reload function on change element from
// displayOptions.typeOptions.reloadOnChange parameters
if ( this . parameter . typeOptions && this . parameter . typeOptions . reloadOnChange ) {
2022-09-02 07:13:17 -07:00
// Get all parameter in reloadOnChange property
2019-10-20 11:55:49 -07:00
// This reload when parameters in reloadOnChange is updated
2022-09-02 07:13:17 -07:00
const parametersOnChange : string [ ] = this . parameter . typeOptions . reloadOnChange ;
for ( let i = 0 ; i < parametersOnChange . length ; i ++ ) {
const parameter = parametersOnChange [ i ] as string ;
2019-10-20 11:55:49 -07:00
if ( parameter in this . node . parameters ) {
this . $watch ( ( ) => {
if ( this . node && this . node . parameters && this . node . parameters [ parameter ] ) {
return this . node . parameters ! [ parameter ] ;
} else {
return null ;
}
} , ( ) => {
this . loadRemoteParameterOptions ( ) ;
} , { deep : true , immediate : true } ) ;
}
}
}
2019-06-23 03:35:23 -07:00
}
2021-08-13 03:01:12 -07: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 - 5 xs ) 0 var ( -- spacing - 2 xs ) 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 : 6 px ;
line - height : 26 px ;
2021-08-29 04:36:17 -07:00
background - color : # f0f0f0 ;
2019-06-23 03:35:23 -07:00
}
. expression {
2022-07-20 04:32:51 -07:00
textarea , input {
2021-08-29 04:36:17 -07:00
cursor : pointer ! important ;
2019-06-23 03:35:23 -07:00
}
2022-07-20 04:32:51 -07:00
-- input - border - color : var ( -- color - secondary - tint - 1 ) ;
2022-08-25 02:30:18 -07:00
-- input - background - color : var ( -- color - secondary - tint - 3 ) ;
2022-07-20 04:32:51 -07:00
-- input - font - color : var ( -- color - secondary ) ;
}
2019-06-23 03:35:23 -07:00
2022-07-20 04:32:51 -07:00
. droppable {
-- input - border - color : var ( -- color - secondary - tint - 1 ) ;
2022-08-25 02:30:18 -07:00
-- input - background - color : var ( -- color - secondary - tint - 3 ) ;
2021-08-29 04:36:17 -07:00
-- input - border - style : dashed ;
2022-07-20 04:32:51 -07:00
}
. activeDrop {
-- input - border - color : var ( -- color - success ) ;
-- input - background - color : var ( -- color - success - tint - 2 ) ;
-- input - border - style : solid ;
textarea , input {
cursor : grabbing ! important ;
}
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 {
max - width : 340 px ;
margin : 6 px 0 ;
2019-06-23 03:35:23 -07:00
white - space : normal ;
2021-09-22 02:02:38 -07:00
padding - right : 20 px ;
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 : 2 px ;
font - size : var ( -- font - size - 2 xs ) ;
font - weight : var ( -- font - weight - regular ) ;
line - height : var ( -- font - line - height - xloose ) ;
color : $ -- custom - font - very - light ;
}
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 ;
}
2019-06-23 03:35:23 -07:00
< / style >