2019-06-23 03:35:23 -07:00
< template >
< div @ keydown.stop class = "credentials-input-wrapper" >
< el -row >
2019-06-24 05:45:03 -07:00
< el -col :span ="6" class = "headline-regular" >
Credentials Name :
< el -tooltip class = "credentials-info" placement = "top" effect = "light" >
< div slot = "content" v-html ="helpTexts.credentialsName" > < / div >
< font -awesome -icon icon = "question-circle" / >
< / e l - t o o l t i p >
2019-06-23 03:35:23 -07:00
< / e l - c o l >
< el -col :span ="18" >
< el -input size = "small" type = "text" v-model ="name" > < / el -input >
< / e l - c o l >
< / e l - r o w >
< br / >
< div class = "headline" >
Credential Data :
2019-06-24 05:45:03 -07:00
< el -tooltip class = "credentials-info" placement = "top" effect = "light" >
< div slot = "content" v-html ="helpTexts.credentialsData" > < / div >
< font -awesome -icon icon = "question-circle" / >
< / e l - t o o l t i p >
2019-06-23 03:35:23 -07:00
< / div >
< el -row v-for ="parameter in credentialTypeData.properties" :key="parameter.name" class="parameter-wrapper" >
2019-11-17 13:38:37 -08:00
< el -col :span ="6" class = "parameter-name" >
2019-06-23 03:35:23 -07:00
{ { parameter . displayName } } :
2019-11-17 13:38:37 -08:00
< el -tooltip placement = "top" class = "parameter-info" v-if ="parameter.description" effect="light" >
< div slot = "content" v-html ="parameter.description" > < / div >
< font -awesome -icon icon = "question-circle" / >
< / e l - t o o l t i p >
2019-06-23 03:35:23 -07:00
< / e l - c o l >
< el -col :span ="18" >
< parameter -input :parameter ="parameter" :value ="propertyValue[parameter.name]" :path ="parameter.name" :isCredential ="true" @valueChanged ="valueChanged" / >
< / e l - c o l >
< / e l - r o w >
< el -row class = "nodes-access-wrapper" >
< el -col :span ="6" class = "headline" >
Nodes with access :
2019-06-24 05:45:03 -07:00
< el -tooltip class = "credentials-info" placement = "top" effect = "light" >
< div slot = "content" v-html ="helpTexts.nodesWithAccess" > < / div >
< font -awesome -icon icon = "question-circle" / >
< / e l - t o o l t i p >
2019-06-23 03:35:23 -07:00
< / e l - c o l >
< el -col :span ="18" >
< el -transfer
: titles = "['No Access', 'Access ']"
v - model = "nodesAccess"
: data = "allNodesRequestingAccess" >
< / e l - t r a n s f e r >
< div v-if ="nodesAccess.length === 0" class="no-nodes-access" >
< strong >
Important !
< / strong > < br / >
Add at least one node which has access to the credentials !
< / div >
< / e l - c o l >
< / e l - r o w >
< div class = "action-buttons" >
< el -button type = "success" @click ="updateCredentials" v-if ="credentialData" >
Save
< / e l - b u t t o n >
< el -button type = "success" @click ="createCredentials" v-else >
Create
< / e l - b u t t o n >
< / div >
< / div >
< / template >
< script lang = "ts" >
import Vue from 'vue' ;
import { restApi } from '@/components/mixins/restApi' ;
import { nodeHelpers } from '@/components/mixins/nodeHelpers' ;
2019-06-30 10:09:08 -07:00
import { showMessage } from '@/components/mixins/showMessage' ;
2019-06-23 03:35:23 -07:00
import { ICredentialsDecryptedResponse , IUpdateInformation } from '@/Interface' ;
import {
CredentialInformation ,
ICredentialDataDecryptedObject ,
ICredentialsDecrypted ,
ICredentialType ,
ICredentialNodeAccess ,
INodeCredentialDescription ,
INodeTypeDescription ,
} from 'n8n-workflow' ;
import ParameterInput from '@/components/ParameterInput.vue' ;
import mixins from 'vue-typed-mixins' ;
export default mixins (
nodeHelpers ,
restApi ,
2019-06-30 10:09:08 -07:00
showMessage ,
2019-06-23 03:35:23 -07:00
) . extend ( {
name : 'CredentialsInput' ,
props : [
'credentialTypeData' , // ICredentialType
'credentialData' , // ICredentialsDecryptedResponse
'nodesInit' , // {
// type: Array,
// default: () => { [] },
// }
] ,
components : {
ParameterInput ,
} ,
data ( ) {
return {
2019-06-24 05:45:03 -07:00
helpTexts : {
credentialsData : 'The credentials to set.' ,
credentialsName : 'The name the credentials should be saved as. Use a name<br />which makes it clear to what exactly they give access to.<br />For credentials of an Email account that could be the Email address itself.' ,
nodesWithAccess : 'The nodes which allowed to use this credentials.' ,
} ,
2019-06-23 03:35:23 -07:00
nodesAccess : [ ] as string [ ] ,
name : '' ,
propertyValue : { } as ICredentialDataDecryptedObject ,
} ;
} ,
computed : {
allNodesRequestingAccess ( ) : Array < { key : string , label : string } > {
const returnNodeTypes : string [ ] = [ ] ;
const nodeTypes : INodeTypeDescription [ ] = this . $store . getters . allNodeTypes ;
let nodeType : INodeTypeDescription ;
let credentialTypeDescription : INodeCredentialDescription ;
// Find the node types which need the credentials
for ( nodeType of nodeTypes ) {
if ( ! nodeType . credentials ) {
continue ;
}
for ( credentialTypeDescription of nodeType . credentials ) {
if ( credentialTypeDescription . name === ( this . credentialTypeData as ICredentialType ) . name && ! returnNodeTypes . includes ( credentialTypeDescription . name ) ) {
returnNodeTypes . push ( nodeType . name ) ;
break ;
}
}
}
// Return the data in the correct format el-transfer expects
return returnNodeTypes . map ( ( nodeTypeName : string ) => {
return {
key : nodeTypeName ,
label : this . $store . getters . nodeType ( nodeTypeName ) . displayName as string ,
} ;
} ) ;
} ,
} ,
methods : {
valueChanged ( parameterData : IUpdateInformation ) {
2019-07-10 02:46:59 -07:00
const name = parameterData . name . split ( '.' ) . pop ( ) as string ;
// For a currently for me unknown reason can In not simply just
// set the value and it has to be this way.
const tempValue = JSON . parse ( JSON . stringify ( this . propertyValue ) ) ;
tempValue [ name ] = parameterData . value ;
Vue . set ( this , 'propertyValue' , tempValue ) ;
2019-06-23 03:35:23 -07:00
} ,
2019-06-30 10:09:08 -07:00
async createCredentials ( ) : Promise < void > {
2019-06-23 03:35:23 -07:00
const nodesAccess = this . nodesAccess . map ( ( nodeType ) => {
return {
nodeType ,
} ;
} ) ;
const newCredentials = {
name : this . name ,
type : ( this . credentialTypeData as ICredentialType ) . name ,
nodesAccess ,
data : this . propertyValue ,
} as ICredentialsDecrypted ;
2019-06-30 10:09:08 -07:00
let result ;
try {
result = await this . restApi ( ) . createNewCredentials ( newCredentials ) ;
} catch ( error ) {
this . $showError ( error , 'Problem Creating Credentials' , 'There was a problem creating the credentials:' ) ;
return ;
}
2019-06-23 03:35:23 -07:00
// Add also to local store
this . $store . commit ( 'addCredentials' , result ) ;
this . $emit ( 'credentialsCreated' , result ) ;
} ,
async updateCredentials ( ) {
const nodesAccess : ICredentialNodeAccess [ ] = [ ] ;
const addedNodeTypes : string [ ] = [ ] ;
// Add Node-type which already had access to keep the original added date
let nodeAccessData : ICredentialNodeAccess ;
for ( nodeAccessData of ( this . credentialData as ICredentialsDecryptedResponse ) . nodesAccess ) {
if ( this . nodesAccess . includes ( ( nodeAccessData . nodeType ) ) ) {
nodesAccess . push ( nodeAccessData ) ;
addedNodeTypes . push ( nodeAccessData . nodeType ) ;
}
}
// Add Node-type which did not have access before
for ( const nodeType of this . nodesAccess ) {
if ( ! addedNodeTypes . includes ( nodeType ) ) {
nodesAccess . push ( {
nodeType ,
} ) ;
}
}
const newCredentials = {
name : this . name ,
type : ( this . credentialTypeData as ICredentialType ) . name ,
nodesAccess ,
data : this . propertyValue ,
} as ICredentialsDecrypted ;
2019-06-30 10:09:08 -07:00
let result ;
try {
result = await this . restApi ( ) . updateCredentials ( ( this . credentialData as ICredentialsDecryptedResponse ) . id as string , newCredentials ) ;
2019-07-01 05:52:14 -07:00
} catch ( error ) {
2019-06-30 10:09:08 -07:00
this . $showError ( error , 'Problem Updating Credentials' , 'There was a problem updating the credentials:' ) ;
return ;
}
2019-06-23 03:35:23 -07:00
// Update also in local store
this . $store . commit ( 'updateCredentials' , result ) ;
// Now that the credentials changed check if any nodes use credentials
// which have now a different name
this . updateNodesCredentialsIssues ( ) ;
this . $emit ( 'credentialsUpdated' , result ) ;
} ,
init ( ) {
if ( this . credentialData ) {
// Initialize with the given data
this . name = ( this . credentialData as ICredentialsDecryptedResponse ) . name ;
this . propertyValue = ( this . credentialData as ICredentialsDecryptedResponse ) . data as ICredentialDataDecryptedObject ;
const nodesAccess = ( this . credentialData as ICredentialsDecryptedResponse ) . nodesAccess . map ( ( nodeAccess ) => {
return nodeAccess . nodeType ;
} ) ;
Vue . set ( this , 'nodesAccess' , nodesAccess ) ;
} else {
// No data supplied so init empty
this . name = '' ;
this . propertyValue = { } as ICredentialDataDecryptedObject ;
const nodesAccess = [ ] as string [ ] ;
nodesAccess . push . apply ( nodesAccess , this . nodesInit ) ;
Vue . set ( this , 'nodesAccess' , nodesAccess ) ;
}
// Set default values
for ( const property of ( this . credentialTypeData as ICredentialType ) . properties ) {
if ( ! this . propertyValue . hasOwnProperty ( property . name ) ) {
this . propertyValue [ property . name ] = property . default as CredentialInformation ;
}
}
} ,
} ,
watch : {
credentialData ( ) {
this . init ( ) ;
} ,
credentialTypeData ( ) {
this . init ( ) ;
} ,
} ,
mounted ( ) {
this . init ( ) ;
} ,
} ) ;
< / script >
< style lang = "scss" >
. credentials - input - wrapper {
. action - buttons {
margin - top : 2 em ;
text - align : right ;
}
. headline {
font - weight : 600 ;
color : $ -- color - primary ;
margin - bottom : 1 em ;
}
. nodes - access - wrapper {
margin - top : 1 em ;
}
. no - nodes - access {
margin : 1 em 0 ;
color : $ -- color - primary ;
line - height : 1.75 em ;
}
. parameter - wrapper {
line - height : 3 em ;
2019-11-17 13:38:37 -08:00
. parameter - name {
position : relative ;
& : hover {
. parameter - info {
display : inline ;
}
}
. parameter - info {
display : none ;
}
}
2019-06-23 03:35:23 -07:00
}
2019-06-24 05:45:03 -07:00
. credentials - info {
display : none ;
}
. headline : hover ,
. headline - regular : hover {
. credentials - info {
display : inline ;
}
}
2019-06-23 03:35:23 -07:00
}
< / style >