Skip to content

Instantly share code, notes, and snippets.

@rikyperdana
Created May 14, 2024 01:23
Show Gist options
  • Save rikyperdana/be33c82ae6bb069aad565ff69d904758 to your computer and use it in GitHub Desktop.
Save rikyperdana/be33c82ae6bb069aad565ff69d904758 to your computer and use it in GitHub Desktop.
All minified AutoForm + AutoTable + MitGen
var m,_,afState={arrLen:{},form:{}},{stringify,parse}=JSON,autoForm=opts=>({view:()=>{var withAs=(obj,cb)=>cb(obj),ifit=(obj,cb)=>Boolean(obj)&&cb(obj),ors=array=>array.find(Boolean),ands=array=>array.reduce((a,b)=>a&&b,true),normal=name=>name.replace(/\d/g,'$'),fileData=(key,val)=>{var form=new FormData();form.append(key,val);return form},dateValue=(timestamp,hour)=>{var date=new Date(timestamp),zeros=num=>num<10?'0'+num:''+num,dateStamp=[date.getFullYear(),zeros(date.getMonth()+1),zeros(date.getDate())].join('-'),hourStamp=['T',zeros(date.getHours()),':',zeros(date.getMinutes())].join('');return!hour?dateStamp:dateStamp+hourStamp},linearize=obj=>{var recurse=doc=>withAs(doc[_.keys(doc)[0]],value=>typeof(value)==='object'?_.map(value,(val,key)=>recurse({[_.keys(doc)[0]+'.'+key]:val})):doc);return _.fromPairs(_.flattenDeep(recurse({doc:obj})).map(i=>[_.keys(i)[0].substr(4),_.values(i)[0]]))}afState.form[opts.id]=opts.doc?_.assign(afState.form[opts.id],linearize(opts.doc)):afState.form[opts.id];var attr={form:{id:opts.id,oncreate:opts.oncreate,onchange:e=>[e.redraw=false,afState.form[opts.id]=afState.form[opts.id]||{},afState.form[opts.id][e.target.name]=e.target.value],onsubmit:e=>{e.preventDefault();afState.form[opts.id]=opts.autoReset&&null;var submit=()=>opts.action(_.filter(e.target,i=>i.name&&i.value).map(obj=>withAs(opts.schema[normal(obj.name)].type,type=>_.reduceRight(obj.name.split('.'),(res,inc)=>({[inc]:res}),(obj.checked||obj.value)&&ors([((type===String)&&obj.value),((type===Number)&& +ors([obj.checked&&_.last(obj.name.split('.')),obj.value])),((type===Date)&&(new Date(obj.value)).getTime())])))).reduce((res,inc)=>{var recursive=data=>ors([typeof(data)==='object'&&withAs({key:_.keys(data)[0],val:_.values(data)[0]},({key,val})=>ors([+key+1&&_.range(+key+1).map(i=>i=== +key?recursive(val):undefined),{[key]:recursive(val)}])),data]);return _.merge(res,recursive(inc))},{}),opts);!opts.confirmMessage?submit():confirm(opts.confirmMessage)&&submit()}},arrLen:(name,type)=>({onclick:()=>{afState.arrLen[name]=_.get(afState.arrLen,name)||0;var dec=afState.arrLen[name]>0?-1:0;afState.arrLen[name]+=({inc:1,dec})[type]}}),label:(name,schema)=>m('label.label',m('span',schema.label||_.startCase(name.split('.').map(i=> +i+1? +i+1:i).join('.'))),m('span',m('b.has-text-danger',!schema.optional&&' *')))},inputTypes=(name,schema)=>({file:()=>m('.field',attr.label(name,schema),withAs(_.get(afState.form,[opts.id,name]),thisFile=>thisFile?m('.field.has-addons',[m('input.input',{readonly:true,disabled:true,value:'100% '+parse(thisFile).ori}),m('.control',m('.button.is-danger',{onclick:()=>fetch('/unload',{headers:{'Content-Type':'application/json'},method:'post',body:thisFile}).then(res=>res.json()).then(res=>res.status===true&&(delete afState.form[opts.id][name])&&m.redraw())},'-'))]):[m('input.button',{type:'file',accept:withAs(_.get(schema,'autoform.accept'),extList=>!extList?'*':extList.map(i=>'.'+i).join(',')),onchange:e=>ands([(_.get(schema,'autoform.limit')||1e10)>e.target.files[0].size,withAs(_.get(schema,'autoform.accept'),extList=>extList?extList.includes(e.target.files[0].name.split('.').slice(-1)[0]):true)])&&fetch('/upload',{method:'post',body:fileData(name,e.target.files[0])}).then(res=>res.json()).then(res=>_.assign(afState.form[opts.id],{[name]:stringify({id:res[name].newFilename,ori:res[name].originalFilename,size:res[name].size,ext:res[name].mimetype.split('/')[1]})})&&m.redraw())}),m('p.help',_.get(schema,'autoform.help'))]),m('input.input',{type:'hidden',name:!schema.exclude?name:'',value:_.get(afState.form,[opts.id,name])})),hidden:()=>m('input.input',{type:'hidden',name:!schema.exclude?name:'',value:schema.autoValue&&schema.autoValue(name,afState.form[opts.id],opts)}),readonly:()=>m('.field',attr.label(name,schema),m('input.input',{readonly:true,name:!schema.exclude?name:'',disabled:true,value:schema.autoValue(name,afState.form[opts.id],opts)}),m('p.help',_.get(schema,'autoform.help'))),"datetime-local":()=>m('.field',attr.label(name,schema),m('.control',m('input.input',{type:'datetime-local',name:!schema.exclude?name:'',required:!schema.optional,value:dateValue(_.get(afState.form,[opts.id,name]),true),onchange:schema.autoRedraw&&function(){}})),m('p.help',_.get(schema,'autoform.help'))),textarea:()=>m('.field',attr.label(name,schema),m('textarea.textarea',{name:!schema.exclude?name:'',required:!schema.optional,value:_.get(afState.form,[opts.id,name]),placeholder:_.get(schema,'autoform.placeholder'),rows:_.get(schema,'autoform.rows')||6,onchange:schema.autoRedraw&&function(){}}),m('p.help',_.get(schema,'autoform.help'))),password:()=>m('.field',attr.label(name,schema),m('input.input',{name:!schema.exclude?name:'',pattern:schema.regExp,required:!schema.optional,type:'password',placeholder:_.get(schema,'autoform.placeholder'),onchange:schema.autoRedraw&&function(){}}),m('p.help',_.get(schema,'autoform.help'))),checkbox:()=>m('.field.is-expanded',attr.label(name,schema),schema.autoform.options().map(i=>m('label.checkbox',m('input',{type:'checkbox',id:name+'.'+i.value,name:schema.exclude?'':name+'.'+i.value,value:Boolean(document.querySelector('#'+name+i.value+':checked'))}),i.label))),select:()=>m('.field.is-expanded',attr.label(name,schema),m('.select.is-fullwidth',m('select',{name:!schema.exclude?name:'',required:!schema.optional,value:_.get(afState.form,[opts.id,name]),onchange:schema.autoRedraw&&function(){}},m('option',{value:''},'-'),schema.autoform.options(name,afState.form[opts.id]).map(i=>m('option',{value:i.value,selected:!!_.get(afState.form,[opts.id,name])},i.label)))),m('p.help',_.get(schema,'autoform.help'))),standard:()=>ors([schema.type===Object&&m('.box',withAs(_.get(afState,`toggleHide.${opts.id }["${ name }"]`),toggleHide=>[m('.columns.is-mobile',[m('.column',attr.label(name,schema)),!_.get(schema,'autoform.noToggle')&&m('.column',m('span.tag',{style:{float:'right'},onclick:x=>[_.assign(afState,{toggleHide:{[opts.id]:{[name]:!toggleHide}}}),m.redraw()]},toggleHide?'Show':'Hide'))]),withAs(_.map(opts.schema,(val,key)=>_.merge(val,{name:key})).filter(i=>withAs(str=>_.size(_.split(str,'.')),getLen=>_.every([_.includes(i.name,normal(name)+'.'),getLen(name)+1===getLen(i.name)]))).map(i=>withAs({childSchema:opts.schema[normal(i.name)],fieldName:name+'.'+_.last(i.name.split('.'))},({childSchema,fieldName})=>({[fieldName]:()=>inputTypes(fieldName,childSchema)[_.get(childSchema,'autoform.type')||'standard']()}))),fields=>!toggleHide&&m('div',_.get(opts.layout,normal(name))?opts.layout[normal(name)].map(i=>m('.columns',i.map(j=>m('.column',fields.find(k=>k[name+'.'+j])[name+'.'+j]())))):fields.map(i=>_.values(i)[0]()))),m('p.help',_.get(schema,'autoform.help'))])),schema.type===Array&&m('.box',attr.label(name,schema),!schema.fixed&&m('.tags',m('.tag.is-success',attr.arrLen(name,'inc'),'Add+'),m('.tag.is-warning',attr.arrLen(name,'dec'),'Rem-'),m('.tag',afState.arrLen[name]),),_.range(_.get(opts.doc,name)&&opts.doc[name].length,afState.arrLen[name]).map(i=>withAs(opts.schema[normal(name)+'.$'],childSchema=>inputTypes(name+'.'+i,childSchema)[_.get(childSchema,'autoform.type')||'standard']())),m('p.help',_.get(schema,'autoform.help'))),m('.field',attr.label(name,schema),m('.control',m('input.input',{step:'any',name:!schema.exclude?name:'',placeholder:_.get(schema,'autoform.placeholder'),value:ors([schema.autoValue&&schema.autoValue(name,afState.form[opts.id],opts),schema.type===Date&&dateValue(_.get(afState.form,[opts.id,name])),_.get(afState.form,[opts.id,name])]),required:!schema.optional,pattern:schema.regExp,min:schema.minMax&&schema.minMax(name,afState.form[opts.id])[0],max:schema.minMax&&schema.minMax(name,afState.form[opts.id])[1],onchange:schema.autoRedraw&&function(){},type:_.findKey({date:Date,text:String,number:Number},(val,key)=>val===schema.type)})),m('p.help',_.get(schema,'autoform.help')))])}),fields=_.map(opts.schema,(val,key)=>!_.includes(key,'.')&&{[key]:()=>inputTypes(key,val)[_.get(val,'autoform.type')||'standard']()}).filter(Boolean);return m('form',attr.form,_.get(opts,'layout.top')?opts.layout.top.map(i=>m('.columns',i.map(j=>m('.column',fields.find(k=>k[j])[j]())))):fields.map(i=>_.values(i)[0]()),m('.row',m('.field.is-grouped',[{label:_.get(opts,'submit.value')||'Submit',opt:_.assign({type:'submit',class:'is-info'},opts.submit)},...(opts.buttons||[])].map(i=>m('.control',m('button.button',i.opt,i.label))))))}});var atState={},ors=array=>array.find(Boolean),ands=array=>array.reduce((a,b)=>a&&b,true),withAs=(obj,cb)=>cb(obj),ifit=(obj,cb)=>Boolean(obj)&&cb(obj),timestamp=str=> +(new Date(str)),atModify=(rows,opts)=>rows .filter(i=>withAs({start:_.get(atState,[opts.id,'start_range']),end:_.get(atState,[opts.id,'end_range']),func:eval(_.get(atState,[opts.id,'rangeFunc']))},({start,end,func})=>ands([start,end,timestamp(start)<timestamp(end)])?func(i,timestamp(start),timestamp(end)):i)).filter(i=>ands(_.map(_.get(atState,[opts.id,'filters']),(val,key)=>opts.filters[key].find(j=>j.label===val)).map(j=>j.func(i.data)))).filter(i=>_.values(i.row).map(_.lowerCase).join('').includes(_.get(atState,[opts.id,'search'])||'')).sort((a,b)=>_.get(atState,[opts.id,'sortBy'])&&_[_.get(atState,[opts.id,'sortWay'])?'gt':'lt'](a.row[_.get(atState,[opts.id,'sortBy'])],b.row[_.get(atState,[opts.id,'sortBy'])])?-1:1).slice((_.get(atState,[opts.id,'activeStep'])||0)*(_.get(atState,[opts.id,'pagination'])||0),((_.get(atState,[opts.id,'activeStep'])||0)*(_.get(atState,[opts.id,'pagination'])||0))+ors([_.get(atState,[opts.id,'activeStep']),_.get(opts,['showSteps',0]),opts.rows.length])),autoTable=opts=>({view:()=>m('.box',m('.columns',opts.search&&m('.column.is-10',m('form',{onsubmit:e=>[e.preventDefault(),_.assign(atState,{[opts.id]:{search:_.lowerCase(e.target[0].value)}}),m.redraw()]},m('.control.is-expanded',m('input.input.is-fullwidth',{type:'text',placeholder:'Search data'})))),opts.showSteps&&m('.column.is-2',m('.select.is-fullwidth',m('select',{onchange:e=>[_.assign(atState,{[opts.id]:_.merge(_.get(atState,opts.id),{activeStep: +e.target.value,pagination:0})})],value:_.get(atState,[opts.id,'activeStep'])},opts.showSteps.map(i=>m('option',{value:i},'Show '+i)))))),opts.timeRange&&m('.columns',m('.column',m('label.label','Criteria'),m('.select.is-fullwidth',m('select',{value:_.get(atState,[opts.id,'rangeFunc']),onchange:e=>_.merge(atState,{[opts.id]:{rangeFunc:e.target.value}})},[m('option',{value:0},'-'),..._.map(opts.timeRange,(func,label)=>m('option',{value:func},label))]))),['start_range','end_range'].map(i=>m('.column',m('label.label',_.startCase(i)),m('.control',m('input.input',{type:'datetime-local',name:i,value:_.get(atState,[opts.id,i]),onchange:e=>_.merge(atState,{[opts.id]:{[i]:e.target.value}})}))))),opts.filters&&m('.columns',_.map(opts.filters,(val,key)=>m('.column',m('.field',m('label.label',key),m('.select.is-fullwidth',m('select',{onchange:e=>_.assign(atState,{[opts.id]:_.merge(_.get(atState,opts.id),{filters:_.merge(_.get(atState,[opts.id,'filters'])||{},{[key]:e.target.value})})}),value:_.values(_.get(atState,[opts.id,'filters'])||{}).find(i=>val.map(j=>j.label).includes(i))},val.map(i=>m('option',{value:i.label},i.label))))))),),m('.field.is-grouped',[...(opts.buttons||[]).map(i=>i&&m('.control',m('.button',i.opt,i.label))),opts.export&&m('.control',m('.button.is-link',{onclick:e=>saveAs(new Blob([[atModify(opts.rows,opts).map(i=>_.values(i.row).join(';')).join('\n')]],{type:'text/csv;charset=utf-8;'}),opts.export()+'.csv')},'Export CSV')),ors(['filters','start_range','end_range','rangeFunc'].map(i=>_.get(atState,[opts.id,i])))&&m('.button.is-warning',{onclick:e=>[['filters','start_range','end_range','rangeFunc'].map(i=>delete atState[opts.id][i]),m.redraw()]},'Reset Filters')]),m('.table-container',m('table.table',m('thead',m('tr',_.map(opts.heads,(i,j)=>m('th',{onclick:()=>[_.assign(atState,{[opts.id]:_.merge(_.get(atState,opts.id),{sortBy:j,sortWay:!_.get(atState,[opts.id,'sortWay'])})}),m.redraw()]},m('div',m('span',ifit(_.get(opts,['tooltip',j]),tip=>({class:'has-tooltip-bottom','data-tooltip':tip})),i),m('span.icon',j===_.get(atState,[opts.id,'sortBy'])?m('i.fas.fa-angle-'+(_.get(atState,[opts.id,'sortWay'])?'up':'down')):m('i.fas.fa-sort'))))))),m('tbody',atModify(opts.rows,opts).map(i=>m('tr',{onclick:()=>opts.onclick(i.data)},_.map(opts.heads,(val,key)=>m('td',i.row[key]))))))),m('nav.pagination',m('.pagination-list',_.range(opts.rows.length/ors([_.get(atState,[opts.id,'activeStep']),_.get(opts,['showSteps',0])])).map(i=>m('div',m('a.pagination-link',{class:_.get(atState,[opts.id,'pagination'])===i&&'is-current',onclick:()=>[_.assign(atState,{[opts.id]:_.merge(_.get(atState,opts.id),{pagination:i,search:null,activeStep:ors([_.get(atState,[opts.id,'activeStep']),opts.showSteps[0]])})}),m.redraw()]},i+1))))))});var m,_,mgState={},comps={},state={},withAs=(opts,cb)=>cb(opts),ifit=(opts,cb)=>Boolean(opts)&&cb(opts),ands=array=>array.reduce((a,b)=>a&&b,true),makeArray=n=>[...Array(n).keys()],makeIconLabel=(icon,label)=>[icon&&m('span.icon',m('i.fas.fa-'+icon)),m('span',label)],poster=(url,body,cb)=>fetch(url,{headers:{'Content-Type':'application/json'},method:'post',body:JSON.stringify(body)}).then(res=>res.json()).then(cb),mitGen=opts=>({view:()=>m('div',{class:'has-background-light'},opts.theme&&m('link',{rel:'stylesheet',href:`https://unpkg.com/bulmaswatch/${opts.theme }/bulmaswatch.min.css`}),m('nav.navbar.is-primary.is-fixed-top',m('.navbar-brand',m('a.navbar-item',{onclick:()=>[_.assign(mgState,{comp:undefined}),m.redraw()]},opts.brand.full||opts.brand.name),m('.navbar-burger',{role:'button',class:mgState.burgerMenu&&'is-active',onclick:()=>mgState.burgerMenu=!mgState.burgerMenu},_.range(3).map(i=>m('span',{'aria-hidden':true})))),m('.navbar-menu',{class:mgState.burgerMenu&&'is-active'},m('.navbar-start',_.map(opts.start,(val,key)=>m('a.navbar-item',{class:val.submenu&&'has-dropdown is-hoverable',onclick:()=>[_.assign(mgState,{comp:val.comp,burgerMenu:null}),m.redraw()]},val.submenu?[m('a.navbar-link',val.full||_.startCase(key)),m('.navbar-dropdown',_.map(val.submenu,(i,j)=>m('a.navbar-item',{onclick:e=>[e.stopPropagation(),_.assign(mgState,{comp:i.comp,burgerMenu:null}),m.redraw()]},makeIconLabel(i.icon,i.full||_.startCase(j)))))]:m('span',val.full||_.startCase(key))))),opts.end&&m('.navbar-end',m('.navbar-item.has-dropdown.is-hoverable',m('a.navbar-link',{onclick:()=>[(mgState.burgerMenu=!mgState.burgerMenu),_.assign(mgState,{comp:opts.end.comp}),m.redraw()]},opts.end.full),m('.navbar-dropdown.is-right',opts.end.submenu&&_.map(opts.end.submenu,(i,j)=>m('a.navbar-item',{onclick:()=>[(mgState.burgerMenu=!mgState.burgerMenu),_.assign(mgState,{comp:i.comp}),m.redraw()]},makeIconLabel(i.icon,i.full||_.startCase(j))))))))),m('section.section',m('.container',{style:'min-height:100vh'},withAs([m('.content',mgState.comp?mgState.comp():[opts.above,m('h1','Dashboard'),_.chunk(_.map(opts.start,(v,k)=>[v,k]),3).map(i=>m('.columns',i.map(j=>m('.column',m('a.box',m('article.media',{onclick:()=>[_.assign(mgState,{comp:j[0].comp}),m.redraw()]},m('.media-left',m('span.icon.has-text-primary',m('i.fas.fa-2x.fa-'+j[0].icon))),m('.media-content',m('.content',m('h3',j[0].full||_.startCase(j[1])))))))))),opts.below])],body=>opts.login?(opts.loginState?body:opts.login()):body))))});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment