diff --git a/CHANGELOG.md b/CHANGELOG.md index bc12258c..cc4c2157 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [4.0.17] - 2023-11-07 + +### Fixed + +- AzureAD only returned first 100 groups. +- Constants with arrays now work correctly +- Little ldap test bug +- model bug, bad merging and weird caching + +### Added + +- Expression field can now have property `value` for manual data assignment +- Added form property ansibleCredentials, allowing to pass ansible_user and ansible_password + ## [4.0.16] - 2023-10-07 ### Changed @@ -590,7 +604,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Allow change password for current local user - Start tracking versions -[Unreleased]: https://github.com/ansibleguy76/ansibleforms/compare/4.0.16...HEAD +[Unreleased]: https://github.com/ansibleguy76/ansibleforms/compare/4.0.17...HEAD + +[4.0.17]: https://github.com/ansibleguy76/ansibleforms/compare/4.0.16...4.0.17 [4.0.16]: https://github.com/ansibleguy76/ansibleforms/compare/4.0.15...4.0.16 diff --git a/app_versions.gradle b/app_versions.gradle index 2680417f..01104665 100644 --- a/app_versions.gradle +++ b/app_versions.gradle @@ -1,2 +1,2 @@ -ext.version_code = 40016 -ext.version_name = "4.0.16" +ext.version_code = 40017 +ext.version_name = "4.0.17" diff --git a/client/package.json b/client/package.json index 99a9cd2a..26f7d74f 100644 --- a/client/package.json +++ b/client/package.json @@ -1,6 +1,6 @@ { "name": "ansible_forms_vue", - "version": "4.0.16", + "version": "4.0.17", "private": true, "scripts": { "serve": "vue-cli-service serve", @@ -12,9 +12,9 @@ "lint": "vue-cli-service lint" }, "dependencies": { - "core-js": "~3.33.0", - "vue": "~2.7", - "axios": "~1.5.1", + "core-js": "~3.33.2", + "vue": "~2.7.15", + "axios": "~1.6.0", "es6-promise": "~4.2.8", "vuelidate": "~0.7.7", "vue-router": "~3.5.4", @@ -37,10 +37,10 @@ "thenby": "*", "vue-showdown": "2.4.1", "bulma-calendar": "6.1.19", - "@fortawesome/fontawesome-svg-core":"~6.2.1", - "@fortawesome/free-solid-svg-icons":"~6.2.1", - "@fortawesome/free-regular-svg-icons":"~6.2.1", - "@fortawesome/free-brands-svg-icons":"~6.2.1", + "@fortawesome/fontawesome-svg-core":"~6.4.2", + "@fortawesome/free-solid-svg-icons":"~6.4.2", + "@fortawesome/free-regular-svg-icons":"~6.4.2", + "@fortawesome/free-brands-svg-icons":"~6.4.2", "@fortawesome/vue-fontawesome":"2.0.10", "@femessage/log-viewer":"*" diff --git a/client/public/assets/css/swagger.css b/client/public/assets/css/swagger.css index 17ddca5a..58f24b55 100644 --- a/client/public/assets/css/swagger.css +++ b/client/public/assets/css/swagger.css @@ -1,4 +1,4 @@ -.topbar-wrapper img[alt="Swagger UI"] { +.topbar-wrapper>a.link { content: url('/assets/img/logo_ansible_forms_full_white.svg'); } diff --git a/client/src/components/BulmaSettingsMenu.vue b/client/src/components/BulmaSettingsMenu.vue index 445d08fb..328b2a2d 100644 --- a/client/src/components/BulmaSettingsMenu.vue +++ b/client/src/components/BulmaSettingsMenu.vue @@ -31,7 +31,7 @@ {group:"authentication",title:"Groups",to:"/groups"}, {group:"authentication",title:"Users",to:"/users"}, {group:"authentication",title:"Ldap",to:"/ldap"}, - {group:"authentication",title:"Azure AD",to:"/azuread"}, + {group:"authentication",title:"MS Entra ID",to:"/azuread"}, {group:"connection",title:"Credentials",to:"/credentials"}, {group:"connection",title:"Ssh",to:"/sshkey"}, {group:"connection",title:"Known Hosts",to:"/knownhosts"}, diff --git a/client/src/components/Form.vue b/client/src/components/Form.vue index 6730ca36..4971e0fb 100644 --- a/client/src/components/Form.vue +++ b/client/src/components/Form.vue @@ -466,6 +466,7 @@ import Helpers from './../lib/Helpers' import Copy from 'copy-to-clipboard' import 'vue-json-pretty/lib/styles.css'; + import Lodash from 'lodash' import VueShowdown from 'vue-showdown'; import { required, minValue,maxValue,minLength,maxLength,helpers,requiredIf,sameAs } from 'vuelidate/lib/validators' @@ -1288,14 +1289,13 @@ foundfield=foundfield.replace(/\[[0-9]*\]/,'') // make xxx[y] => xxx fieldvalue = undefined targetflag = undefined - // console.log(foundfield + "("+fieldvalue+")" + " -> targetflag = " + targetflag) // mark the field as a dependent field if(foundfield in ref.form){ // does field xxx exist in our form ? // if the field exists // and it's from an expression or table // or it's deep link in a column (colum has .) // and the reference field is an object - if(ref.fieldOptions[foundfield] && (["expression","table"].includes(ref.fieldOptions[foundfield].type)||column.includes(".")) && (typeof ref.form[foundfield]=="object")){ + if(ref.fieldOptions[foundfield] && (["expression","table","constant"].includes(ref.fieldOptions[foundfield].type)||column.includes(".")) && ((typeof ref.form[foundfield]=="object") || (Array.isArray(ref.form[foundfield])))){ // objects and array should be stringified fieldvalue=JSON.stringify(ref.form[foundfield]) // console.log(Helpers.replacePlaceholders(match[1],ref.form)) @@ -1345,10 +1345,10 @@ value=undefined // cannot evaluate yet } if(value!=undefined){ - value=value.replace("'__undefined__'","undefined") // replace undefined values - value=value.replace("__undefined__","undefined") - value=value.replace("'__null__'","null") // replace undefined values - value=value.replace("__null__","null") + value=value.replaceAll("'__undefined__'","undefined") // replace undefined values + value=value.replaceAll("__undefined__","undefined") + value=value.replaceAll("'__null__'","null") // replace undefined values + value=value.replaceAll("__null__","null") } return {"hasPlaceholders":hasPlaceholders,"value":value} // return the result }, @@ -1582,6 +1582,10 @@ ref.$toast("Cannot reset field status " + item.name) } } + } else if(item.value && flag==undefined){ + ref.setFieldStatus(item.name,"running",false) + if(item.type=="expression") Vue.set(ref.form, item.name, item.value); + ref.setFieldStatus(item.name,"fixed") } }else{ // not visible field if(item.type=="expression"){ @@ -1826,26 +1830,28 @@ // generate the form json output generateJsonOutput(filedata={}){ var ref=this - this.formdata={} + var formdata={} this.currentForm.fields.forEach((item, i) => { // this.checkDependencies(item) // hide field based on dependency if(this.visibility[item.name] && !item.noOutput){ var fieldmodel = [].concat(item.model || []) var outputObject = item.outputObject || item.type=="expression" || item.type=="file" || item.type=="table" || false - var outputValue + var outputValue = undefined // if uploaded file info, use that if(item.name in filedata){ outputValue=filedata[item.name] // else just use the formdata }else{ - outputValue = this.form[item.name] + // deep clone, otherwise weird effects + outputValue = JSON.parse(JSON.stringify(this.form[item.name])) } // if no model is given, we assign to the root if(!outputObject){ // do we need to flatten output ? outputValue=this.getFieldValue(outputValue,item.valueColumn || "",true) } if(fieldmodel.length==0){ - this.formdata[item.name]=outputValue + // deep clone = otherwise weird effects + formdata[item.name]=JSON.parse(JSON.stringify(outputValue)) }else{ fieldmodel.forEach((f)=>{ // convert fieldmodel for actual object @@ -1853,9 +1859,15 @@ // using reduce, which is a recursive function f.split(/\s*\.\s*/).reduce((master,obj, level,arr) => { // if last + if (level === (arr.length - 1)){ // the last piece we assign the value to - master[obj]=outputValue + if(master[obj]===undefined){ + master[obj]=outputValue + }else{ + master[obj]=Lodash.merge(master[obj],outputValue) + } + }else{ // initialize first time to object if(master[obj]===undefined){ @@ -1865,13 +1877,14 @@ // return the result for next reduce iteration return master[obj] - },ref.formdata); + },formdata); }) } } }); - + // update main data + Vue.set(this,"formdata",formdata) }, // validate form before submit validateForm(){ @@ -1977,7 +1990,6 @@ .forEach(f => { postdata.credentials[f.name]=this.formdata[f.name] }) - this.jobResult.message= "Connecting with job api "; this.jobResult.status="info"; @@ -2106,7 +2118,7 @@ Vue.set(ref.fieldOptions,item.name,{}) // storing some easy to find options Vue.set(ref.fieldOptions[item.name],"evalDefault",item.evalDefault??false) if(["expression","query","enum","table","html"].includes(item.type)){ - Vue.set(ref.fieldOptions[item.name],"isDynamic",!!(item.expression??item.query??false)) + Vue.set(ref.fieldOptions[item.name],"isDynamic",!!(item.expression??item.query??item.value??false)) Vue.set(ref.fieldOptions[item.name],"valueColumn",item.valueColumn||"") Vue.set(ref.fieldOptions[item.name],"placeholderColumn",item.placeholderColumn||"") Vue.set(ref.fieldOptions[item.name],"type",item.type) @@ -2133,6 +2145,9 @@ // initiate the constants if(ref.constants){ Object.keys(ref.constants).forEach((item)=>{ + ref.fieldOptions[item]={ + type: "constant", + } Vue.set(ref.form,item,ref.constants[item]) }) } diff --git a/client/src/views/AzureAd.vue b/client/src/views/AzureAd.vue index d9a77063..169d5ac2 100644 --- a/client/src/views/AzureAd.vue +++ b/client/src/views/AzureAd.vue @@ -1,7 +1,7 @@