acts-as-approvable 0.6.4 → 0.6.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|