2019-06-23 03:35:23 -07:00
< template >
< span >
2020-07-29 05:12:54 -07:00
< el -dialog class = "workflow-settings" :visible ="dialogVisible" append -to -body width = "65%" title = "Workflow Settings" :before-close ="closeDialog" >
2019-06-23 03:35:23 -07:00
< div v-loading ="isLoading" >
< el -row >
< el -col :span ="10" class = "setting-name" >
Error Workflow :
< el -tooltip class = "setting-info" placement = "top" effect = "light" >
< div slot = "content" v-html ="helpTexts.errorWorkflow" > < / div >
< font -awesome -icon icon = "question-circle" / >
< / e l - t o o l t i p >
< / e l - c o l >
< el -col :span ="14" class = "ignore-key-press" >
< el -select v -model = " workflowSettings.errorWorkflow " placeholder = "Select Workflow" size = "small" filterable >
< el -option
v - for = "item in workflows"
: key = "item.id"
: label = "item.name"
: value = "item.id" >
< / e l - o p t i o n >
< / e l - s e l e c t >
< / e l - c o l >
< / e l - r o w >
< el -row >
< el -col :span ="10" class = "setting-name" >
Timezone :
< el -tooltip class = "setting-info" placement = "top" effect = "light" >
< div slot = "content" v-html ="helpTexts.timezone" > < / div >
< font -awesome -icon icon = "question-circle" / >
< / e l - t o o l t i p >
< / e l - c o l >
< el -col :span ="14" class = "ignore-key-press" >
< el -select v -model = " workflowSettings.timezone " placeholder = "Select Timezone" size = "small" filterable >
< el -option
v - for = "timezone of timezones"
: key = "timezone.key"
: label = "timezone.value"
: value = "timezone.key" >
< / e l - o p t i o n >
< / e l - s e l e c t >
< / e l - c o l >
< / e l - r o w >
2019-07-10 11:53:13 -07:00
< el -row >
< el -col :span ="10" class = "setting-name" >
Save Data Error Execution :
< el -tooltip class = "setting-info" placement = "top" effect = "light" >
< div slot = "content" v-html ="helpTexts.saveDataErrorExecution" > < / div >
< font -awesome -icon icon = "question-circle" / >
< / e l - t o o l t i p >
< / e l - c o l >
< el -col :span ="14" class = "ignore-key-press" >
< el -select v -model = " workflowSettings.saveDataErrorExecution " placeholder = "Select Option" size = "small" filterable >
< el -option
v - for = "option of saveDataErrorExecutionOptions"
: key = "option.key"
: label = "option.value"
: value = "option.key" >
< / e l - o p t i o n >
< / e l - s e l e c t >
< / e l - c o l >
< / e l - r o w >
< el -row >
< el -col :span ="10" class = "setting-name" >
Save Data Success Execution :
< el -tooltip class = "setting-info" placement = "top" effect = "light" >
< div slot = "content" v-html ="helpTexts.saveDataSuccessExecution" > < / div >
< font -awesome -icon icon = "question-circle" / >
< / e l - t o o l t i p >
< / e l - c o l >
< el -col :span ="14" class = "ignore-key-press" >
< el -select v -model = " workflowSettings.saveDataSuccessExecution " placeholder = "Select Option" size = "small" filterable >
< el -option
v - for = "option of saveDataSuccessExecutionOptions"
: key = "option.key"
: label = "option.value"
: value = "option.key" >
< / e l - o p t i o n >
< / e l - s e l e c t >
< / e l - c o l >
< / e l - r o w >
2019-06-23 03:35:23 -07:00
< el -row >
< el -col :span ="10" class = "setting-name" >
2019-07-10 09:06:26 -07:00
Save Manual Executions :
2019-06-23 03:35:23 -07:00
< el -tooltip class = "setting-info" placement = "top" effect = "light" >
2019-07-10 09:06:26 -07:00
< div slot = "content" v-html ="helpTexts.saveManualExecutions" > < / div >
2019-06-23 03:35:23 -07:00
< font -awesome -icon icon = "question-circle" / >
< / e l - t o o l t i p >
< / e l - c o l >
< el -col :span ="14" class = "ignore-key-press" >
2019-07-10 09:06:26 -07:00
< el -select v -model = " workflowSettings.saveManualExecutions " placeholder = "Select Option" size = "small" filterable >
2019-06-23 03:35:23 -07:00
< el -option
v - for = "option of saveManualOptions"
: key = "option.key"
: label = "option.value"
: value = "option.key" >
< / e l - o p t i o n >
< / e l - s e l e c t >
< / e l - c o l >
< / e l - r o w >
2021-02-08 23:59:32 -08:00
< el -row >
< el -col :span ="10" class = "setting-name" >
Save Execution Progress :
< el -tooltip class = "setting-info" placement = "top" effect = "light" >
< div slot = "content" v-html ="helpTexts.saveExecutionProgress" > < / div >
< font -awesome -icon icon = "question-circle" / >
< / e l - t o o l t i p >
< / e l - c o l >
< el -col :span ="14" class = "ignore-key-press" >
< el -select v -model = " workflowSettings.saveExecutionProgress " placeholder = "Select Option" size = "small" filterable >
< el -option
v - for = "option of saveExecutionProgressOptions"
: key = "option.key"
: label = "option.value"
: value = "option.key" >
< / e l - o p t i o n >
< / e l - s e l e c t >
< / e l - c o l >
< / e l - r o w >
2020-07-29 05:12:54 -07:00
< el -row >
< el -col :span ="10" class = "setting-name" >
Timeout Workflow :
< el -tooltip class = "setting-info" placement = "top" effect = "light" >
< div slot = "content" v-html ="helpTexts.executionTimeoutToggle" > < / div >
< font -awesome -icon icon = "question-circle" / >
< / e l - t o o l t i p >
< / e l - c o l >
< el -col :span ="14" >
< div >
< el -switch ref = "inputField" : value = "workflowSettings.executionTimeout > -1" @change ="toggleTimeout" active -color = " # 13ce66 " > < / e l - s w i t c h >
< div class = "expression-info clickable" @ click = "expressionEditDialogVisible = true" > Edit Expression < / div >
< / div >
< / e l - c o l >
< / e l - r o w >
< div v-if ="workflowSettings.executionTimeout > -1" >
< el -row >
< el -col :span ="10" class = "setting-name" >
Timeout After :
< el -tooltip class = "setting-info" placement = "top" effect = "light" >
< div slot = "content" v-html ="helpTexts.executionTimeout" > < / div >
< font -awesome -icon icon = "question-circle" / >
< / e l - t o o l t i p >
< / e l - c o l >
< el -col :span ="4" >
2020-07-29 05:19:35 -07:00
< el -input -number size = "small" v-model ="timeoutHMS.hours" :min="0" placeholder="hours" type="number" class="el-input_inner" > < / el -input -number > < br / >
2020-07-29 05:12:54 -07:00
< div class = "timeout-setting-name" > hours < / div >
< / e l - c o l >
< el -col :span ="4" >
2020-07-29 05:19:35 -07:00
< el -input -number size = "small" v-model ="timeoutHMS.minutes" :min="0" placeholder="minutes" type="number" class="el-input_inner" > < / el -input -number > < br / >
2020-07-29 05:12:54 -07:00
< div class = "timeout-setting-name" > minutes < / div >
< / e l - c o l >
< el -col :span ="4" >
2020-07-29 05:19:35 -07:00
< el -input -number size = "small" v-model ="timeoutHMS.seconds" :min="0" placeholder="seconds" type="number" class="el-input_inner" > < / el -input -number > < br / >
2020-07-29 05:12:54 -07:00
< div class = "timeout-setting-name" > seconds < / div >
< / e l - c o l >
< / e l - r o w >
< / div >
2019-06-23 03:35:23 -07:00
< div class = "action-buttons" >
< el -button type = "success" @click ="saveSettings" >
Save
< / e l - b u t t o n >
< / div >
< / div >
< / e l - d i a l o g >
< / span >
< / template >
< script lang = "ts" >
import Vue from 'vue' ;
2021-05-05 17:46:33 -07:00
import { externalHooks } from '@/components/mixins/externalHooks' ;
2019-06-23 03:35:23 -07:00
import { restApi } from '@/components/mixins/restApi' ;
import { genericHelpers } from '@/components/mixins/genericHelpers' ;
import { showMessage } from '@/components/mixins/showMessage' ;
import {
2020-07-29 05:12:54 -07:00
ITimeoutHMS ,
2019-06-23 03:35:23 -07:00
IWorkflowDataUpdate ,
2019-07-10 11:53:13 -07:00
IWorkflowSettings ,
IWorkflowShortResponse ,
2019-06-23 03:35:23 -07:00
} from '@/Interface' ;
import mixins from 'vue-typed-mixins' ;
export default mixins (
2021-05-05 17:46:33 -07:00
externalHooks ,
2019-06-23 03:35:23 -07:00
genericHelpers ,
restApi ,
showMessage ,
) . extend ( {
name : 'WorkflowSettings' ,
props : [
'dialogVisible' ,
] ,
data ( ) {
return {
isLoading : true ,
helpTexts : {
errorWorkflow : 'The workflow to run in case the current one fails.<br />To function correctly that workflow has to contain an "Error Trigger" node!' ,
timezone : 'The timezone in which the workflow should run. Gets for example used by "Cron" node.' ,
2019-07-10 11:53:13 -07:00
saveDataErrorExecution : 'If data data of executions should be saved in case they failed.' ,
saveDataSuccessExecution : 'If data data of executions should be saved in case they succeed.' ,
2021-02-08 23:59:32 -08:00
saveExecutionProgress : 'If data should be saved after each node, allowing you to resume in case of errors from where it stopped. May increase latency.' ,
2019-07-10 09:06:26 -07:00
saveManualExecutions : 'If data data of executions should be saved when started manually from the editor.' ,
2020-07-29 05:12:54 -07:00
executionTimeoutToggle : 'Cancel workflow execution after defined time' ,
executionTimeout : 'After what time the workflow should timeout.' ,
2019-06-23 03:35:23 -07:00
} ,
defaultValues : {
timezone : 'America/New_York' ,
2019-07-10 11:53:13 -07:00
saveDataErrorExecution : 'all' ,
saveDataSuccessExecution : 'all' ,
2021-02-08 23:59:32 -08:00
saveExecutionProgress : false ,
2019-07-10 09:06:26 -07:00
saveManualExecutions : false ,
2019-06-23 03:35:23 -07:00
} ,
2019-07-10 11:53:13 -07:00
saveDataErrorExecutionOptions : [ ] as Array < { key : string , value : string } > ,
saveDataSuccessExecutionOptions : [ ] as Array < { key : string , value : string } > ,
2021-02-08 23:59:32 -08:00
saveExecutionProgressOptions : [ ] as Array < { key : string | boolean , value : string } > ,
2019-06-23 03:35:23 -07:00
saveManualOptions : [ ] as Array < { key : string | boolean , value : string } > ,
timezones : [ ] as Array < { key : string , value : string } > ,
2019-07-10 12:01:22 -07:00
workflowSettings : { } as IWorkflowSettings ,
2019-06-23 03:35:23 -07:00
workflows : [ ] as IWorkflowShortResponse [ ] ,
2020-07-29 05:12:54 -07:00
executionTimeout : this . $store . getters . executionTimeout ,
maxExecutionTimeout : this . $store . getters . maxExecutionTimeout ,
timeoutHMS : { hours : 0 , minutes : 0 , seconds : 0 } as ITimeoutHMS ,
2019-06-23 03:35:23 -07:00
} ;
} ,
watch : {
dialogVisible ( newValue , oldValue ) {
if ( newValue ) {
this . openDialog ( ) ;
}
2021-05-05 17:46:33 -07:00
this . $externalHooks ( ) . run ( 'workflowSettings.dialogVisibleChanged' , { dialogVisible : newValue } ) ;
2019-06-23 03:35:23 -07:00
} ,
} ,
methods : {
closeDialog ( ) {
// Handle the close externally as the visible parameter is an external prop
// and is so not allowed to be changed here.
this . $emit ( 'closeDialog' ) ;
return false ;
} ,
2019-07-10 11:53:13 -07:00
async loadSaveDataErrorExecutionOptions ( ) {
this . saveDataErrorExecutionOptions . length = 0 ;
2019-07-10 12:01:22 -07:00
this . saveDataErrorExecutionOptions . push . apply ( // eslint-disable-line no-useless-call
2019-07-10 11:53:13 -07:00
this . saveDataErrorExecutionOptions , [
{
key : 'DEFAULT' ,
value : 'Default - ' + ( this . defaultValues . saveDataErrorExecution === 'all' ? 'Save' : 'Do not save' ) ,
} ,
{
key : 'all' ,
value : 'Save' ,
} ,
{
key : 'none' ,
value : 'Do not save' ,
2019-07-10 12:01:22 -07:00
} ,
2019-12-29 13:02:21 -08:00
] ,
2019-07-10 11:53:13 -07:00
) ;
} ,
async loadSaveDataSuccessExecutionOptions ( ) {
this . saveDataSuccessExecutionOptions . length = 0 ;
2019-07-10 12:01:22 -07:00
this . saveDataSuccessExecutionOptions . push . apply ( // eslint-disable-line no-useless-call
2019-07-10 11:53:13 -07:00
this . saveDataSuccessExecutionOptions , [
{
key : 'DEFAULT' ,
value : 'Default - ' + ( this . defaultValues . saveDataSuccessExecution === 'all' ? 'Save' : 'Do not save' ) ,
} ,
{
key : 'all' ,
value : 'Save' ,
} ,
{
key : 'none' ,
value : 'Do not save' ,
2019-07-10 12:01:22 -07:00
} ,
2019-12-29 13:02:21 -08:00
] ,
2019-07-10 11:53:13 -07:00
) ;
} ,
2021-02-08 23:59:32 -08:00
async loadSaveExecutionProgressOptions ( ) {
this . saveExecutionProgressOptions . length = 0 ;
this . saveExecutionProgressOptions . push . apply ( // eslint-disable-line no-useless-call
this . saveExecutionProgressOptions , [
{
key : 'DEFAULT' ,
value : 'Default - ' + ( this . defaultValues . saveExecutionProgress === true ? 'Yes' : 'No' ) ,
} ,
{
key : true ,
value : 'Yes' ,
} ,
{
key : false ,
value : 'No' ,
} ,
] ,
) ;
} ,
2019-06-23 03:35:23 -07:00
async loadSaveManualOptions ( ) {
this . saveManualOptions . length = 0 ;
this . saveManualOptions . push ( {
key : 'DEFAULT' ,
2019-07-10 11:53:13 -07:00
value : 'Default - ' + ( this . defaultValues . saveManualExecutions === true ? 'Yes' : 'No' ) ,
2019-06-23 03:35:23 -07:00
} ) ;
this . saveManualOptions . push ( {
key : true ,
value : 'Yes' ,
} ) ;
this . saveManualOptions . push ( {
key : false ,
value : 'No' ,
} ) ;
} ,
2019-07-10 11:53:13 -07:00
2019-06-23 03:35:23 -07:00
async loadTimezones ( ) {
if ( this . timezones . length !== 0 ) {
// Data got already loaded
return ;
}
const timezones = await this . restApi ( ) . getTimezones ( ) ;
let defaultTimezoneValue = timezones [ this . defaultValues . timezone ] as string | undefined ;
if ( defaultTimezoneValue === undefined ) {
defaultTimezoneValue = 'Default Timezone not valid!' ;
}
this . timezones . push ( {
key : 'DEFAULT' ,
value : ` Default - ${ defaultTimezoneValue } ` ,
} ) ;
for ( const timezone of Object . keys ( timezones ) ) {
this . timezones . push ( {
key : timezone ,
value : timezones [ timezone ] as string ,
} ) ;
}
} ,
async loadWorkflows ( ) {
const workflows = await this . restApi ( ) . getWorkflows ( ) ;
workflows . sort ( ( a , b ) => {
if ( a . name . toLowerCase ( ) < b . name . toLowerCase ( ) ) {
return - 1 ;
}
if ( a . name . toLowerCase ( ) > b . name . toLowerCase ( ) ) {
return 1 ;
}
return 0 ;
} ) ;
// @ts-ignore
workflows . unshift ( {
id : undefined as unknown as string ,
name : '- No Workflow -' ,
} ) ;
Vue . set ( this , 'workflows' , workflows ) ;
} ,
async openDialog ( ) {
if ( this . $route . params . name === undefined ) {
this . $showMessage ( {
title : 'No workflow active' ,
message : ` No workflow active to display settings of. ` ,
type : 'error' ,
duration : 0 ,
} ) ;
this . closeDialog ( ) ;
return ;
}
2019-07-10 11:53:13 -07:00
this . defaultValues . saveDataErrorExecution = this . $store . getters . saveDataErrorExecution ;
this . defaultValues . saveDataSuccessExecution = this . $store . getters . saveDataSuccessExecution ;
2019-07-10 09:06:26 -07:00
this . defaultValues . saveManualExecutions = this . $store . getters . saveManualExecutions ;
2019-06-23 03:35:23 -07:00
this . defaultValues . timezone = this . $store . getters . timezone ;
this . isLoading = true ;
const promises = [ ] ;
promises . push ( this . loadWorkflows ( ) ) ;
2019-07-10 11:53:13 -07:00
promises . push ( this . loadSaveDataErrorExecutionOptions ( ) ) ;
promises . push ( this . loadSaveDataSuccessExecutionOptions ( ) ) ;
2021-02-08 23:59:32 -08:00
promises . push ( this . loadSaveExecutionProgressOptions ( ) ) ;
2019-06-23 03:35:23 -07:00
promises . push ( this . loadSaveManualOptions ( ) ) ;
promises . push ( this . loadTimezones ( ) ) ;
try {
await Promise . all ( promises ) ;
} catch ( error ) {
this . $showError ( error , 'Problem loading settings' , 'The following error occurred loading the data:' ) ;
}
const workflowSettings = JSON . parse ( JSON . stringify ( this . $store . getters . workflowSettings ) ) ;
if ( workflowSettings . timezone === undefined ) {
workflowSettings . timezone = 'DEFAULT' ;
}
2019-07-10 11:53:13 -07:00
if ( workflowSettings . saveDataErrorExecution === undefined ) {
workflowSettings . saveDataErrorExecution = 'DEFAULT' ;
}
if ( workflowSettings . saveDataSuccessExecution === undefined ) {
workflowSettings . saveDataSuccessExecution = 'DEFAULT' ;
}
2021-02-08 23:59:32 -08:00
if ( workflowSettings . saveExecutionProgress === undefined ) {
workflowSettings . saveExecutionProgress = 'DEFAULT' ;
}
2019-07-10 09:06:26 -07:00
if ( workflowSettings . saveManualExecutions === undefined ) {
workflowSettings . saveManualExecutions = 'DEFAULT' ;
2019-06-23 03:35:23 -07:00
}
2020-07-29 05:12:54 -07:00
if ( workflowSettings . executionTimeout === undefined ) {
workflowSettings . executionTimeout = this . $store . getters . executionTimeout ;
}
if ( workflowSettings . maxExecutionTimeout === undefined ) {
workflowSettings . maxExecutionTimeout = this . $store . getters . maxExecutionTimeout ;
}
2019-06-23 03:35:23 -07:00
Vue . set ( this , 'workflowSettings' , workflowSettings ) ;
2020-07-29 05:12:54 -07:00
this . timeoutHMS = this . convertToHMS ( workflowSettings . executionTimeout ) ;
2019-06-23 03:35:23 -07:00
this . isLoading = false ;
} ,
async saveSettings ( ) {
// Set that the active state should be changed
const data : IWorkflowDataUpdate = {
settings : this . workflowSettings ,
} ;
2020-07-29 05:12:54 -07:00
// Convert hours, minutes, seconds into seconds for the workflow timeout
const { hours , minutes , seconds } = this . timeoutHMS ;
data . settings ! . executionTimeout =
data . settings ! . executionTimeout !== - 1
? hours * 3600 + minutes * 60 + seconds
: - 1 ;
if ( data . settings ! . executionTimeout === 0 ) {
this . $showError ( new Error ( 'timeout is activated but set to 0' ) , 'Problem saving settings' , 'There was a problem saving the settings:' ) ;
return ;
}
// @ts-ignore
if ( data . settings ! . executionTimeout > this . workflowSettings . maxExecutionTimeout ) {
const { hours , minutes , seconds } = this . convertToHMS ( this . workflowSettings . maxExecutionTimeout as number ) ;
this . $showError ( new Error ( ` Maximum Timeout is: ${ hours } hours, ${ minutes } minutes, ${ seconds } seconds ` ) , 'Problem saving settings' , 'Set timeout is exceeding the maximum timeout!' ) ;
return ;
}
delete data . settings ! . maxExecutionTimeout ;
2019-06-23 03:35:23 -07:00
this . isLoading = true ;
try {
await this . restApi ( ) . updateWorkflow ( this . $route . params . name , data ) ;
} catch ( error ) {
this . $showError ( error , 'Problem saving settings' , 'There was a problem saving the settings:' ) ;
this . isLoading = false ;
return ;
}
2019-07-10 11:53:13 -07:00
// Get the settings without the defaults set for local workflow settings
const localWorkflowSettings : IWorkflowSettings = { } ;
for ( const key of Object . keys ( this . workflowSettings ) ) {
if ( this . workflowSettings [ key ] !== 'DEFAULT' ) {
localWorkflowSettings [ key ] = this . workflowSettings [ key ] ;
}
}
2021-05-05 17:46:33 -07:00
const oldSettings = JSON . parse ( JSON . stringify ( this . $store . getters . workflowSettings ) ) ;
2019-07-10 11:53:13 -07:00
this . $store . commit ( 'setWorkflowSettings' , localWorkflowSettings ) ;
2019-06-23 03:35:23 -07:00
this . isLoading = false ;
this . $showMessage ( {
title : 'Settings saved' ,
message : 'The workflow settings got saved!' ,
type : 'success' ,
} ) ;
this . closeDialog ( ) ;
2021-05-05 17:46:33 -07:00
this . $externalHooks ( ) . run ( 'workflowSettings.saveSettings' , { oldSettings } ) ;
2019-06-23 03:35:23 -07:00
} ,
2020-07-29 05:12:54 -07:00
toggleTimeout ( ) {
this . workflowSettings . executionTimeout = this . workflowSettings . executionTimeout === - 1 ? 0 : - 1 ;
} ,
convertToHMS ( num : number ) : ITimeoutHMS {
if ( num > 0 ) {
let remainder : number ;
const hours = Math . floor ( num / 3600 ) ;
remainder = num % 3600 ;
const minutes = Math . floor ( remainder / 60 ) ;
const seconds = remainder % 60 ;
return { hours , minutes , seconds } ;
}
return { hours : 0 , minutes : 0 , seconds : 0 } ;
} ,
2019-06-23 03:35:23 -07:00
} ,
} ) ;
< / script >
< style scoped lang = "scss" >
. workflow - settings {
. el - row {
padding : 0.25 em 0 ;
}
}
. action - buttons {
margin - top : 1 em ;
text - align : right ;
}
. setting - info {
display : none ;
}
. setting - name {
line - height : 32 px ;
}
. setting - name : hover {
. setting - info {
display : inline ;
}
}
2020-07-29 05:12:54 -07:00
. timeout - setting - name {
text - align : center ;
width : calc ( 100 % - 20 px ) ;
}
2019-06-23 03:35:23 -07:00
< / style >