acts-as-approvable 0.6.4 → 0.6.5
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +5 -0
- data/Gemfile.lock +1 -1
- data/README.md +1 -0
- data/VERSION +1 -1
- data/gemfiles/rails2.gemfile.lock +1 -1
- data/gemfiles/rails30.gemfile.lock +1 -1
- data/gemfiles/rails31.gemfile.lock +1 -1
- data/gemfiles/rails32.gemfile.lock +1 -1
- data/generators/acts_as_approvable/acts_as_approvable_generator.rb +11 -16
- data/generators/acts_as_approvable/templates/approvals.js +71 -0
- data/generators/acts_as_approvable/templates/initializer.rb +1 -1
- data/generators/acts_as_approvable/templates/jquery.form.js +101 -0
- data/generators/acts_as_approvable/templates/views/erb/_table.html.erb +2 -2
- data/generators/acts_as_approvable/templates/views/erb/index.html.erb +2 -0
- data/generators/acts_as_approvable/templates/views/haml/_table.html.haml +2 -2
- data/generators/acts_as_approvable/templates/views/haml/index.html.haml +2 -0
- data/lib/generators/acts_as_approvable/acts_as_approvable_generator.rb +13 -18
- data/lib/generators/acts_as_approvable/base.rb +30 -0
- data/lib/generators/acts_as_approvable/templates/approvals.js +71 -0
- data/lib/generators/acts_as_approvable/templates/jquery.form.js +101 -0
- data/lib/generators/erb/acts_as_approvable_generator.rb +5 -16
- data/lib/generators/erb/templates/_table.html.erb +2 -2
- data/lib/generators/erb/templates/index.html.erb +2 -0
- data/lib/generators/haml/acts_as_approvable_generator.rb +5 -16
- data/lib/generators/haml/templates/_table.html.haml +2 -2
- data/lib/generators/haml/templates/index.html.haml +2 -0
- metadata +26 -22
- data/lib/generators/acts_as_approvable.rb +0 -0
data/CHANGELOG
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -37,6 +37,7 @@ These options are also available by passing `--help` as an option to the generat
|
|
37
37
|
--base BASE Base class for ApprovableController.
|
38
38
|
--haml* Generate HAML views instead of ERB.
|
39
39
|
--owner [User] Enable and, optionally, set the model for approval ownerships.
|
40
|
+
--scripts Copy javascripts for ApprovalsController and its views.
|
40
41
|
|
41
42
|
\* This option is not available in Rails 3. You should configure your template engine in `config/application.rb`
|
42
43
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.6.
|
1
|
+
0.6.5
|
@@ -1,4 +1,8 @@
|
|
1
|
+
require 'generators/acts_as_approvable/base'
|
2
|
+
|
1
3
|
class ActsAsApprovableGenerator < Rails::Generator::Base
|
4
|
+
include ActsAsApprovable::Generators::Base
|
5
|
+
|
2
6
|
default_options :base => 'ApplicationController'
|
3
7
|
|
4
8
|
def manifest
|
@@ -15,6 +19,12 @@ class ActsAsApprovableGenerator < Rails::Generator::Base
|
|
15
19
|
m.directory 'config/initializers'
|
16
20
|
m.template 'initializer.rb', 'config/initializers/acts_as_approvable.rb'
|
17
21
|
|
22
|
+
if scripts?
|
23
|
+
m.directory 'public/javascripts'
|
24
|
+
m.template 'jquery.form.js', 'public/javascripts/jquery.form.js'
|
25
|
+
m.template 'approvals.js', 'public/javascripts/approvals.js'
|
26
|
+
end
|
27
|
+
|
18
28
|
m.route route
|
19
29
|
end
|
20
30
|
end
|
@@ -24,22 +34,6 @@ class ActsAsApprovableGenerator < Rails::Generator::Base
|
|
24
34
|
options[:haml] ? 'haml' : 'erb'
|
25
35
|
end
|
26
36
|
|
27
|
-
def owner?
|
28
|
-
options[:owner].present?
|
29
|
-
end
|
30
|
-
|
31
|
-
def collection_actions
|
32
|
-
actions = [:index, :history]
|
33
|
-
actions << :mine if owner?
|
34
|
-
actions.map { |a| ":#{a}" }
|
35
|
-
end
|
36
|
-
|
37
|
-
def member_actions
|
38
|
-
actions = [:approve, :reject]
|
39
|
-
actions << :assign if owner?
|
40
|
-
actions.map { |a| ":#{a}" }
|
41
|
-
end
|
42
|
-
|
43
37
|
def route
|
44
38
|
route = 'map.resources :approvals, :only => [:index], :collection => ['
|
45
39
|
route << collection_actions.reject { |a| a == ':index' }.join(', ')
|
@@ -54,6 +48,7 @@ class ActsAsApprovableGenerator < Rails::Generator::Base
|
|
54
48
|
opt.on('--base BASE', 'Base class for ApprovableController.') { |v| options[:base] = v }
|
55
49
|
opt.on('--haml', 'Generate HAML views instead of ERB.') { |v| options[:haml] = v }
|
56
50
|
opt.on('--owner [User]', 'Enable and, optionally, set the model for approval ownerships.') { |v| options[:owner] = v || 'User' }
|
51
|
+
opt.on('--scripts', 'Indicates when to generate scripts.') { |v| options[:scripts] = v }
|
57
52
|
end
|
58
53
|
end
|
59
54
|
|
@@ -0,0 +1,71 @@
|
|
1
|
+
$(function() {
|
2
|
+
// Assignment
|
3
|
+
$('form.assignment').each(function() {
|
4
|
+
var form = $(this),
|
5
|
+
spinner = $('.spinner', this);
|
6
|
+
|
7
|
+
form.ajaxForm({
|
8
|
+
dataType: 'json',
|
9
|
+
beforeSubmit: function() {
|
10
|
+
spinner.show();
|
11
|
+
},
|
12
|
+
success: function(data, status, jqx) {
|
13
|
+
spinner.hide();
|
14
|
+
|
15
|
+
if (!data.success) {
|
16
|
+
alert('There was an issue assigning this approval!')
|
17
|
+
}
|
18
|
+
},
|
19
|
+
error: function(jqx, status, error) {
|
20
|
+
spinner.hide();
|
21
|
+
alert('There was an issue assigning this approval!')
|
22
|
+
},
|
23
|
+
});
|
24
|
+
|
25
|
+
$('select', this).change(function() {
|
26
|
+
form.submit();
|
27
|
+
});
|
28
|
+
});
|
29
|
+
|
30
|
+
// Approval and Rejection
|
31
|
+
var actionLinks = $('td.actions a');
|
32
|
+
|
33
|
+
actionLinks.click(function() {
|
34
|
+
if ($(this).hasClass('disabled')) return false;
|
35
|
+
|
36
|
+
var verbing = ($(this).hasClass('approve') ? 'approving' : 'rejecting'),
|
37
|
+
row = $(this).parents('tr'),
|
38
|
+
settings = {
|
39
|
+
dataType: 'json',
|
40
|
+
url: $(this).attr('href'),
|
41
|
+
beforeSubmit: function() {
|
42
|
+
actionLinks.addClass('disabled');
|
43
|
+
},
|
44
|
+
success: function(data) {
|
45
|
+
actionLinks.removeClass('disabled');
|
46
|
+
|
47
|
+
if (!data.success) {
|
48
|
+
if (data.message) {
|
49
|
+
alert(data.message);
|
50
|
+
} else {
|
51
|
+
alert('There was an issue ' + verbing + ' the approval.');
|
52
|
+
}
|
53
|
+
} else {
|
54
|
+
row.fadeOut('fast', row.remove);
|
55
|
+
}
|
56
|
+
},
|
57
|
+
error: function() {
|
58
|
+
actionLinks.removeClass('disabled');
|
59
|
+
alert('There was an issue ' + verbing + ' the approval.');
|
60
|
+
}
|
61
|
+
};
|
62
|
+
|
63
|
+
if ($(this).hasClass('reject')) {
|
64
|
+
var reason = prompt('Reason for rejection');
|
65
|
+
if (reason) settings['data'] = {reason: reason};
|
66
|
+
}
|
67
|
+
|
68
|
+
$.ajax(settings);
|
69
|
+
return false;
|
70
|
+
});
|
71
|
+
});
|
@@ -1,3 +1,3 @@
|
|
1
1
|
ActsAsApprovable.view_language = '<%= view_language %>'
|
2
|
-
<% if owner? %>ActsAsApprovable::Ownership.configure<% if
|
2
|
+
<% if owner? %>ActsAsApprovable::Ownership.configure<% if owner != 'User' %>(:owner => <%= owner.constantize %>)<% end %>
|
3
3
|
<% end %>
|
@@ -0,0 +1,101 @@
|
|
1
|
+
;(function($){$.fn.ajaxSubmit=function(options){if(!this.length){log('ajaxSubmit: skipping submit process - no element selected');return this;}
|
2
|
+
if(typeof options=='function'){options={success:options};}
|
3
|
+
var action=this.attr('action');var url=(typeof action==='string')?$.trim(action):'';url=url||window.location.href||'';if(url){url=(url.match(/^([^#]+)/)||[])[1];}
|
4
|
+
options=$.extend(true,{url:url,success:$.ajaxSettings.success,type:this[0].getAttribute('method')||'GET',iframeSrc:/^https/i.test(window.location.href||'')?'javascript:false':'about:blank'},options);var veto={};this.trigger('form-pre-serialize',[this,options,veto]);if(veto.veto){log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');return this;}
|
5
|
+
if(options.beforeSerialize&&options.beforeSerialize(this,options)===false){log('ajaxSubmit: submit aborted via beforeSerialize callback');return this;}
|
6
|
+
var n,v,a=this.formToArray(options.semantic);if(options.data){options.extraData=options.data;for(n in options.data){if(options.data[n]instanceof Array){for(var k in options.data[n]){a.push({name:n,value:options.data[n][k]});}}
|
7
|
+
else{v=options.data[n];v=$.isFunction(v)?v():v;a.push({name:n,value:v});}}}
|
8
|
+
if(options.beforeSubmit&&options.beforeSubmit(a,this,options)===false){log('ajaxSubmit: submit aborted via beforeSubmit callback');return this;}
|
9
|
+
this.trigger('form-submit-validate',[a,this,options,veto]);if(veto.veto){log('ajaxSubmit: submit vetoed via form-submit-validate trigger');return this;}
|
10
|
+
var q=$.param(a);if(options.type.toUpperCase()=='GET'){options.url+=(options.url.indexOf('?')>=0?'&':'?')+q;options.data=null;}
|
11
|
+
else{options.data=q;}
|
12
|
+
var $form=this,callbacks=[];if(options.resetForm){callbacks.push(function(){$form.resetForm();});}
|
13
|
+
if(options.clearForm){callbacks.push(function(){$form.clearForm();});}
|
14
|
+
if(!options.dataType&&options.target){var oldSuccess=options.success||function(){};callbacks.push(function(data){var fn=options.replaceTarget?'replaceWith':'html';$(options.target)[fn](data).each(oldSuccess,arguments);});}
|
15
|
+
else if(options.success){callbacks.push(options.success);}
|
16
|
+
options.success=function(data,status,xhr){var context=options.context||options;for(var i=0,max=callbacks.length;i<max;i++){callbacks[i].apply(context,[data,status,xhr||$form,$form]);}};var fileInputs=$('input:file',this).length>0;var mp='multipart/form-data';var multipart=($form.attr('enctype')==mp||$form.attr('encoding')==mp);if(options.iframe!==false&&(fileInputs||options.iframe||multipart)){if(options.closeKeepAlive){$.get(options.closeKeepAlive,fileUpload);}
|
17
|
+
else{fileUpload();}}
|
18
|
+
else{$.ajax(options);}
|
19
|
+
this.trigger('form-submit-notify',[this,options]);return this;function fileUpload(){var form=$form[0],s,g,id,$io,io,xhr,sub,n,timedOut,timeoutHandle;if($(':input[name=submit],:input[id=submit]',form).length){alert('Error: Form elements must not have name or id of "submit".');return;}
|
20
|
+
s=$.extend(true,{},$.ajaxSettings,options);s.context=s.context||s;$io,id='jqFormIO'+(new Date().getTime());if(s.iframeTarget){$io=$(s.iframeTarget);n=$io.attr('name');if(n==null)
|
21
|
+
$io.attr('name',id);else
|
22
|
+
id=n;}
|
23
|
+
else{$io=$('<iframe name="'+id+'" src="'+s.iframeSrc+'" />');$io.css({position:'absolute',top:'-1000px',left:'-1000px'});}
|
24
|
+
io=$io[0];xhr={aborted:0,responseText:null,responseXML:null,status:0,statusText:'n/a',getAllResponseHeaders:function(){},getResponseHeader:function(){},setRequestHeader:function(){},abort:function(status){var e=(status==='timeout'?'timeout':'aborted');log('aborting upload... '+e);this.aborted=1;$io.attr('src',s.iframeSrc);xhr.error=e;s.error&&s.error.call(s.context,xhr,e,e);g&&$.event.trigger("ajaxError",[xhr,s,e]);s.complete&&s.complete.call(s.context,xhr,e);}};g=s.global;if(g&&!$.active++){$.event.trigger("ajaxStart");}
|
25
|
+
if(g){$.event.trigger("ajaxSend",[xhr,s]);}
|
26
|
+
if(s.beforeSend&&s.beforeSend.call(s.context,xhr,s)===false){if(s.global){$.active--;}
|
27
|
+
return;}
|
28
|
+
if(xhr.aborted){return;}
|
29
|
+
sub=form.clk;if(sub){n=sub.name;if(n&&!sub.disabled){s.extraData=s.extraData||{};s.extraData[n]=sub.value;if(sub.type=="image"){s.extraData[n+'.x']=form.clk_x;s.extraData[n+'.y']=form.clk_y;}}}
|
30
|
+
function doSubmit(){var t=$form.attr('target'),a=$form.attr('action');form.setAttribute('target',id);if(form.getAttribute('method')!='POST'){form.setAttribute('method','POST');}
|
31
|
+
if(form.getAttribute('action')!=s.url){form.setAttribute('action',s.url);}
|
32
|
+
if(!s.skipEncodingOverride){$form.attr({encoding:'multipart/form-data',enctype:'multipart/form-data'});}
|
33
|
+
if(s.timeout){timeoutHandle=setTimeout(function(){timedOut=true;cb(true);},s.timeout);}
|
34
|
+
var extraInputs=[];try{if(s.extraData){for(var n in s.extraData){extraInputs.push($('<input type="hidden" name="'+n+'" value="'+s.extraData[n]+'" />').appendTo(form)[0]);}}
|
35
|
+
if(!s.iframeTarget){$io.appendTo('body');io.attachEvent?io.attachEvent('onload',cb):io.addEventListener('load',cb,false);}
|
36
|
+
form.submit();}
|
37
|
+
finally{form.setAttribute('action',a);if(t){form.setAttribute('target',t);}else{$form.removeAttr('target');}
|
38
|
+
$(extraInputs).remove();}}
|
39
|
+
if(s.forceSync){doSubmit();}
|
40
|
+
else{setTimeout(doSubmit,10);}
|
41
|
+
var data,doc,domCheckCount=50,callbackProcessed;function cb(e){if(xhr.aborted||callbackProcessed){return;}
|
42
|
+
if(e===true&&xhr){xhr.abort('timeout');return;}
|
43
|
+
var doc=io.contentWindow?io.contentWindow.document:io.contentDocument?io.contentDocument:io.document;if(!doc||doc.location.href==s.iframeSrc){if(!timedOut)
|
44
|
+
return;}
|
45
|
+
io.detachEvent?io.detachEvent('onload',cb):io.removeEventListener('load',cb,false);var status='success',errMsg;try{if(timedOut){throw'timeout';}
|
46
|
+
var isXml=s.dataType=='xml'||doc.XMLDocument||$.isXMLDoc(doc);log('isXml='+isXml);if(!isXml&&window.opera&&(doc.body==null||doc.body.innerHTML=='')){if(--domCheckCount){log('requeing onLoad callback, DOM not available');setTimeout(cb,250);return;}}
|
47
|
+
var docRoot=doc.body?doc.body:doc.documentElement;xhr.responseText=docRoot?docRoot.innerHTML:null;xhr.responseXML=doc.XMLDocument?doc.XMLDocument:doc;if(isXml)
|
48
|
+
s.dataType='xml';xhr.getResponseHeader=function(header){var headers={'content-type':s.dataType};return headers[header];};if(docRoot){xhr.status=Number(docRoot.getAttribute('status'))||xhr.status;xhr.statusText=docRoot.getAttribute('statusText')||xhr.statusText;}
|
49
|
+
var scr=/(json|script|text)/.test(s.dataType.toLowerCase());if(scr||s.textarea){var ta=doc.getElementsByTagName('textarea')[0];if(ta){xhr.responseText=ta.value;xhr.status=Number(ta.getAttribute('status'))||xhr.status;xhr.statusText=ta.getAttribute('statusText')||xhr.statusText;}
|
50
|
+
else if(scr){var pre=doc.getElementsByTagName('pre')[0];var b=doc.getElementsByTagName('body')[0];if(pre){xhr.responseText=pre.textContent?pre.textContent:pre.innerHTML;}
|
51
|
+
else if(b){xhr.responseText=b.innerHTML;}}}
|
52
|
+
else if(s.dataType=='xml'&&!xhr.responseXML&&xhr.responseText!=null){xhr.responseXML=toXml(xhr.responseText);}
|
53
|
+
try{data=httpData(xhr,s.dataType,s);}
|
54
|
+
catch(e){status='parsererror';xhr.error=errMsg=(e||status);}}
|
55
|
+
catch(e){log('error caught',e);status='error';xhr.error=errMsg=(e||status);}
|
56
|
+
if(xhr.aborted){log('upload aborted');status=null;}
|
57
|
+
if(xhr.status){status=(xhr.status>=200&&xhr.status<300||xhr.status===304)?'success':'error';}
|
58
|
+
if(status==='success'){s.success&&s.success.call(s.context,data,'success',xhr);g&&$.event.trigger("ajaxSuccess",[xhr,s]);}
|
59
|
+
else if(status){if(errMsg==undefined)
|
60
|
+
errMsg=xhr.statusText;s.error&&s.error.call(s.context,xhr,status,errMsg);g&&$.event.trigger("ajaxError",[xhr,s,errMsg]);}
|
61
|
+
g&&$.event.trigger("ajaxComplete",[xhr,s]);if(g&&!--$.active){$.event.trigger("ajaxStop");}
|
62
|
+
s.complete&&s.complete.call(s.context,xhr,status);callbackProcessed=true;if(s.timeout)
|
63
|
+
clearTimeout(timeoutHandle);setTimeout(function(){if(!s.iframeTarget)
|
64
|
+
$io.remove();xhr.responseXML=null;},100);}
|
65
|
+
var toXml=$.parseXML||function(s,doc){if(window.ActiveXObject){doc=new ActiveXObject('Microsoft.XMLDOM');doc.async='false';doc.loadXML(s);}
|
66
|
+
else{doc=(new DOMParser()).parseFromString(s,'text/xml');}
|
67
|
+
return(doc&&doc.documentElement&&doc.documentElement.nodeName!='parsererror')?doc:null;};var parseJSON=$.parseJSON||function(s){return window['eval']('('+s+')');};var httpData=function(xhr,type,s){var ct=xhr.getResponseHeader('content-type')||'',xml=type==='xml'||!type&&ct.indexOf('xml')>=0,data=xml?xhr.responseXML:xhr.responseText;if(xml&&data.documentElement.nodeName==='parsererror'){$.error&&$.error('parsererror');}
|
68
|
+
if(s&&s.dataFilter){data=s.dataFilter(data,type);}
|
69
|
+
if(typeof data==='string'){if(type==='json'||!type&&ct.indexOf('json')>=0){data=parseJSON(data);}else if(type==="script"||!type&&ct.indexOf("javascript")>=0){$.globalEval(data);}}
|
70
|
+
return data;};}};$.fn.ajaxForm=function(options){if(this.length===0){var o={s:this.selector,c:this.context};if(!$.isReady&&o.s){log('DOM not ready, queuing ajaxForm');$(function(){$(o.s,o.c).ajaxForm(options);});return this;}
|
71
|
+
log('terminating; zero elements found by selector'+($.isReady?'':' (DOM not ready)'));return this;}
|
72
|
+
return this.ajaxFormUnbind().bind('submit.form-plugin',function(e){if(!e.isDefaultPrevented()){e.preventDefault();$(this).ajaxSubmit(options);}}).bind('click.form-plugin',function(e){var target=e.target;var $el=$(target);if(!($el.is(":submit,input:image"))){var t=$el.closest(':submit');if(t.length==0){return;}
|
73
|
+
target=t[0];}
|
74
|
+
var form=this;form.clk=target;if(target.type=='image'){if(e.offsetX!=undefined){form.clk_x=e.offsetX;form.clk_y=e.offsetY;}else if(typeof $.fn.offset=='function'){var offset=$el.offset();form.clk_x=e.pageX-offset.left;form.clk_y=e.pageY-offset.top;}else{form.clk_x=e.pageX-target.offsetLeft;form.clk_y=e.pageY-target.offsetTop;}}
|
75
|
+
setTimeout(function(){form.clk=form.clk_x=form.clk_y=null;},100);});};$.fn.ajaxFormUnbind=function(){return this.unbind('submit.form-plugin click.form-plugin');};$.fn.formToArray=function(semantic){var a=[];if(this.length===0){return a;}
|
76
|
+
var form=this[0];var els=semantic?form.getElementsByTagName('*'):form.elements;if(!els){return a;}
|
77
|
+
var i,j,n,v,el,max,jmax;for(i=0,max=els.length;i<max;i++){el=els[i];n=el.name;if(!n){continue;}
|
78
|
+
if(semantic&&form.clk&&el.type=="image"){if(!el.disabled&&form.clk==el){a.push({name:n,value:$(el).val()});a.push({name:n+'.x',value:form.clk_x},{name:n+'.y',value:form.clk_y});}
|
79
|
+
continue;}
|
80
|
+
v=$.fieldValue(el,true);if(v&&v.constructor==Array){for(j=0,jmax=v.length;j<jmax;j++){a.push({name:n,value:v[j]});}}
|
81
|
+
else if(v!==null&&typeof v!='undefined'){a.push({name:n,value:v});}}
|
82
|
+
if(!semantic&&form.clk){var $input=$(form.clk),input=$input[0];n=input.name;if(n&&!input.disabled&&input.type=='image'){a.push({name:n,value:$input.val()});a.push({name:n+'.x',value:form.clk_x},{name:n+'.y',value:form.clk_y});}}
|
83
|
+
return a;};$.fn.formSerialize=function(semantic){return $.param(this.formToArray(semantic));};$.fn.fieldSerialize=function(successful){var a=[];this.each(function(){var n=this.name;if(!n){return;}
|
84
|
+
var v=$.fieldValue(this,successful);if(v&&v.constructor==Array){for(var i=0,max=v.length;i<max;i++){a.push({name:n,value:v[i]});}}
|
85
|
+
else if(v!==null&&typeof v!='undefined'){a.push({name:this.name,value:v});}});return $.param(a);};$.fn.fieldValue=function(successful){for(var val=[],i=0,max=this.length;i<max;i++){var el=this[i];var v=$.fieldValue(el,successful);if(v===null||typeof v=='undefined'||(v.constructor==Array&&!v.length)){continue;}
|
86
|
+
v.constructor==Array?$.merge(val,v):val.push(v);}
|
87
|
+
return val;};$.fieldValue=function(el,successful){var n=el.name,t=el.type,tag=el.tagName.toLowerCase();if(successful===undefined){successful=true;}
|
88
|
+
if(successful&&(!n||el.disabled||t=='reset'||t=='button'||(t=='checkbox'||t=='radio')&&!el.checked||(t=='submit'||t=='image')&&el.form&&el.form.clk!=el||tag=='select'&&el.selectedIndex==-1)){return null;}
|
89
|
+
if(tag=='select'){var index=el.selectedIndex;if(index<0){return null;}
|
90
|
+
var a=[],ops=el.options;var one=(t=='select-one');var max=(one?index+1:ops.length);for(var i=(one?index:0);i<max;i++){var op=ops[i];if(op.selected){var v=op.value;if(!v){v=(op.attributes&&op.attributes['value']&&!(op.attributes['value'].specified))?op.text:op.value;}
|
91
|
+
if(one){return v;}
|
92
|
+
a.push(v);}}
|
93
|
+
return a;}
|
94
|
+
return $(el).val();};$.fn.clearForm=function(){return this.each(function(){$('input,select,textarea',this).clearFields();});};$.fn.clearFields=$.fn.clearInputs=function(){return this.each(function(){var t=this.type,tag=this.tagName.toLowerCase();if(t=='text'||t=='password'||tag=='textarea'){this.value='';}
|
95
|
+
else if(t=='checkbox'||t=='radio'){this.checked=false;}
|
96
|
+
else if(tag=='select'){this.selectedIndex=-1;}});};$.fn.resetForm=function(){return this.each(function(){if(typeof this.reset=='function'||(typeof this.reset=='object'&&!this.reset.nodeType)){this.reset();}});};$.fn.enable=function(b){if(b===undefined){b=true;}
|
97
|
+
return this.each(function(){this.disabled=!b;});};$.fn.selected=function(select){if(select===undefined){select=true;}
|
98
|
+
return this.each(function(){var t=this.type;if(t=='checkbox'||t=='radio'){this.checked=select;}
|
99
|
+
else if(this.tagName.toLowerCase()=='option'){var $sel=$(this).parent('select');if(select&&$sel[0]&&$sel[0].type=='select-one'){$sel.find('option').selected(false);}
|
100
|
+
this.selected=select;}});};function log(){if($.fn.ajaxSubmit.debug){var msg='[jquery.form] '+Array.prototype.join.call(arguments,'');if(window.console&&window.console.log){window.console.log(msg);}
|
101
|
+
else if(window.opera&&window.opera.postError){window.opera.postError(msg);}}};})(jQuery);
|
@@ -16,8 +16,8 @@
|
|
16
16
|
<% if owner? %> <td><%%= render :partial => 'owner_select', :locals => {:approval => approval} %></td>
|
17
17
|
<% end %> <td><%%= approval.state %></td>
|
18
18
|
<td class='actions'>
|
19
|
-
<%%= link_to('Approve', approve_approval_path(approval)) %>
|
20
|
-
<%%= link_to('Reject', reject_approval_path(approval)) %>
|
19
|
+
<%%= link_to('Approve', approve_approval_path(approval), :class => 'approve') %>
|
20
|
+
<%%= link_to('Reject', reject_approval_path(approval), :class => 'reject') %>
|
21
21
|
</td>
|
22
22
|
</tr>
|
23
23
|
<%% end %>
|
@@ -14,6 +14,6 @@
|
|
14
14
|
<% if owner? %> %td= render :partial => 'owner_select', :locals => {:approval => approval}
|
15
15
|
<% end %> %td= approval.state
|
16
16
|
%td.actions
|
17
|
-
= link_to('Approve', approve_approval_path(approval))
|
18
|
-
= link_to('Reject', reject_approval_path(approval))
|
17
|
+
= link_to('Approve', approve_approval_path(approval), :class => 'approve')
|
18
|
+
= link_to('Reject', reject_approval_path(approval), :class => 'reject')
|
19
19
|
|
@@ -1,10 +1,15 @@
|
|
1
1
|
require 'rails/generators/active_record'
|
2
|
+
require 'generators/acts_as_approvable/base'
|
3
|
+
|
2
4
|
|
3
5
|
class ActsAsApprovableGenerator < Rails::Generators::Base
|
6
|
+
include ActsAsApprovable::Generators::Base
|
7
|
+
|
4
8
|
source_root File.expand_path('../templates', __FILE__)
|
5
9
|
|
6
10
|
class_option :base, :type => :string, :default => 'ApplicationController', :desc => 'Base class for the ApprovalsController'
|
7
11
|
class_option :owner, :type => :string, :optional => true, :desc => 'Model that can own approvals'
|
12
|
+
class_option :scripts, :type => :boolean, :optional => true, :default => false
|
8
13
|
|
9
14
|
desc 'Generates ApprovalsController, a migration the create the Approval table, and an initializer for the plugin.'
|
10
15
|
|
@@ -27,13 +32,20 @@ class ActsAsApprovableGenerator < Rails::Generators::Base
|
|
27
32
|
|
28
33
|
if owner?
|
29
34
|
data << 'ActsAsApprovable::Ownership.configure'
|
30
|
-
data << "(:owner => #{
|
35
|
+
data << "(:owner => #{owner})" if owner != 'User'
|
31
36
|
end
|
32
37
|
|
33
38
|
data << "\n"
|
34
39
|
end
|
35
40
|
end
|
36
41
|
|
42
|
+
def create_script_files
|
43
|
+
return unless scripts?
|
44
|
+
|
45
|
+
template 'jquery.form.js', 'public/javascripts/jquery.form.js'
|
46
|
+
template 'approvals.js', 'public/javascripts/approvals.js'
|
47
|
+
end
|
48
|
+
|
37
49
|
hook_for :template_engine
|
38
50
|
|
39
51
|
def add_routes
|
@@ -53,21 +65,4 @@ class ActsAsApprovableGenerator < Rails::Generators::Base
|
|
53
65
|
|
54
66
|
route(resource.join("\n"))
|
55
67
|
end
|
56
|
-
|
57
|
-
protected
|
58
|
-
def owner?
|
59
|
-
options[:owner].present?
|
60
|
-
end
|
61
|
-
|
62
|
-
def collection_actions
|
63
|
-
actions = [:index, :history]
|
64
|
-
actions << :mine if owner?
|
65
|
-
actions.map { |a| ":#{a}" }
|
66
|
-
end
|
67
|
-
|
68
|
-
def member_actions
|
69
|
-
actions = [:approve, :reject]
|
70
|
-
actions << :assign if owner?
|
71
|
-
actions.map { |a| ":#{a}" }
|
72
|
-
end
|
73
68
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module ActsAsApprovable
|
2
|
+
module Generators
|
3
|
+
module Base
|
4
|
+
protected
|
5
|
+
def owner?
|
6
|
+
options[:owner].present?
|
7
|
+
end
|
8
|
+
|
9
|
+
def owner
|
10
|
+
options[:owner] == 'owner' ? 'User' : options[:owner]
|
11
|
+
end
|
12
|
+
|
13
|
+
def scripts?
|
14
|
+
options[:scripts]
|
15
|
+
end
|
16
|
+
|
17
|
+
def collection_actions
|
18
|
+
actions = [:index, :history]
|
19
|
+
actions << :mine if owner?
|
20
|
+
actions.map { |a| ":#{a}" }
|
21
|
+
end
|
22
|
+
|
23
|
+
def member_actions
|
24
|
+
actions = [:approve, :reject]
|
25
|
+
actions << :assign if owner?
|
26
|
+
actions.map { |a| ":#{a}" }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
$(function() {
|
2
|
+
// Assignment
|
3
|
+
$('form.assignment').each(function() {
|
4
|
+
var form = $(this),
|
5
|
+
spinner = $('.spinner', this);
|
6
|
+
|
7
|
+
form.ajaxForm({
|
8
|
+
dataType: 'json',
|
9
|
+
beforeSubmit: function() {
|
10
|
+
spinner.show();
|
11
|
+
},
|
12
|
+
success: function(data, status, jqx) {
|
13
|
+
spinner.hide();
|
14
|
+
|
15
|
+
if (!data.success) {
|
16
|
+
alert('There was an issue assigning this approval!')
|
17
|
+
}
|
18
|
+
},
|
19
|
+
error: function(jqx, status, error) {
|
20
|
+
spinner.hide();
|
21
|
+
alert('There was an issue assigning this approval!')
|
22
|
+
},
|
23
|
+
});
|
24
|
+
|
25
|
+
$('select', this).change(function() {
|
26
|
+
form.submit();
|
27
|
+
});
|
28
|
+
});
|
29
|
+
|
30
|
+
// Approval and Rejection
|
31
|
+
var actionLinks = $('td.actions a');
|
32
|
+
|
33
|
+
actionLinks.click(function() {
|
34
|
+
if ($(this).hasClass('disabled')) return false;
|
35
|
+
|
36
|
+
var verbing = ($(this).hasClass('approve') ? 'approving' : 'rejecting'),
|
37
|
+
row = $(this).parents('tr'),
|
38
|
+
settings = {
|
39
|
+
dataType: 'json',
|
40
|
+
url: $(this).attr('href'),
|
41
|
+
beforeSubmit: function() {
|
42
|
+
actionLinks.addClass('disabled');
|
43
|
+
},
|
44
|
+
success: function(data) {
|
45
|
+
actionLinks.removeClass('disabled');
|
46
|
+
|
47
|
+
if (!data.success) {
|
48
|
+
if (data.message) {
|
49
|
+
alert(data.message);
|
50
|
+
} else {
|
51
|
+
alert('There was an issue ' + verbing + ' the approval.');
|
52
|
+
}
|
53
|
+
} else {
|
54
|
+
row.fadeOut('fast', row.remove);
|
55
|
+
}
|
56
|
+
},
|
57
|
+
error: function() {
|
58
|
+
actionLinks.removeClass('disabled');
|
59
|
+
alert('There was an issue ' + verbing + ' the approval.');
|
60
|
+
}
|
61
|
+
};
|
62
|
+
|
63
|
+
if ($(this).hasClass('reject')) {
|
64
|
+
var reason = prompt('Reason for rejection');
|
65
|
+
if (reason) settings['data'] = {reason: reason};
|
66
|
+
}
|
67
|
+
|
68
|
+
$.ajax(settings);
|
69
|
+
return false;
|
70
|
+
});
|
71
|
+
});
|
@@ -0,0 +1,101 @@
|
|
1
|
+
;(function($){$.fn.ajaxSubmit=function(options){if(!this.length){log('ajaxSubmit: skipping submit process - no element selected');return this;}
|
2
|
+
if(typeof options=='function'){options={success:options};}
|
3
|
+
var action=this.attr('action');var url=(typeof action==='string')?$.trim(action):'';url=url||window.location.href||'';if(url){url=(url.match(/^([^#]+)/)||[])[1];}
|
4
|
+
options=$.extend(true,{url:url,success:$.ajaxSettings.success,type:this[0].getAttribute('method')||'GET',iframeSrc:/^https/i.test(window.location.href||'')?'javascript:false':'about:blank'},options);var veto={};this.trigger('form-pre-serialize',[this,options,veto]);if(veto.veto){log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');return this;}
|
5
|
+
if(options.beforeSerialize&&options.beforeSerialize(this,options)===false){log('ajaxSubmit: submit aborted via beforeSerialize callback');return this;}
|
6
|
+
var n,v,a=this.formToArray(options.semantic);if(options.data){options.extraData=options.data;for(n in options.data){if(options.data[n]instanceof Array){for(var k in options.data[n]){a.push({name:n,value:options.data[n][k]});}}
|
7
|
+
else{v=options.data[n];v=$.isFunction(v)?v():v;a.push({name:n,value:v});}}}
|
8
|
+
if(options.beforeSubmit&&options.beforeSubmit(a,this,options)===false){log('ajaxSubmit: submit aborted via beforeSubmit callback');return this;}
|
9
|
+
this.trigger('form-submit-validate',[a,this,options,veto]);if(veto.veto){log('ajaxSubmit: submit vetoed via form-submit-validate trigger');return this;}
|
10
|
+
var q=$.param(a);if(options.type.toUpperCase()=='GET'){options.url+=(options.url.indexOf('?')>=0?'&':'?')+q;options.data=null;}
|
11
|
+
else{options.data=q;}
|
12
|
+
var $form=this,callbacks=[];if(options.resetForm){callbacks.push(function(){$form.resetForm();});}
|
13
|
+
if(options.clearForm){callbacks.push(function(){$form.clearForm();});}
|
14
|
+
if(!options.dataType&&options.target){var oldSuccess=options.success||function(){};callbacks.push(function(data){var fn=options.replaceTarget?'replaceWith':'html';$(options.target)[fn](data).each(oldSuccess,arguments);});}
|
15
|
+
else if(options.success){callbacks.push(options.success);}
|
16
|
+
options.success=function(data,status,xhr){var context=options.context||options;for(var i=0,max=callbacks.length;i<max;i++){callbacks[i].apply(context,[data,status,xhr||$form,$form]);}};var fileInputs=$('input:file',this).length>0;var mp='multipart/form-data';var multipart=($form.attr('enctype')==mp||$form.attr('encoding')==mp);if(options.iframe!==false&&(fileInputs||options.iframe||multipart)){if(options.closeKeepAlive){$.get(options.closeKeepAlive,fileUpload);}
|
17
|
+
else{fileUpload();}}
|
18
|
+
else{$.ajax(options);}
|
19
|
+
this.trigger('form-submit-notify',[this,options]);return this;function fileUpload(){var form=$form[0],s,g,id,$io,io,xhr,sub,n,timedOut,timeoutHandle;if($(':input[name=submit],:input[id=submit]',form).length){alert('Error: Form elements must not have name or id of "submit".');return;}
|
20
|
+
s=$.extend(true,{},$.ajaxSettings,options);s.context=s.context||s;$io,id='jqFormIO'+(new Date().getTime());if(s.iframeTarget){$io=$(s.iframeTarget);n=$io.attr('name');if(n==null)
|
21
|
+
$io.attr('name',id);else
|
22
|
+
id=n;}
|
23
|
+
else{$io=$('<iframe name="'+id+'" src="'+s.iframeSrc+'" />');$io.css({position:'absolute',top:'-1000px',left:'-1000px'});}
|
24
|
+
io=$io[0];xhr={aborted:0,responseText:null,responseXML:null,status:0,statusText:'n/a',getAllResponseHeaders:function(){},getResponseHeader:function(){},setRequestHeader:function(){},abort:function(status){var e=(status==='timeout'?'timeout':'aborted');log('aborting upload... '+e);this.aborted=1;$io.attr('src',s.iframeSrc);xhr.error=e;s.error&&s.error.call(s.context,xhr,e,e);g&&$.event.trigger("ajaxError",[xhr,s,e]);s.complete&&s.complete.call(s.context,xhr,e);}};g=s.global;if(g&&!$.active++){$.event.trigger("ajaxStart");}
|
25
|
+
if(g){$.event.trigger("ajaxSend",[xhr,s]);}
|
26
|
+
if(s.beforeSend&&s.beforeSend.call(s.context,xhr,s)===false){if(s.global){$.active--;}
|
27
|
+
return;}
|
28
|
+
if(xhr.aborted){return;}
|
29
|
+
sub=form.clk;if(sub){n=sub.name;if(n&&!sub.disabled){s.extraData=s.extraData||{};s.extraData[n]=sub.value;if(sub.type=="image"){s.extraData[n+'.x']=form.clk_x;s.extraData[n+'.y']=form.clk_y;}}}
|
30
|
+
function doSubmit(){var t=$form.attr('target'),a=$form.attr('action');form.setAttribute('target',id);if(form.getAttribute('method')!='POST'){form.setAttribute('method','POST');}
|
31
|
+
if(form.getAttribute('action')!=s.url){form.setAttribute('action',s.url);}
|
32
|
+
if(!s.skipEncodingOverride){$form.attr({encoding:'multipart/form-data',enctype:'multipart/form-data'});}
|
33
|
+
if(s.timeout){timeoutHandle=setTimeout(function(){timedOut=true;cb(true);},s.timeout);}
|
34
|
+
var extraInputs=[];try{if(s.extraData){for(var n in s.extraData){extraInputs.push($('<input type="hidden" name="'+n+'" value="'+s.extraData[n]+'" />').appendTo(form)[0]);}}
|
35
|
+
if(!s.iframeTarget){$io.appendTo('body');io.attachEvent?io.attachEvent('onload',cb):io.addEventListener('load',cb,false);}
|
36
|
+
form.submit();}
|
37
|
+
finally{form.setAttribute('action',a);if(t){form.setAttribute('target',t);}else{$form.removeAttr('target');}
|
38
|
+
$(extraInputs).remove();}}
|
39
|
+
if(s.forceSync){doSubmit();}
|
40
|
+
else{setTimeout(doSubmit,10);}
|
41
|
+
var data,doc,domCheckCount=50,callbackProcessed;function cb(e){if(xhr.aborted||callbackProcessed){return;}
|
42
|
+
if(e===true&&xhr){xhr.abort('timeout');return;}
|
43
|
+
var doc=io.contentWindow?io.contentWindow.document:io.contentDocument?io.contentDocument:io.document;if(!doc||doc.location.href==s.iframeSrc){if(!timedOut)
|
44
|
+
return;}
|
45
|
+
io.detachEvent?io.detachEvent('onload',cb):io.removeEventListener('load',cb,false);var status='success',errMsg;try{if(timedOut){throw'timeout';}
|
46
|
+
var isXml=s.dataType=='xml'||doc.XMLDocument||$.isXMLDoc(doc);log('isXml='+isXml);if(!isXml&&window.opera&&(doc.body==null||doc.body.innerHTML=='')){if(--domCheckCount){log('requeing onLoad callback, DOM not available');setTimeout(cb,250);return;}}
|
47
|
+
var docRoot=doc.body?doc.body:doc.documentElement;xhr.responseText=docRoot?docRoot.innerHTML:null;xhr.responseXML=doc.XMLDocument?doc.XMLDocument:doc;if(isXml)
|
48
|
+
s.dataType='xml';xhr.getResponseHeader=function(header){var headers={'content-type':s.dataType};return headers[header];};if(docRoot){xhr.status=Number(docRoot.getAttribute('status'))||xhr.status;xhr.statusText=docRoot.getAttribute('statusText')||xhr.statusText;}
|
49
|
+
var scr=/(json|script|text)/.test(s.dataType.toLowerCase());if(scr||s.textarea){var ta=doc.getElementsByTagName('textarea')[0];if(ta){xhr.responseText=ta.value;xhr.status=Number(ta.getAttribute('status'))||xhr.status;xhr.statusText=ta.getAttribute('statusText')||xhr.statusText;}
|
50
|
+
else if(scr){var pre=doc.getElementsByTagName('pre')[0];var b=doc.getElementsByTagName('body')[0];if(pre){xhr.responseText=pre.textContent?pre.textContent:pre.innerHTML;}
|
51
|
+
else if(b){xhr.responseText=b.innerHTML;}}}
|
52
|
+
else if(s.dataType=='xml'&&!xhr.responseXML&&xhr.responseText!=null){xhr.responseXML=toXml(xhr.responseText);}
|
53
|
+
try{data=httpData(xhr,s.dataType,s);}
|
54
|
+
catch(e){status='parsererror';xhr.error=errMsg=(e||status);}}
|
55
|
+
catch(e){log('error caught',e);status='error';xhr.error=errMsg=(e||status);}
|
56
|
+
if(xhr.aborted){log('upload aborted');status=null;}
|
57
|
+
if(xhr.status){status=(xhr.status>=200&&xhr.status<300||xhr.status===304)?'success':'error';}
|
58
|
+
if(status==='success'){s.success&&s.success.call(s.context,data,'success',xhr);g&&$.event.trigger("ajaxSuccess",[xhr,s]);}
|
59
|
+
else if(status){if(errMsg==undefined)
|
60
|
+
errMsg=xhr.statusText;s.error&&s.error.call(s.context,xhr,status,errMsg);g&&$.event.trigger("ajaxError",[xhr,s,errMsg]);}
|
61
|
+
g&&$.event.trigger("ajaxComplete",[xhr,s]);if(g&&!--$.active){$.event.trigger("ajaxStop");}
|
62
|
+
s.complete&&s.complete.call(s.context,xhr,status);callbackProcessed=true;if(s.timeout)
|
63
|
+
clearTimeout(timeoutHandle);setTimeout(function(){if(!s.iframeTarget)
|
64
|
+
$io.remove();xhr.responseXML=null;},100);}
|
65
|
+
var toXml=$.parseXML||function(s,doc){if(window.ActiveXObject){doc=new ActiveXObject('Microsoft.XMLDOM');doc.async='false';doc.loadXML(s);}
|
66
|
+
else{doc=(new DOMParser()).parseFromString(s,'text/xml');}
|
67
|
+
return(doc&&doc.documentElement&&doc.documentElement.nodeName!='parsererror')?doc:null;};var parseJSON=$.parseJSON||function(s){return window['eval']('('+s+')');};var httpData=function(xhr,type,s){var ct=xhr.getResponseHeader('content-type')||'',xml=type==='xml'||!type&&ct.indexOf('xml')>=0,data=xml?xhr.responseXML:xhr.responseText;if(xml&&data.documentElement.nodeName==='parsererror'){$.error&&$.error('parsererror');}
|
68
|
+
if(s&&s.dataFilter){data=s.dataFilter(data,type);}
|
69
|
+
if(typeof data==='string'){if(type==='json'||!type&&ct.indexOf('json')>=0){data=parseJSON(data);}else if(type==="script"||!type&&ct.indexOf("javascript")>=0){$.globalEval(data);}}
|
70
|
+
return data;};}};$.fn.ajaxForm=function(options){if(this.length===0){var o={s:this.selector,c:this.context};if(!$.isReady&&o.s){log('DOM not ready, queuing ajaxForm');$(function(){$(o.s,o.c).ajaxForm(options);});return this;}
|
71
|
+
log('terminating; zero elements found by selector'+($.isReady?'':' (DOM not ready)'));return this;}
|
72
|
+
return this.ajaxFormUnbind().bind('submit.form-plugin',function(e){if(!e.isDefaultPrevented()){e.preventDefault();$(this).ajaxSubmit(options);}}).bind('click.form-plugin',function(e){var target=e.target;var $el=$(target);if(!($el.is(":submit,input:image"))){var t=$el.closest(':submit');if(t.length==0){return;}
|
73
|
+
target=t[0];}
|
74
|
+
var form=this;form.clk=target;if(target.type=='image'){if(e.offsetX!=undefined){form.clk_x=e.offsetX;form.clk_y=e.offsetY;}else if(typeof $.fn.offset=='function'){var offset=$el.offset();form.clk_x=e.pageX-offset.left;form.clk_y=e.pageY-offset.top;}else{form.clk_x=e.pageX-target.offsetLeft;form.clk_y=e.pageY-target.offsetTop;}}
|
75
|
+
setTimeout(function(){form.clk=form.clk_x=form.clk_y=null;},100);});};$.fn.ajaxFormUnbind=function(){return this.unbind('submit.form-plugin click.form-plugin');};$.fn.formToArray=function(semantic){var a=[];if(this.length===0){return a;}
|
76
|
+
var form=this[0];var els=semantic?form.getElementsByTagName('*'):form.elements;if(!els){return a;}
|
77
|
+
var i,j,n,v,el,max,jmax;for(i=0,max=els.length;i<max;i++){el=els[i];n=el.name;if(!n){continue;}
|
78
|
+
if(semantic&&form.clk&&el.type=="image"){if(!el.disabled&&form.clk==el){a.push({name:n,value:$(el).val()});a.push({name:n+'.x',value:form.clk_x},{name:n+'.y',value:form.clk_y});}
|
79
|
+
continue;}
|
80
|
+
v=$.fieldValue(el,true);if(v&&v.constructor==Array){for(j=0,jmax=v.length;j<jmax;j++){a.push({name:n,value:v[j]});}}
|
81
|
+
else if(v!==null&&typeof v!='undefined'){a.push({name:n,value:v});}}
|
82
|
+
if(!semantic&&form.clk){var $input=$(form.clk),input=$input[0];n=input.name;if(n&&!input.disabled&&input.type=='image'){a.push({name:n,value:$input.val()});a.push({name:n+'.x',value:form.clk_x},{name:n+'.y',value:form.clk_y});}}
|
83
|
+
return a;};$.fn.formSerialize=function(semantic){return $.param(this.formToArray(semantic));};$.fn.fieldSerialize=function(successful){var a=[];this.each(function(){var n=this.name;if(!n){return;}
|
84
|
+
var v=$.fieldValue(this,successful);if(v&&v.constructor==Array){for(var i=0,max=v.length;i<max;i++){a.push({name:n,value:v[i]});}}
|
85
|
+
else if(v!==null&&typeof v!='undefined'){a.push({name:this.name,value:v});}});return $.param(a);};$.fn.fieldValue=function(successful){for(var val=[],i=0,max=this.length;i<max;i++){var el=this[i];var v=$.fieldValue(el,successful);if(v===null||typeof v=='undefined'||(v.constructor==Array&&!v.length)){continue;}
|
86
|
+
v.constructor==Array?$.merge(val,v):val.push(v);}
|
87
|
+
return val;};$.fieldValue=function(el,successful){var n=el.name,t=el.type,tag=el.tagName.toLowerCase();if(successful===undefined){successful=true;}
|
88
|
+
if(successful&&(!n||el.disabled||t=='reset'||t=='button'||(t=='checkbox'||t=='radio')&&!el.checked||(t=='submit'||t=='image')&&el.form&&el.form.clk!=el||tag=='select'&&el.selectedIndex==-1)){return null;}
|
89
|
+
if(tag=='select'){var index=el.selectedIndex;if(index<0){return null;}
|
90
|
+
var a=[],ops=el.options;var one=(t=='select-one');var max=(one?index+1:ops.length);for(var i=(one?index:0);i<max;i++){var op=ops[i];if(op.selected){var v=op.value;if(!v){v=(op.attributes&&op.attributes['value']&&!(op.attributes['value'].specified))?op.text:op.value;}
|
91
|
+
if(one){return v;}
|
92
|
+
a.push(v);}}
|
93
|
+
return a;}
|
94
|
+
return $(el).val();};$.fn.clearForm=function(){return this.each(function(){$('input,select,textarea',this).clearFields();});};$.fn.clearFields=$.fn.clearInputs=function(){return this.each(function(){var t=this.type,tag=this.tagName.toLowerCase();if(t=='text'||t=='password'||tag=='textarea'){this.value='';}
|
95
|
+
else if(t=='checkbox'||t=='radio'){this.checked=false;}
|
96
|
+
else if(tag=='select'){this.selectedIndex=-1;}});};$.fn.resetForm=function(){return this.each(function(){if(typeof this.reset=='function'||(typeof this.reset=='object'&&!this.reset.nodeType)){this.reset();}});};$.fn.enable=function(b){if(b===undefined){b=true;}
|
97
|
+
return this.each(function(){this.disabled=!b;});};$.fn.selected=function(select){if(select===undefined){select=true;}
|
98
|
+
return this.each(function(){var t=this.type;if(t=='checkbox'||t=='radio'){this.checked=select;}
|
99
|
+
else if(this.tagName.toLowerCase()=='option'){var $sel=$(this).parent('select');if(select&&$sel[0]&&$sel[0].type=='select-one'){$sel.find('option').selected(false);}
|
100
|
+
this.selected=select;}});};function log(){if($.fn.ajaxSubmit.debug){var msg='[jquery.form] '+Array.prototype.join.call(arguments,'');if(window.console&&window.console.log){window.console.log(msg);}
|
101
|
+
else if(window.opera&&window.opera.postError){window.opera.postError(msg);}}};})(jQuery);
|
@@ -1,9 +1,14 @@
|
|
1
|
+
require 'generators/acts_as_approvable/base'
|
2
|
+
|
1
3
|
module Erb
|
2
4
|
module Generators
|
3
5
|
class ActsAsApprovableGenerator < Rails::Generators::Base
|
6
|
+
include ActsAsApprovable::Generators::Base
|
7
|
+
|
4
8
|
source_root File.expand_path('../templates', __FILE__)
|
5
9
|
|
6
10
|
class_option :owner, :type => :string, :optional => true, :desc => 'Model that can own approvals'
|
11
|
+
class_option :scripts, :type => :boolean, :optional => true, :default => false
|
7
12
|
|
8
13
|
def copy_view_files
|
9
14
|
template 'index.html.erb', 'app/views/approvals/index.html.erb'
|
@@ -23,22 +28,6 @@ module Erb
|
|
23
28
|
def filename_with_extensions(name)
|
24
29
|
[name, format, handler].compact.join('.')
|
25
30
|
end
|
26
|
-
|
27
|
-
def owner?
|
28
|
-
options[:owner].present?
|
29
|
-
end
|
30
|
-
|
31
|
-
def collection_actions
|
32
|
-
actions = [:index, :history]
|
33
|
-
actions << :mine if owner?
|
34
|
-
actions.map { |a| ":#{a}" }
|
35
|
-
end
|
36
|
-
|
37
|
-
def member_actions
|
38
|
-
actions = [:approve, :reject]
|
39
|
-
actions << :assign if owner?
|
40
|
-
actions.map { |a| ":#{a}" }
|
41
|
-
end
|
42
31
|
end
|
43
32
|
end
|
44
33
|
end
|
@@ -16,8 +16,8 @@
|
|
16
16
|
<% if owner? %> <td><%%= render :partial => 'owner_select', :locals => {:approval => approval} %></td>
|
17
17
|
<% end %> <td><%%= approval.state %></td>
|
18
18
|
<td class='actions'>
|
19
|
-
<%%= link_to('Approve', approve_approval_path(approval)) %>
|
20
|
-
<%%= link_to('Reject', reject_approval_path(approval)) %>
|
19
|
+
<%%= link_to('Approve', approve_approval_path(approval), :class => 'approve') %>
|
20
|
+
<%%= link_to('Reject', reject_approval_path(approval), :class => 'reject') %>
|
21
21
|
</td>
|
22
22
|
</tr>
|
23
23
|
<%% end %>
|
@@ -1,9 +1,14 @@
|
|
1
|
+
require 'generators/acts_as_approvable/base'
|
2
|
+
|
1
3
|
module Haml
|
2
4
|
module Generators
|
3
5
|
class ActsAsApprovableGenerator < Rails::Generators::Base
|
6
|
+
include ActsAsApprovable::Generators::Base
|
7
|
+
|
4
8
|
source_root File.expand_path('../templates', __FILE__)
|
5
9
|
|
6
10
|
class_option :owner, :type => :string, :optional => true, :desc => 'Model that can own approvals'
|
11
|
+
class_option :scripts, :type => :boolean, :optional => true, :default => false
|
7
12
|
|
8
13
|
def copy_view_files
|
9
14
|
template 'index.html.haml', 'app/views/approvals/index.html.haml'
|
@@ -23,22 +28,6 @@ module Haml
|
|
23
28
|
def filename_with_extensions(name)
|
24
29
|
[name, format, handler].compact.join('.')
|
25
30
|
end
|
26
|
-
|
27
|
-
def owner?
|
28
|
-
options[:owner].present?
|
29
|
-
end
|
30
|
-
|
31
|
-
def collection_actions
|
32
|
-
actions = [:index, :history]
|
33
|
-
actions << :mine if owner?
|
34
|
-
actions.map { |a| ":#{a}" }
|
35
|
-
end
|
36
|
-
|
37
|
-
def member_actions
|
38
|
-
actions = [:approve, :reject]
|
39
|
-
actions << :assign if owner?
|
40
|
-
actions.map { |a| ":#{a}" }
|
41
|
-
end
|
42
31
|
end
|
43
32
|
end
|
44
33
|
end
|
@@ -14,6 +14,6 @@
|
|
14
14
|
<% if owner? %> %td= render :partial => 'owner_select', :locals => {:approval => approval}
|
15
15
|
<% end %> %td= approval.state
|
16
16
|
%td.actions
|
17
|
-
= link_to('Approve', approve_approval_path(approval))
|
18
|
-
= link_to('Reject', reject_approval_path(approval))
|
17
|
+
= link_to('Approve', approve_approval_path(approval), :class => 'approve')
|
18
|
+
= link_to('Reject', reject_approval_path(approval), :class => 'reject')
|
19
19
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts-as-approvable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -15,7 +15,7 @@ date: 2012-02-14 00:00:00.000000000Z
|
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: activerecord
|
18
|
-
requirement: &
|
18
|
+
requirement: &70261451581460 !ruby/object:Gem::Requirement
|
19
19
|
none: false
|
20
20
|
requirements:
|
21
21
|
- - ~>
|
@@ -23,10 +23,10 @@ dependencies:
|
|
23
23
|
version: '2.3'
|
24
24
|
type: :development
|
25
25
|
prerelease: false
|
26
|
-
version_requirements: *
|
26
|
+
version_requirements: *70261451581460
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: appraisal
|
29
|
-
requirement: &
|
29
|
+
requirement: &70261451581040 !ruby/object:Gem::Requirement
|
30
30
|
none: false
|
31
31
|
requirements:
|
32
32
|
- - ! '>='
|
@@ -34,10 +34,10 @@ dependencies:
|
|
34
34
|
version: '0'
|
35
35
|
type: :development
|
36
36
|
prerelease: false
|
37
|
-
version_requirements: *
|
37
|
+
version_requirements: *70261451581040
|
38
38
|
- !ruby/object:Gem::Dependency
|
39
39
|
name: redcarpet
|
40
|
-
requirement: &
|
40
|
+
requirement: &70261451580580 !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
42
42
|
requirements:
|
43
43
|
- - ! '>='
|
@@ -45,10 +45,10 @@ dependencies:
|
|
45
45
|
version: '0'
|
46
46
|
type: :development
|
47
47
|
prerelease: false
|
48
|
-
version_requirements: *
|
48
|
+
version_requirements: *70261451580580
|
49
49
|
- !ruby/object:Gem::Dependency
|
50
50
|
name: shoulda
|
51
|
-
requirement: &
|
51
|
+
requirement: &70261451580100 !ruby/object:Gem::Requirement
|
52
52
|
none: false
|
53
53
|
requirements:
|
54
54
|
- - ! '>='
|
@@ -56,10 +56,10 @@ dependencies:
|
|
56
56
|
version: '0'
|
57
57
|
type: :development
|
58
58
|
prerelease: false
|
59
|
-
version_requirements: *
|
59
|
+
version_requirements: *70261451580100
|
60
60
|
- !ruby/object:Gem::Dependency
|
61
61
|
name: sqlite3
|
62
|
-
requirement: &
|
62
|
+
requirement: &70261451579620 !ruby/object:Gem::Requirement
|
63
63
|
none: false
|
64
64
|
requirements:
|
65
65
|
- - ! '>='
|
@@ -67,10 +67,10 @@ dependencies:
|
|
67
67
|
version: '0'
|
68
68
|
type: :development
|
69
69
|
prerelease: false
|
70
|
-
version_requirements: *
|
70
|
+
version_requirements: *70261451579620
|
71
71
|
- !ruby/object:Gem::Dependency
|
72
72
|
name: mocha
|
73
|
-
requirement: &
|
73
|
+
requirement: &70261451579100 !ruby/object:Gem::Requirement
|
74
74
|
none: false
|
75
75
|
requirements:
|
76
76
|
- - ! '>='
|
@@ -78,10 +78,10 @@ dependencies:
|
|
78
78
|
version: '0'
|
79
79
|
type: :development
|
80
80
|
prerelease: false
|
81
|
-
version_requirements: *
|
81
|
+
version_requirements: *70261451579100
|
82
82
|
- !ruby/object:Gem::Dependency
|
83
83
|
name: rake
|
84
|
-
requirement: &
|
84
|
+
requirement: &70261451571860 !ruby/object:Gem::Requirement
|
85
85
|
none: false
|
86
86
|
requirements:
|
87
87
|
- - ! '>='
|
@@ -89,10 +89,10 @@ dependencies:
|
|
89
89
|
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
|
-
version_requirements: *
|
92
|
+
version_requirements: *70261451571860
|
93
93
|
- !ruby/object:Gem::Dependency
|
94
94
|
name: simplecov
|
95
|
-
requirement: &
|
95
|
+
requirement: &70261451571300 !ruby/object:Gem::Requirement
|
96
96
|
none: false
|
97
97
|
requirements:
|
98
98
|
- - ! '>='
|
@@ -100,10 +100,10 @@ dependencies:
|
|
100
100
|
version: '0'
|
101
101
|
type: :development
|
102
102
|
prerelease: false
|
103
|
-
version_requirements: *
|
103
|
+
version_requirements: *70261451571300
|
104
104
|
- !ruby/object:Gem::Dependency
|
105
105
|
name: yard
|
106
|
-
requirement: &
|
106
|
+
requirement: &70261451570720 !ruby/object:Gem::Requirement
|
107
107
|
none: false
|
108
108
|
requirements:
|
109
109
|
- - ! '>='
|
@@ -111,10 +111,10 @@ dependencies:
|
|
111
111
|
version: '0'
|
112
112
|
type: :development
|
113
113
|
prerelease: false
|
114
|
-
version_requirements: *
|
114
|
+
version_requirements: *70261451570720
|
115
115
|
- !ruby/object:Gem::Dependency
|
116
116
|
name: pry
|
117
|
-
requirement: &
|
117
|
+
requirement: &70261451569920 !ruby/object:Gem::Requirement
|
118
118
|
none: false
|
119
119
|
requirements:
|
120
120
|
- - ! '>='
|
@@ -122,7 +122,7 @@ dependencies:
|
|
122
122
|
version: '0'
|
123
123
|
type: :development
|
124
124
|
prerelease: false
|
125
|
-
version_requirements: *
|
125
|
+
version_requirements: *70261451569920
|
126
126
|
description: Generic approval queues for record creation and updates
|
127
127
|
email: dwarf@girsbrain.org
|
128
128
|
executables: []
|
@@ -149,9 +149,11 @@ files:
|
|
149
149
|
- gemfiles/rails32.gemfile.lock
|
150
150
|
- generators/acts_as_approvable/USAGE
|
151
151
|
- generators/acts_as_approvable/acts_as_approvable_generator.rb
|
152
|
+
- generators/acts_as_approvable/templates/approvals.js
|
152
153
|
- generators/acts_as_approvable/templates/approvals_controller.rb
|
153
154
|
- generators/acts_as_approvable/templates/create_approvals.rb
|
154
155
|
- generators/acts_as_approvable/templates/initializer.rb
|
156
|
+
- generators/acts_as_approvable/templates/jquery.form.js
|
155
157
|
- generators/acts_as_approvable/templates/views/erb/_owner_select.html.erb
|
156
158
|
- generators/acts_as_approvable/templates/views/erb/_table.html.erb
|
157
159
|
- generators/acts_as_approvable/templates/views/erb/index.html.erb
|
@@ -166,11 +168,13 @@ files:
|
|
166
168
|
- lib/acts_as_approvable/error.rb
|
167
169
|
- lib/acts_as_approvable/ownership.rb
|
168
170
|
- lib/acts_as_approvable/railtie.rb
|
169
|
-
- lib/generators/acts_as_approvable.rb
|
170
171
|
- lib/generators/acts_as_approvable/USAGE
|
171
172
|
- lib/generators/acts_as_approvable/acts_as_approvable_generator.rb
|
173
|
+
- lib/generators/acts_as_approvable/base.rb
|
174
|
+
- lib/generators/acts_as_approvable/templates/approvals.js
|
172
175
|
- lib/generators/acts_as_approvable/templates/approvals_controller.rb
|
173
176
|
- lib/generators/acts_as_approvable/templates/create_approvals.rb
|
177
|
+
- lib/generators/acts_as_approvable/templates/jquery.form.js
|
174
178
|
- lib/generators/erb/acts_as_approvable_generator.rb
|
175
179
|
- lib/generators/erb/templates/_owner_select.html.erb
|
176
180
|
- lib/generators/erb/templates/_table.html.erb
|
File without changes
|