|
41 | 41 | <span class="icon is-pulled-right" v-show="loopbusy">
|
42 | 42 | <font-awesome-icon icon="spinner" size="lg" class="has-text-warning" spin />
|
43 | 43 | </span>
|
| 44 | + <span class="icon is-pulled-right has-tooltip-arrow has-tooltip-multiline has-tooltip-warning" v-show="!canSubmit && !loopbusy" :data-tooltip="unevaluatedFieldsWarning"> |
| 45 | + <font-awesome-icon icon="exclamation-triangle" size="lg" class="has-text-warning" /> |
| 46 | + </span> |
44 | 47 | <!-- reload button -->
|
45 | 48 | <button @click="reloadForm" class="button is-white is-small mr-3">
|
46 | 49 | <span class="has-text-info icon">
|
|
362 | 365 | <p class="has-text-danger" v-if="'maxLength' in $v.form[field.name] && !$v.form[field.name].maxLength">Can not be more than {{$v.form[field.name].$params.maxLength.max}} characters long</p>
|
363 | 366 | <p class="has-text-danger" v-if="'minValue' in $v.form[field.name] && !$v.form[field.name].minValue">Value cannot be lower than {{$v.form[field.name].$params.minValue.min}}</p>
|
364 | 367 | <p class="has-text-danger" v-if="'maxValue' in $v.form[field.name] && !$v.form[field.name].maxValue">Value cannot be higher than {{$v.form[field.name].$params.maxValue.max}}</p>
|
365 |
| - <p class="has-text-danger" v-if="'minSize' in $v.form[field.name] && !$v.form[field.name].minSize">{{$v.form[field.name].$params.minSize.description}}</p> |
366 |
| - <p class="has-text-danger" v-if="'maxSize' in $v.form[field.name] && !$v.form[field.name].maxSize">{{$v.form[field.name].$params.maxSize.description}}</p> |
367 |
| - <p class="has-text-danger" v-if="'regex' in $v.form[field.name] && !$v.form[field.name].regex">{{$v.form[field.name].$params.regex.description}}</p> |
368 |
| - <p class="has-text-danger" v-if="'validIf' in $v.form[field.name] && !$v.form[field.name].validIf">{{$v.form[field.name].$params.validIf.description}}</p> |
369 |
| - <p class="has-text-danger" v-if="'validIfNot' in $v.form[field.name] && !$v.form[field.name].validIfNot">{{$v.form[field.name].$params.validIfNot.description}}</p> |
370 |
| - <p class="has-text-danger" v-if="'notIn' in $v.form[field.name] && !$v.form[field.name].notIn">{{$v.form[field.name].$params.notIn.description}}</p> |
371 |
| - <p class="has-text-danger" v-if="'in' in $v.form[field.name] && !$v.form[field.name].in">{{$v.form[field.name].$params.in.description}}</p> |
| 368 | + <p class="has-text-danger" v-if="'minSize' in $v.form[field.name] && !$v.form[field.name].minSize">{{ replacePlaceholderInString($v.form[field.name].$params.minSize.description,true).value }}</p> |
| 369 | + <p class="has-text-danger" v-if="'maxSize' in $v.form[field.name] && !$v.form[field.name].maxSize">{{ replacePlaceholderInString($v.form[field.name].$params.maxSize.description,true).value }}</p> |
| 370 | + <p class="has-text-danger" v-if="'regex' in $v.form[field.name] && !$v.form[field.name].regex">{{ replacePlaceholderInString($v.form[field.name].$params.regex.description,true).value }}</p> |
| 371 | + <p class="has-text-danger" v-if="'validIf' in $v.form[field.name] && !$v.form[field.name].validIf">{{ replacePlaceholderInString($v.form[field.name].$params.validIf.description,true).value }}</p> |
| 372 | + <p class="has-text-danger" v-if="'validIfNot' in $v.form[field.name] && !$v.form[field.name].validIfNot">{{ replacePlaceholderInString($v.form[field.name].$params.validIfNot.description,true).value }}</p> |
| 373 | + <p class="has-text-danger" v-if="'notIn' in $v.form[field.name] && !$v.form[field.name].notIn">{{ replacePlaceholderInString($v.form[field.name].$params.notIn.description,true).value }}</p> |
| 374 | + <p class="has-text-danger" v-if="'in' in $v.form[field.name] && !$v.form[field.name].in">{{ replacePlaceholderInString($v.form[field.name].$params.in.description,true).value }}</p> |
372 | 375 | <p class="has-text-danger" v-if="'sameAs' in $v.form[field.name] && !$v.form[field.name].sameAs">Field must be identical to '{{$v.form[field.name].$params.sameAs.eq}}'</p>
|
373 | 376 | </div>
|
374 | 377 | </div>
|
|
380 | 383 | <!-- job buttons -->
|
381 | 384 | <hr v-if="!!currentForm" />
|
382 | 385 | <!-- play button -->
|
383 |
| - <button v-if="!!currentForm && !jobResult.message" class="button is-primary is-fullwidth" @click="jobResult.message='initializing'"><span class="icon"><font-awesome-icon icon="play" /></span><span>Run</span></button> |
| 386 | + <button v-if="!!currentForm && !jobResult.message" class="button is-primary is-fullwidth has-tooltip-multiline has-tooltip-arrow has-tooltip-warning" :data-tooltip="(!canSubmit)?unevaluatedFieldsWarning:undefined" :disabled="!canSubmit" @click="jobResult.message='initializing'"><span class="icon"><font-awesome-icon icon="play" /></span><span>Run</span></button> |
384 | 387 | <div class="columns">
|
385 | 388 | <!-- progress/close button -->
|
386 | 389 | <div class="column">
|
|
513 | 516 | subjob:{}, // output of last subjob
|
514 | 517 | dynamicFieldDependencies:{}, // which fields need to be re-evaluated if other fields change
|
515 | 518 | dynamicFieldDependentOf:{}, // which fields are dependend from others
|
| 519 | + unevaluatedFields:[], // list of unevaluatedFields |
516 | 520 | defaults:{}, // holds default info per field
|
517 | 521 | dynamicFieldStatus:{}, // holds the status of dynamics fields (running=currently being evaluated, variable=depends on others, fixed=only need 1-time lookup, default=has defaulted, undefined=trigger eval/query)
|
518 | 522 | queryresults:{}, // holds the results of dynamic dropdown boxes
|
|
654 | 658 | return obj
|
655 | 659 | },
|
656 | 660 | computed: {
|
| 661 | + // unevaluatedFieldsWarning |
| 662 | + unevaluatedFieldsWarning(){ |
| 663 | + if(this.canSubmit){ |
| 664 | + return undefined |
| 665 | + }else{ |
| 666 | + return this.unevaluatedFields.join(",") + " " + ((this.unevaluatedFields.length==1)?"is":"are") + " unevaluated..." |
| 667 | + } |
| 668 | + }, |
657 | 669 | // joboutput
|
658 | 670 | filteredJobOutput(){
|
659 | 671 | if(!this.filterOutput) return this.jobResult?.data?.output?.replace(/\r\n/g,"<br>")
|
|
1396 | 1408 | //console.log("enter loop");
|
1397 | 1409 | // ref.$toast("... loop ...")
|
1398 | 1410 | hasUnevaluatedFields=false; // reset flag
|
| 1411 | + ref.unevaluatedFields=[]; // the list of unevaluatedfields - reset |
1399 | 1412 | // console.log("-------------------------------")
|
1400 | 1413 | ref.currentForm.fields.forEach(
|
1401 | 1414 | function(item,index){
|
|
1408 | 1421 | // console.log("eval expression " + item.name)
|
1409 | 1422 | // console.log(`[${item.name}][${flag}] : evaluating`)
|
1410 | 1423 | hasUnevaluatedFields=true // set the un-eval flag if this is required
|
| 1424 | + ref.unevaluatedFields.push(item.name) |
1411 | 1425 | // set flag running
|
1412 | 1426 | ref.setFieldStatus(item.name,"running",false)
|
1413 | 1427 | placeholderCheck = ref.replacePlaceholders(item) // check and replace placeholders
|
|
1524 | 1538 | // console.log("eval query : " + item.name)
|
1525 | 1539 | // set flag running
|
1526 | 1540 | hasUnevaluatedFields=true
|
| 1541 | + ref.unevaluatedFields.push(item.name) |
1527 | 1542 | ref.setFieldStatus(item.name,"running",false)
|
1528 | 1543 | placeholderCheck = ref.replacePlaceholders(item) // check and replace placeholders
|
1529 | 1544 | if(placeholderCheck.value!=undefined){ // expression is clean ?
|
|
1653 | 1668 | if(ref.watchdog>50){ // is it taking too long ?
|
1654 | 1669 | ref.jobResult.message="" // stop and reset
|
1655 | 1670 | ref.$toast.warning("It took too long to evaluate all fields before run.\r\nLet the form stabilize and try again.")
|
| 1671 | + ref.$toast.warning(ref.unevaluatedFieldsWarning) |
1656 | 1672 | }else{
|
1657 | 1673 | //ref.$toast.info(`Stabilizing form...${ref.watchdog}`)
|
1658 | 1674 | }
|
|
1839 | 1855 | generateJsonOutput(filedata={}){
|
1840 | 1856 | var ref=this
|
1841 | 1857 | var formdata={}
|
1842 |
| - this.currentForm.fields.forEach((item, i) => { |
1843 |
| - // this.checkDependencies(item) // hide field based on dependency |
1844 |
| - if(this.visibility[item.name] && !item.noOutput){ |
1845 |
| - var fieldmodel = [].concat(item.model || []) |
1846 |
| - var outputObject = item.outputObject || item.type=="expression" || item.type=="file" || item.type=="table" || false |
1847 |
| - var outputValue = undefined |
1848 |
| - // if uploaded file info, use that |
1849 |
| - if(item.name in filedata){ |
1850 |
| - outputValue=filedata[item.name] |
1851 |
| - // else just use the formdata |
1852 |
| - }else{ |
1853 |
| - // deep clone, otherwise weird effects |
1854 |
| - outputValue = Helpers.deepClone(this.form[item.name]) |
1855 |
| - } |
1856 |
| - // if no model is given, we assign to the root |
1857 |
| - if(!outputObject){ // do we need to flatten output ? |
1858 |
| - outputValue=this.getFieldValue(outputValue,item.valueColumn || "",true) |
1859 |
| - } |
1860 |
| - if(fieldmodel.length==0){ |
1861 |
| - // deep clone = otherwise weird effects |
1862 |
| - formdata[item.name]=Helpers.deepClone(outputValue) |
1863 |
| - }else{ |
1864 |
| - fieldmodel.forEach((f)=>{ |
1865 |
| - // convert fieldmodel for actual object |
1866 |
| - // svm.lif.name => svm["lif"].name = formvalue |
1867 |
| - // using reduce, which is a recursive function |
1868 |
| - f.split(/\s*\.\s*/).reduce((master,obj, level,arr) => { |
1869 |
| - // if last |
1870 |
| - |
1871 |
| - if (level === (arr.length - 1)){ |
| 1858 | + try{ |
| 1859 | + this.currentForm.fields.forEach((item, i) => { |
| 1860 | + // this.checkDependencies(item) // hide field based on dependency |
| 1861 | + if(this.visibility[item.name] && !item.noOutput){ |
| 1862 | + var fieldmodel = [].concat(item.model || []) |
| 1863 | + var outputObject = item.outputObject || item.type=="expression" || item.type=="file" || item.type=="table" || false |
| 1864 | + var outputValue = undefined |
| 1865 | + // if uploaded file info, use that |
| 1866 | + if(item.name in filedata){ |
| 1867 | + outputValue=filedata[item.name] |
| 1868 | + // else just use the formdata |
| 1869 | + }else{ |
| 1870 | + // deep clone, otherwise weird effects |
| 1871 | + outputValue = Helpers.deepClone(this.form[item.name]) |
| 1872 | + } |
| 1873 | + // if no model is given, we assign to the root |
| 1874 | + if(!outputObject){ // do we need to flatten output ? |
| 1875 | + outputValue=this.getFieldValue(outputValue,item.valueColumn || "",true) |
| 1876 | + } |
| 1877 | + if(fieldmodel.length==0){ |
| 1878 | + // deep clone = otherwise weird effects |
| 1879 | + formdata[item.name]=Helpers.deepClone(outputValue) |
| 1880 | + }else{ |
| 1881 | +
|
| 1882 | + // here we build the full model object |
| 1883 | + fieldmodel.forEach((f)=>{ |
| 1884 | + // convert fieldmodel for actual object |
| 1885 | + // svm.lif.name => svm["lif"].name = formvalue |
| 1886 | + // using reduce, which is a recursive function |
| 1887 | + f.split(/\s*\.\s*/).reduce((master,obj, level,arr) => { |
| 1888 | +
|
| 1889 | + var arrsplit = undefined |
| 1890 | +
|
| 1891 | + // if last |
| 1892 | + if (level === (arr.length - 1)){ |
| 1893 | + |
| 1894 | +
|
1872 | 1895 | // the last piece we assign the value to
|
1873 |
| - if(master[obj]===undefined){ |
1874 |
| - master[obj]=outputValue |
1875 |
| - }else{ |
1876 |
| - master[obj]=Lodash.merge(master[obj],outputValue) |
| 1896 | + // if the last piece is an array, we need to create the array first |
| 1897 | + if(obj.match(/.*\[[0-9]+\]$/)){ |
| 1898 | + // split the array name and index |
| 1899 | + arrsplit=obj.split(/\[([0-9]+)\]$/) |
| 1900 | + // if the array doesn't exist, we create it |
| 1901 | + if(master[arrsplit[0]]===undefined){ |
| 1902 | + master[arrsplit[0]]=[] |
| 1903 | + } |
| 1904 | + // if the array index doesn't exist, we create it |
| 1905 | + if(master[arrsplit[0]][arrsplit[1]]===undefined){ |
| 1906 | + master[arrsplit[0]][arrsplit[1]]={} |
| 1907 | + } |
| 1908 | + // assign the value to the array index |
| 1909 | + master[arrsplit[0]][arrsplit[1]]=outputValue |
| 1910 | + |
| 1911 | + return master[arrsplit[0]][arrsplit[1]] |
| 1912 | + |
| 1913 | + }else{ // just an object |
| 1914 | +
|
| 1915 | + // if the object doesn't exist, we create it |
| 1916 | + if(master[obj]===undefined){ |
| 1917 | + master[obj]=outputValue |
| 1918 | + }else{ |
| 1919 | + master[obj]=Lodash.merge(master[obj],outputValue) |
| 1920 | + } |
| 1921 | + |
| 1922 | + // return the result for next reduce iteration |
| 1923 | + return master[obj] |
| 1924 | + |
1877 | 1925 | }
|
1878 |
| - |
1879 |
| - }else{ |
1880 |
| - // initialize first time to object |
1881 |
| - if(master[obj]===undefined){ |
1882 |
| - master[obj]={} |
| 1926 | +
|
| 1927 | + |
| 1928 | +
|
| 1929 | + }else{ |
| 1930 | + // initialize first time to object or array |
| 1931 | +
|
| 1932 | + // if the object is an array, we need to create the array first |
| 1933 | + if(obj.match(/.*\[[0-9]+\]$/)){ |
| 1934 | + // split the array name and index |
| 1935 | + arrsplit=obj.split(/\[([0-9]+)\]$/) |
| 1936 | + // if the array doesn't exist, we create it |
| 1937 | + if(master[arrsplit[0]]===undefined){ |
| 1938 | + master[arrsplit[0]]=[] |
| 1939 | + } |
| 1940 | + // if the array index doesn't exist, we create it |
| 1941 | + if(master[arrsplit[0]][arrsplit[1]]===undefined){ |
| 1942 | + master[arrsplit[0]][arrsplit[1]]={} |
| 1943 | + } |
| 1944 | +
|
| 1945 | + // return the result for next reduce iteration |
| 1946 | + return master[arrsplit[0]][arrsplit[1]] |
| 1947 | +
|
| 1948 | + }else{ // just an object |
| 1949 | +
|
| 1950 | + // if the object doesn't exist, we create it |
| 1951 | + if(master[obj]===undefined){ |
| 1952 | + master[obj]={} |
| 1953 | + } |
| 1954 | + // return the result for next reduce iteration |
| 1955 | + return master[obj] |
1883 | 1956 | }
|
1884 |
| - } |
1885 |
| - // return the result for next reduce iteration |
1886 |
| - return master[obj] |
1887 | 1957 |
|
1888 |
| - },formdata); |
1889 |
| - }) |
| 1958 | + } |
| 1959 | +
|
| 1960 | +
|
| 1961 | + },formdata); |
| 1962 | +
|
| 1963 | + }) |
1890 | 1964 |
|
| 1965 | + } |
1891 | 1966 | }
|
1892 |
| - } |
1893 |
| - }); |
| 1967 | + }); |
| 1968 | + }catch(err){ |
| 1969 | + console.log(err) |
| 1970 | + ref.$toast.error("Failed to generate json output.\r\nContact the developer.\r\n" + (err.message || err.toString())) |
| 1971 | + } |
1894 | 1972 | // update main data
|
1895 | 1973 | Vue.set(this,"formdata",formdata)
|
1896 | 1974 | },
|
|
0 commit comments