rails_admin_history_rollback 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a12d7f962a2d0b27c5455677619e3400ff66fa1b
4
+ data.tar.gz: 3ed591875d01ead17dff40c133b54b5491ca2349
5
+ SHA512:
6
+ metadata.gz: 4d573c00a69cb1cf9cb7d299b16eb730bcdacdbc4dd946533380a0a95fc6e9ec71858dc1d20937cf1b0c2b9ae4dacae1c98e1e02d6b44f3d1b7a21a520fe49ed
7
+ data.tar.gz: 1f8eaf7a2c1a81685ff627aef4543dc550cf7469af02cb7ae02fe47589856fe20ddeac6c6b6069c25939d35712ea906aaa2b9f69f8afc19c581cb731ca1557f5
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2015 Rikki Pitt
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,49 @@
1
+ (function(){function diff_match_patch(){this.Diff_Timeout=1;this.Diff_EditCost=4;this.Match_Threshold=0.5;this.Match_Distance=1E3;this.Patch_DeleteThreshold=0.5;this.Patch_Margin=4;this.Match_MaxBits=32}
2
+ diff_match_patch.prototype.diff_main=function(a,b,c,d){"undefined"==typeof d&&(d=0>=this.Diff_Timeout?Number.MAX_VALUE:(new Date).getTime()+1E3*this.Diff_Timeout);if(null==a||null==b)throw Error("Null input. (diff_main)");if(a==b)return a?[[0,a]]:[];"undefined"==typeof c&&(c=!0);var e=c,f=this.diff_commonPrefix(a,b);c=a.substring(0,f);a=a.substring(f);b=b.substring(f);var f=this.diff_commonSuffix(a,b),g=a.substring(a.length-f);a=a.substring(0,a.length-f);b=b.substring(0,b.length-f);a=this.diff_compute_(a,
3
+ b,e,d);c&&a.unshift([0,c]);g&&a.push([0,g]);this.diff_cleanupMerge(a);return a};
4
+ diff_match_patch.prototype.diff_compute_=function(a,b,c,d){if(!a)return[[1,b]];if(!b)return[[-1,a]];var e=a.length>b.length?a:b,f=a.length>b.length?b:a,g=e.indexOf(f);return-1!=g?(c=[[1,e.substring(0,g)],[0,f],[1,e.substring(g+f.length)]],a.length>b.length&&(c[0][0]=c[2][0]=-1),c):1==f.length?[[-1,a],[1,b]]:(e=this.diff_halfMatch_(a,b))?(f=e[0],a=e[1],g=e[2],b=e[3],e=e[4],f=this.diff_main(f,g,c,d),c=this.diff_main(a,b,c,d),f.concat([[0,e]],c)):c&&100<a.length&&100<b.length?this.diff_lineMode_(a,b,
5
+ d):this.diff_bisect_(a,b,d)};
6
+ diff_match_patch.prototype.diff_lineMode_=function(a,b,c){var d=this.diff_linesToChars_(a,b);a=d.chars1;b=d.chars2;d=d.lineArray;a=this.diff_main(a,b,!1,c);this.diff_charsToLines_(a,d);this.diff_cleanupSemantic(a);a.push([0,""]);for(var e=d=b=0,f="",g="";b<a.length;){switch(a[b][0]){case 1:e++;g+=a[b][1];break;case -1:d++;f+=a[b][1];break;case 0:if(1<=d&&1<=e){a.splice(b-d-e,d+e);b=b-d-e;d=this.diff_main(f,g,!1,c);for(e=d.length-1;0<=e;e--)a.splice(b,0,d[e]);b+=d.length}d=e=0;g=f=""}b++}a.pop();return a};
7
+ diff_match_patch.prototype.diff_bisect_=function(a,b,c){for(var d=a.length,e=b.length,f=Math.ceil((d+e)/2),g=f,h=2*f,j=Array(h),i=Array(h),k=0;k<h;k++)j[k]=-1,i[k]=-1;j[g+1]=0;i[g+1]=0;for(var k=d-e,q=0!=k%2,r=0,t=0,p=0,w=0,v=0;v<f&&!((new Date).getTime()>c);v++){for(var n=-v+r;n<=v-t;n+=2){var l=g+n,m;m=n==-v||n!=v&&j[l-1]<j[l+1]?j[l+1]:j[l-1]+1;for(var s=m-n;m<d&&s<e&&a.charAt(m)==b.charAt(s);)m++,s++;j[l]=m;if(m>d)t+=2;else if(s>e)r+=2;else if(q&&(l=g+k-n,0<=l&&l<h&&-1!=i[l])){var u=d-i[l];if(m>=
8
+ u)return this.diff_bisectSplit_(a,b,m,s,c)}}for(n=-v+p;n<=v-w;n+=2){l=g+n;u=n==-v||n!=v&&i[l-1]<i[l+1]?i[l+1]:i[l-1]+1;for(m=u-n;u<d&&m<e&&a.charAt(d-u-1)==b.charAt(e-m-1);)u++,m++;i[l]=u;if(u>d)w+=2;else if(m>e)p+=2;else if(!q&&(l=g+k-n,0<=l&&(l<h&&-1!=j[l])&&(m=j[l],s=g+m-l,u=d-u,m>=u)))return this.diff_bisectSplit_(a,b,m,s,c)}}return[[-1,a],[1,b]]};
9
+ diff_match_patch.prototype.diff_bisectSplit_=function(a,b,c,d,e){var f=a.substring(0,c),g=b.substring(0,d);a=a.substring(c);b=b.substring(d);f=this.diff_main(f,g,!1,e);e=this.diff_main(a,b,!1,e);return f.concat(e)};
10
+ diff_match_patch.prototype.diff_linesToChars_=function(a,b){function c(a){for(var b="",c=0,f=-1,g=d.length;f<a.length-1;){f=a.indexOf("\n",c);-1==f&&(f=a.length-1);var r=a.substring(c,f+1),c=f+1;(e.hasOwnProperty?e.hasOwnProperty(r):void 0!==e[r])?b+=String.fromCharCode(e[r]):(b+=String.fromCharCode(g),e[r]=g,d[g++]=r)}return b}var d=[],e={};d[0]="";var f=c(a),g=c(b);return{chars1:f,chars2:g,lineArray:d}};
11
+ diff_match_patch.prototype.diff_charsToLines_=function(a,b){for(var c=0;c<a.length;c++){for(var d=a[c][1],e=[],f=0;f<d.length;f++)e[f]=b[d.charCodeAt(f)];a[c][1]=e.join("")}};diff_match_patch.prototype.diff_commonPrefix=function(a,b){if(!a||!b||a.charAt(0)!=b.charAt(0))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;)a.substring(f,e)==b.substring(f,e)?f=c=e:d=e,e=Math.floor((d-c)/2+c);return e};
12
+ diff_match_patch.prototype.diff_commonSuffix=function(a,b){if(!a||!b||a.charAt(a.length-1)!=b.charAt(b.length-1))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;)a.substring(a.length-e,a.length-f)==b.substring(b.length-e,b.length-f)?f=c=e:d=e,e=Math.floor((d-c)/2+c);return e};
13
+ diff_match_patch.prototype.diff_commonOverlap_=function(a,b){var c=a.length,d=b.length;if(0==c||0==d)return 0;c>d?a=a.substring(c-d):c<d&&(b=b.substring(0,c));c=Math.min(c,d);if(a==b)return c;for(var d=0,e=1;;){var f=a.substring(c-e),f=b.indexOf(f);if(-1==f)return d;e+=f;if(0==f||a.substring(c-e)==b.substring(0,e))d=e,e++}};
14
+ diff_match_patch.prototype.diff_halfMatch_=function(a,b){function c(a,b,c){for(var d=a.substring(c,c+Math.floor(a.length/4)),e=-1,g="",h,j,n,l;-1!=(e=b.indexOf(d,e+1));){var m=f.diff_commonPrefix(a.substring(c),b.substring(e)),s=f.diff_commonSuffix(a.substring(0,c),b.substring(0,e));g.length<s+m&&(g=b.substring(e-s,e)+b.substring(e,e+m),h=a.substring(0,c-s),j=a.substring(c+m),n=b.substring(0,e-s),l=b.substring(e+m))}return 2*g.length>=a.length?[h,j,n,l,g]:null}if(0>=this.Diff_Timeout)return null;
15
+ var d=a.length>b.length?a:b,e=a.length>b.length?b:a;if(4>d.length||2*e.length<d.length)return null;var f=this,g=c(d,e,Math.ceil(d.length/4)),d=c(d,e,Math.ceil(d.length/2)),h;if(!g&&!d)return null;h=d?g?g[4].length>d[4].length?g:d:d:g;var j;a.length>b.length?(g=h[0],d=h[1],e=h[2],j=h[3]):(e=h[0],j=h[1],g=h[2],d=h[3]);h=h[4];return[g,d,e,j,h]};
16
+ diff_match_patch.prototype.diff_cleanupSemantic=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=0,h=0,j=0,i=0;f<a.length;)0==a[f][0]?(c[d++]=f,g=j,h=i,i=j=0,e=a[f][1]):(1==a[f][0]?j+=a[f][1].length:i+=a[f][1].length,e&&(e.length<=Math.max(g,h)&&e.length<=Math.max(j,i))&&(a.splice(c[d-1],0,[-1,e]),a[c[d-1]+1][0]=1,d--,d--,f=0<d?c[d-1]:-1,i=j=h=g=0,e=null,b=!0)),f++;b&&this.diff_cleanupMerge(a);this.diff_cleanupSemanticLossless(a);for(f=1;f<a.length;){if(-1==a[f-1][0]&&1==a[f][0]){b=a[f-1][1];c=a[f][1];
17
+ d=this.diff_commonOverlap_(b,c);e=this.diff_commonOverlap_(c,b);if(d>=e){if(d>=b.length/2||d>=c.length/2)a.splice(f,0,[0,c.substring(0,d)]),a[f-1][1]=b.substring(0,b.length-d),a[f+1][1]=c.substring(d),f++}else if(e>=b.length/2||e>=c.length/2)a.splice(f,0,[0,b.substring(0,e)]),a[f-1][0]=1,a[f-1][1]=c.substring(0,c.length-e),a[f+1][0]=-1,a[f+1][1]=b.substring(e),f++;f++}f++}};
18
+ diff_match_patch.prototype.diff_cleanupSemanticLossless=function(a){function b(a,b){if(!a||!b)return 6;var c=a.charAt(a.length-1),d=b.charAt(0),e=c.match(diff_match_patch.nonAlphaNumericRegex_),f=d.match(diff_match_patch.nonAlphaNumericRegex_),g=e&&c.match(diff_match_patch.whitespaceRegex_),h=f&&d.match(diff_match_patch.whitespaceRegex_),c=g&&c.match(diff_match_patch.linebreakRegex_),d=h&&d.match(diff_match_patch.linebreakRegex_),i=c&&a.match(diff_match_patch.blanklineEndRegex_),j=d&&b.match(diff_match_patch.blanklineStartRegex_);
19
+ return i||j?5:c||d?4:e&&!g&&h?3:g||h?2:e||f?1:0}for(var c=1;c<a.length-1;){if(0==a[c-1][0]&&0==a[c+1][0]){var d=a[c-1][1],e=a[c][1],f=a[c+1][1],g=this.diff_commonSuffix(d,e);if(g)var h=e.substring(e.length-g),d=d.substring(0,d.length-g),e=h+e.substring(0,e.length-g),f=h+f;for(var g=d,h=e,j=f,i=b(d,e)+b(e,f);e.charAt(0)===f.charAt(0);){var d=d+e.charAt(0),e=e.substring(1)+f.charAt(0),f=f.substring(1),k=b(d,e)+b(e,f);k>=i&&(i=k,g=d,h=e,j=f)}a[c-1][1]!=g&&(g?a[c-1][1]=g:(a.splice(c-1,1),c--),a[c][1]=
20
+ h,j?a[c+1][1]=j:(a.splice(c+1,1),c--))}c++}};diff_match_patch.nonAlphaNumericRegex_=/[^a-zA-Z0-9]/;diff_match_patch.whitespaceRegex_=/\s/;diff_match_patch.linebreakRegex_=/[\r\n]/;diff_match_patch.blanklineEndRegex_=/\n\r?\n$/;diff_match_patch.blanklineStartRegex_=/^\r?\n\r?\n/;
21
+ diff_match_patch.prototype.diff_cleanupEfficiency=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=!1,h=!1,j=!1,i=!1;f<a.length;){if(0==a[f][0])a[f][1].length<this.Diff_EditCost&&(j||i)?(c[d++]=f,g=j,h=i,e=a[f][1]):(d=0,e=null),j=i=!1;else if(-1==a[f][0]?i=!0:j=!0,e&&(g&&h&&j&&i||e.length<this.Diff_EditCost/2&&3==g+h+j+i))a.splice(c[d-1],0,[-1,e]),a[c[d-1]+1][0]=1,d--,e=null,g&&h?(j=i=!0,d=0):(d--,f=0<d?c[d-1]:-1,j=i=!1),b=!0;f++}b&&this.diff_cleanupMerge(a)};
22
+ diff_match_patch.prototype.diff_cleanupMerge=function(a){a.push([0,""]);for(var b=0,c=0,d=0,e="",f="",g;b<a.length;)switch(a[b][0]){case 1:d++;f+=a[b][1];b++;break;case -1:c++;e+=a[b][1];b++;break;case 0:1<c+d?(0!==c&&0!==d&&(g=this.diff_commonPrefix(f,e),0!==g&&(0<b-c-d&&0==a[b-c-d-1][0]?a[b-c-d-1][1]+=f.substring(0,g):(a.splice(0,0,[0,f.substring(0,g)]),b++),f=f.substring(g),e=e.substring(g)),g=this.diff_commonSuffix(f,e),0!==g&&(a[b][1]=f.substring(f.length-g)+a[b][1],f=f.substring(0,f.length-
23
+ g),e=e.substring(0,e.length-g))),0===c?a.splice(b-d,c+d,[1,f]):0===d?a.splice(b-c,c+d,[-1,e]):a.splice(b-c-d,c+d,[-1,e],[1,f]),b=b-c-d+(c?1:0)+(d?1:0)+1):0!==b&&0==a[b-1][0]?(a[b-1][1]+=a[b][1],a.splice(b,1)):b++,c=d=0,f=e=""}""===a[a.length-1][1]&&a.pop();c=!1;for(b=1;b<a.length-1;)0==a[b-1][0]&&0==a[b+1][0]&&(a[b][1].substring(a[b][1].length-a[b-1][1].length)==a[b-1][1]?(a[b][1]=a[b-1][1]+a[b][1].substring(0,a[b][1].length-a[b-1][1].length),a[b+1][1]=a[b-1][1]+a[b+1][1],a.splice(b-1,1),c=!0):a[b][1].substring(0,
24
+ a[b+1][1].length)==a[b+1][1]&&(a[b-1][1]+=a[b+1][1],a[b][1]=a[b][1].substring(a[b+1][1].length)+a[b+1][1],a.splice(b+1,1),c=!0)),b++;c&&this.diff_cleanupMerge(a)};diff_match_patch.prototype.diff_xIndex=function(a,b){var c=0,d=0,e=0,f=0,g;for(g=0;g<a.length;g++){1!==a[g][0]&&(c+=a[g][1].length);-1!==a[g][0]&&(d+=a[g][1].length);if(c>b)break;e=c;f=d}return a.length!=g&&-1===a[g][0]?f:f+(b-e)};
25
+ diff_match_patch.prototype.diff_prettyHtml=function(a){for(var b=[],c=/&/g,d=/</g,e=/>/g,f=/\n/g,g=0;g<a.length;g++){var h=a[g][0],j=a[g][1],j=j.replace(c,"&amp;").replace(d,"&lt;").replace(e,"&gt;").replace(f,"&para;<br>");switch(h){case 1:b[g]='<ins style="background:#e6ffe6;">'+j+"</ins>";break;case -1:b[g]='<del style="background:#ffe6e6;">'+j+"</del>";break;case 0:b[g]="<span>"+j+"</span>"}}return b.join("")};
26
+ diff_match_patch.prototype.diff_text1=function(a){for(var b=[],c=0;c<a.length;c++)1!==a[c][0]&&(b[c]=a[c][1]);return b.join("")};diff_match_patch.prototype.diff_text2=function(a){for(var b=[],c=0;c<a.length;c++)-1!==a[c][0]&&(b[c]=a[c][1]);return b.join("")};diff_match_patch.prototype.diff_levenshtein=function(a){for(var b=0,c=0,d=0,e=0;e<a.length;e++){var f=a[e][0],g=a[e][1];switch(f){case 1:c+=g.length;break;case -1:d+=g.length;break;case 0:b+=Math.max(c,d),d=c=0}}return b+=Math.max(c,d)};
27
+ diff_match_patch.prototype.diff_toDelta=function(a){for(var b=[],c=0;c<a.length;c++)switch(a[c][0]){case 1:b[c]="+"+encodeURI(a[c][1]);break;case -1:b[c]="-"+a[c][1].length;break;case 0:b[c]="="+a[c][1].length}return b.join("\t").replace(/%20/g," ")};
28
+ diff_match_patch.prototype.diff_fromDelta=function(a,b){for(var c=[],d=0,e=0,f=b.split(/\t/g),g=0;g<f.length;g++){var h=f[g].substring(1);switch(f[g].charAt(0)){case "+":try{c[d++]=[1,decodeURI(h)]}catch(j){throw Error("Illegal escape in diff_fromDelta: "+h);}break;case "-":case "=":var i=parseInt(h,10);if(isNaN(i)||0>i)throw Error("Invalid number in diff_fromDelta: "+h);h=a.substring(e,e+=i);"="==f[g].charAt(0)?c[d++]=[0,h]:c[d++]=[-1,h];break;default:if(f[g])throw Error("Invalid diff operation in diff_fromDelta: "+
29
+ f[g]);}}if(e!=a.length)throw Error("Delta length ("+e+") does not equal source text length ("+a.length+").");return c};diff_match_patch.prototype.match_main=function(a,b,c){if(null==a||null==b||null==c)throw Error("Null input. (match_main)");c=Math.max(0,Math.min(c,a.length));return a==b?0:a.length?a.substring(c,c+b.length)==b?c:this.match_bitap_(a,b,c):-1};
30
+ diff_match_patch.prototype.match_bitap_=function(a,b,c){function d(a,d){var e=a/b.length,g=Math.abs(c-d);return!f.Match_Distance?g?1:e:e+g/f.Match_Distance}if(b.length>this.Match_MaxBits)throw Error("Pattern too long for this browser.");var e=this.match_alphabet_(b),f=this,g=this.Match_Threshold,h=a.indexOf(b,c);-1!=h&&(g=Math.min(d(0,h),g),h=a.lastIndexOf(b,c+b.length),-1!=h&&(g=Math.min(d(0,h),g)));for(var j=1<<b.length-1,h=-1,i,k,q=b.length+a.length,r,t=0;t<b.length;t++){i=0;for(k=q;i<k;)d(t,c+
31
+ k)<=g?i=k:q=k,k=Math.floor((q-i)/2+i);q=k;i=Math.max(1,c-k+1);var p=Math.min(c+k,a.length)+b.length;k=Array(p+2);for(k[p+1]=(1<<t)-1;p>=i;p--){var w=e[a.charAt(p-1)];k[p]=0===t?(k[p+1]<<1|1)&w:(k[p+1]<<1|1)&w|((r[p+1]|r[p])<<1|1)|r[p+1];if(k[p]&j&&(w=d(t,p-1),w<=g))if(g=w,h=p-1,h>c)i=Math.max(1,2*c-h);else break}if(d(t+1,c)>g)break;r=k}return h};
32
+ diff_match_patch.prototype.match_alphabet_=function(a){for(var b={},c=0;c<a.length;c++)b[a.charAt(c)]=0;for(c=0;c<a.length;c++)b[a.charAt(c)]|=1<<a.length-c-1;return b};
33
+ diff_match_patch.prototype.patch_addContext_=function(a,b){if(0!=b.length){for(var c=b.substring(a.start2,a.start2+a.length1),d=0;b.indexOf(c)!=b.lastIndexOf(c)&&c.length<this.Match_MaxBits-this.Patch_Margin-this.Patch_Margin;)d+=this.Patch_Margin,c=b.substring(a.start2-d,a.start2+a.length1+d);d+=this.Patch_Margin;(c=b.substring(a.start2-d,a.start2))&&a.diffs.unshift([0,c]);(d=b.substring(a.start2+a.length1,a.start2+a.length1+d))&&a.diffs.push([0,d]);a.start1-=c.length;a.start2-=c.length;a.length1+=
34
+ c.length+d.length;a.length2+=c.length+d.length}};
35
+ diff_match_patch.prototype.patch_make=function(a,b,c){var d;if("string"==typeof a&&"string"==typeof b&&"undefined"==typeof c)d=a,b=this.diff_main(d,b,!0),2<b.length&&(this.diff_cleanupSemantic(b),this.diff_cleanupEfficiency(b));else if(a&&"object"==typeof a&&"undefined"==typeof b&&"undefined"==typeof c)b=a,d=this.diff_text1(b);else if("string"==typeof a&&b&&"object"==typeof b&&"undefined"==typeof c)d=a;else if("string"==typeof a&&"string"==typeof b&&c&&"object"==typeof c)d=a,b=c;else throw Error("Unknown call format to patch_make.");
36
+ if(0===b.length)return[];c=[];a=new diff_match_patch.patch_obj;for(var e=0,f=0,g=0,h=d,j=0;j<b.length;j++){var i=b[j][0],k=b[j][1];!e&&0!==i&&(a.start1=f,a.start2=g);switch(i){case 1:a.diffs[e++]=b[j];a.length2+=k.length;d=d.substring(0,g)+k+d.substring(g);break;case -1:a.length1+=k.length;a.diffs[e++]=b[j];d=d.substring(0,g)+d.substring(g+k.length);break;case 0:k.length<=2*this.Patch_Margin&&e&&b.length!=j+1?(a.diffs[e++]=b[j],a.length1+=k.length,a.length2+=k.length):k.length>=2*this.Patch_Margin&&
37
+ e&&(this.patch_addContext_(a,h),c.push(a),a=new diff_match_patch.patch_obj,e=0,h=d,f=g)}1!==i&&(f+=k.length);-1!==i&&(g+=k.length)}e&&(this.patch_addContext_(a,h),c.push(a));return c};diff_match_patch.prototype.patch_deepCopy=function(a){for(var b=[],c=0;c<a.length;c++){var d=a[c],e=new diff_match_patch.patch_obj;e.diffs=[];for(var f=0;f<d.diffs.length;f++)e.diffs[f]=d.diffs[f].slice();e.start1=d.start1;e.start2=d.start2;e.length1=d.length1;e.length2=d.length2;b[c]=e}return b};
38
+ diff_match_patch.prototype.patch_apply=function(a,b){if(0==a.length)return[b,[]];a=this.patch_deepCopy(a);var c=this.patch_addPadding(a);b=c+b+c;this.patch_splitMax(a);for(var d=0,e=[],f=0;f<a.length;f++){var g=a[f].start2+d,h=this.diff_text1(a[f].diffs),j,i=-1;if(h.length>this.Match_MaxBits){if(j=this.match_main(b,h.substring(0,this.Match_MaxBits),g),-1!=j&&(i=this.match_main(b,h.substring(h.length-this.Match_MaxBits),g+h.length-this.Match_MaxBits),-1==i||j>=i))j=-1}else j=this.match_main(b,h,g);
39
+ if(-1==j)e[f]=!1,d-=a[f].length2-a[f].length1;else if(e[f]=!0,d=j-g,g=-1==i?b.substring(j,j+h.length):b.substring(j,i+this.Match_MaxBits),h==g)b=b.substring(0,j)+this.diff_text2(a[f].diffs)+b.substring(j+h.length);else if(g=this.diff_main(h,g,!1),h.length>this.Match_MaxBits&&this.diff_levenshtein(g)/h.length>this.Patch_DeleteThreshold)e[f]=!1;else{this.diff_cleanupSemanticLossless(g);for(var h=0,k,i=0;i<a[f].diffs.length;i++){var q=a[f].diffs[i];0!==q[0]&&(k=this.diff_xIndex(g,h));1===q[0]?b=b.substring(0,
40
+ j+k)+q[1]+b.substring(j+k):-1===q[0]&&(b=b.substring(0,j+k)+b.substring(j+this.diff_xIndex(g,h+q[1].length)));-1!==q[0]&&(h+=q[1].length)}}}b=b.substring(c.length,b.length-c.length);return[b,e]};
41
+ diff_match_patch.prototype.patch_addPadding=function(a){for(var b=this.Patch_Margin,c="",d=1;d<=b;d++)c+=String.fromCharCode(d);for(d=0;d<a.length;d++)a[d].start1+=b,a[d].start2+=b;var d=a[0],e=d.diffs;if(0==e.length||0!=e[0][0])e.unshift([0,c]),d.start1-=b,d.start2-=b,d.length1+=b,d.length2+=b;else if(b>e[0][1].length){var f=b-e[0][1].length;e[0][1]=c.substring(e[0][1].length)+e[0][1];d.start1-=f;d.start2-=f;d.length1+=f;d.length2+=f}d=a[a.length-1];e=d.diffs;0==e.length||0!=e[e.length-1][0]?(e.push([0,
42
+ c]),d.length1+=b,d.length2+=b):b>e[e.length-1][1].length&&(f=b-e[e.length-1][1].length,e[e.length-1][1]+=c.substring(0,f),d.length1+=f,d.length2+=f);return c};
43
+ diff_match_patch.prototype.patch_splitMax=function(a){for(var b=this.Match_MaxBits,c=0;c<a.length;c++)if(!(a[c].length1<=b)){var d=a[c];a.splice(c--,1);for(var e=d.start1,f=d.start2,g="";0!==d.diffs.length;){var h=new diff_match_patch.patch_obj,j=!0;h.start1=e-g.length;h.start2=f-g.length;""!==g&&(h.length1=h.length2=g.length,h.diffs.push([0,g]));for(;0!==d.diffs.length&&h.length1<b-this.Patch_Margin;){var g=d.diffs[0][0],i=d.diffs[0][1];1===g?(h.length2+=i.length,f+=i.length,h.diffs.push(d.diffs.shift()),
44
+ j=!1):-1===g&&1==h.diffs.length&&0==h.diffs[0][0]&&i.length>2*b?(h.length1+=i.length,e+=i.length,j=!1,h.diffs.push([g,i]),d.diffs.shift()):(i=i.substring(0,b-h.length1-this.Patch_Margin),h.length1+=i.length,e+=i.length,0===g?(h.length2+=i.length,f+=i.length):j=!1,h.diffs.push([g,i]),i==d.diffs[0][1]?d.diffs.shift():d.diffs[0][1]=d.diffs[0][1].substring(i.length))}g=this.diff_text2(h.diffs);g=g.substring(g.length-this.Patch_Margin);i=this.diff_text1(d.diffs).substring(0,this.Patch_Margin);""!==i&&
45
+ (h.length1+=i.length,h.length2+=i.length,0!==h.diffs.length&&0===h.diffs[h.diffs.length-1][0]?h.diffs[h.diffs.length-1][1]+=i:h.diffs.push([0,i]));j||a.splice(++c,0,h)}}};diff_match_patch.prototype.patch_toText=function(a){for(var b=[],c=0;c<a.length;c++)b[c]=a[c];return b.join("")};
46
+ diff_match_patch.prototype.patch_fromText=function(a){var b=[];if(!a)return b;a=a.split("\n");for(var c=0,d=/^@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@$/;c<a.length;){var e=a[c].match(d);if(!e)throw Error("Invalid patch string: "+a[c]);var f=new diff_match_patch.patch_obj;b.push(f);f.start1=parseInt(e[1],10);""===e[2]?(f.start1--,f.length1=1):"0"==e[2]?f.length1=0:(f.start1--,f.length1=parseInt(e[2],10));f.start2=parseInt(e[3],10);""===e[4]?(f.start2--,f.length2=1):"0"==e[4]?f.length2=0:(f.start2--,f.length2=
47
+ parseInt(e[4],10));for(c++;c<a.length;){e=a[c].charAt(0);try{var g=decodeURI(a[c].substring(1))}catch(h){throw Error("Illegal escape in patch_fromText: "+g);}if("-"==e)f.diffs.push([-1,g]);else if("+"==e)f.diffs.push([1,g]);else if(" "==e)f.diffs.push([0,g]);else if("@"==e)break;else if(""!==e)throw Error('Invalid patch mode "'+e+'" in: '+g);c++}}return b};diff_match_patch.patch_obj=function(){this.diffs=[];this.start2=this.start1=null;this.length2=this.length1=0};
48
+ diff_match_patch.patch_obj.prototype.toString=function(){var a,b;a=0===this.length1?this.start1+",0":1==this.length1?this.start1+1:this.start1+1+","+this.length1;b=0===this.length2?this.start2+",0":1==this.length2?this.start2+1:this.start2+1+","+this.length2;a=["@@ -"+a+" +"+b+" @@\n"];var c;for(b=0;b<this.diffs.length;b++){switch(this.diffs[b][0]){case 1:c="+";break;case -1:c="-";break;case 0:c=" "}a[b+1]=c+encodeURI(this.diffs[b][1])+"\n"}return a.join("").replace(/%20/g," ")};
49
+ this.diff_match_patch=diff_match_patch;this.DIFF_DELETE=-1;this.DIFF_INSERT=1;this.DIFF_EQUAL=0;})()
@@ -0,0 +1,71 @@
1
+ // Generated by CoffeeScript 1.6.3
2
+ /*
3
+ @preserve jQuery.PrettyTextDiff 1.0.3
4
+ See https://github.com/arnab/jQuery.PrettyTextDiff/
5
+ */
6
+
7
+
8
+ (function() {
9
+ var $;
10
+
11
+ $ = jQuery;
12
+
13
+ $.fn.extend({
14
+ prettyTextDiff: function(options) {
15
+ var dmp, settings;
16
+ settings = {
17
+ originalContainer: ".original",
18
+ changedContainer: ".changed",
19
+ diffContainer: ".diff",
20
+ cleanup: true,
21
+ debug: false
22
+ };
23
+ settings = $.extend(settings, options);
24
+ $.fn.prettyTextDiff.debug("Options: ", settings, settings);
25
+ dmp = new diff_match_patch();
26
+ return this.each(function() {
27
+ var changed, diff_as_html, diffs, original;
28
+ original = $(settings.originalContainer, this).text();
29
+ $.fn.prettyTextDiff.debug("Original text found: ", original, settings);
30
+ changed = $(settings.changedContainer, this).text();
31
+ $.fn.prettyTextDiff.debug("Changed text found: ", changed, settings);
32
+ diffs = dmp.diff_main(original, changed);
33
+ if (settings.cleanup) {
34
+ dmp.diff_cleanupSemantic(diffs);
35
+ }
36
+ $.fn.prettyTextDiff.debug("Diffs: ", diffs, settings);
37
+ diff_as_html = $.map(diffs, function(diff) {
38
+ return $.fn.prettyTextDiff.createHTML(diff);
39
+ });
40
+ $(settings.diffContainer, this).html(diff_as_html.join(''));
41
+ return this;
42
+ });
43
+ }
44
+ });
45
+
46
+ $.fn.prettyTextDiff.debug = function(message, object, settings) {
47
+ if (settings.debug) {
48
+ return console.log(message, object);
49
+ }
50
+ };
51
+
52
+ $.fn.prettyTextDiff.createHTML = function(diff) {
53
+ var data, html, operation, pattern_amp, pattern_gt, pattern_lt, pattern_para, text;
54
+ html = [];
55
+ pattern_amp = /&/g;
56
+ pattern_lt = /</g;
57
+ pattern_gt = />/g;
58
+ pattern_para = /\n/g;
59
+ operation = diff[0], data = diff[1];
60
+ text = data.replace(pattern_amp, '&amp;').replace(pattern_lt, '&lt;').replace(pattern_gt, '&gt;').replace(pattern_para, '<br>');
61
+ switch (operation) {
62
+ case DIFF_INSERT:
63
+ return '<ins>' + text + '</ins>';
64
+ case DIFF_DELETE:
65
+ return '<del>' + text + '</del>';
66
+ case DIFF_EQUAL:
67
+ return '<span>' + text + '</span>';
68
+ }
69
+ };
70
+
71
+ }).call(this);
@@ -0,0 +1,95 @@
1
+ (function($) {
2
+ $.widget("ra.history", {
3
+
4
+ _create: function() {
5
+ var widget = this;
6
+ var dom_widget = widget.element;
7
+
8
+ var changesetLink = dom_widget.find('a.changeset');
9
+ changesetLink.unbind().bind("click", function(e){
10
+ widget._bindModalOpening(e, $(this).data('url'));
11
+ return false;
12
+ });
13
+ },
14
+
15
+ _bindModalOpening: function(e, url) {
16
+ e.preventDefault();
17
+ widget = this;
18
+ if($("#modal").length)
19
+ return false;
20
+
21
+ var dialog = this._getModal();
22
+
23
+ setTimeout(function(){ // fix race condition with modal insertion in the dom (Chrome => Team/add a new fan => #modal not found when it should have). Somehow .on('show') is too early, tried it too.
24
+ $.ajax({
25
+ url: url,
26
+ beforeSend: function(xhr) {
27
+ xhr.setRequestHeader("Accept", "text/javascript");
28
+ },
29
+ success: function(data, status, xhr) {
30
+ dialog.find('.modal-body').html(data);
31
+ widget._bindFormEvents();
32
+ },
33
+ error: function(xhr, status, error) {
34
+ dialog.find('.modal-body').html(xhr.responseText);
35
+ },
36
+ dataType: 'text'
37
+ });
38
+ },100);
39
+
40
+ },
41
+
42
+ _bindFormEvents: function() {
43
+ var widget = this,
44
+ dialog = this._getModal(),
45
+ table = dialog.find("table")
46
+ saveButton = dialog.find('.save-action');
47
+
48
+ dialog.find('.modal-header-title').html(table.data('title'));
49
+ dialog.find('.cancel-action').unbind().click(function(){
50
+ dialog.modal('hide');
51
+ return false;
52
+ }).html('Cancel');
53
+
54
+ dialog.find('#version tr').prettyTextDiff();
55
+ saveButton.attr('href', table.data('rollbackurl')).html('Rollback');
56
+ },
57
+
58
+ _getModal: function() {
59
+ var widget = this;
60
+ if (!widget.dialog) {
61
+ widget.dialog = $('<div id="modal" class="modal fade">\
62
+ <div class="modal-dialog modal-lg">\
63
+ <div class="modal-content">\
64
+ <div class="modal-header">\
65
+ <a href="#" class="close" data-dismiss="modal">&times;</a>\
66
+ <h3 class="modal-header-title">...</h3>\
67
+ </div>\
68
+ <div class="modal-body">\
69
+ ...\
70
+ </div>\
71
+ <div class="modal-footer">\
72
+ <a href="#" class="btn cancel-action">...</a>\
73
+ <a href="#" class="btn btn-primary save-action" data-method="put" data-confirm="Are you sure?">...</a>\
74
+ </div>\
75
+ </div>\
76
+ </div>\
77
+ </div>')
78
+ .modal({
79
+ keyboard: true,
80
+ backdrop: true,
81
+ show: true
82
+ })
83
+ .on('hidden.bs.modal', function(){
84
+ widget.dialog.remove(); // We don't want to reuse closed modals
85
+ widget.dialog = null;
86
+ });
87
+ }
88
+ return this.dialog;
89
+ }
90
+ });
91
+ })(jQuery);
92
+
93
+ $(document).on('rails_admin.dom_ready', function() {
94
+ $('#history').history();
95
+ });
@@ -0,0 +1,12 @@
1
+ td.diff {
2
+ white-space: normal !important;
3
+ }
4
+
5
+ ins {
6
+ background-color: #c6ffc6;
7
+ text-decoration: none;
8
+ }
9
+
10
+ del {
11
+ background-color: #ffc6c6;
12
+ }
@@ -0,0 +1,23 @@
1
+ %table#history.table.table-condensed.table-striped
2
+ %thead
3
+ %tr
4
+ %th.shrink.user= t("admin.table_headers.username")
5
+ %th.shrink.items= t("admin.table_headers.item")
6
+ %th.changes= t("admin.table_headers.changes")
7
+ %th.rollback= t("admin.table_headers.rollback")
8
+ %tbody
9
+ - @history.each do |t|
10
+ - abstract_model = RailsAdmin.config(t.table).abstract_model
11
+ %tr
12
+ %td= t.try :username
13
+ - if o = abstract_model.try(:get, t.item)
14
+ - label = o.send(abstract_model.config.object_label_method)
15
+ - if show_action = action(:show, abstract_model, o)
16
+ %td= link_to(label, url_for(action: show_action.action_name, model_name: abstract_model.to_param, id: o.id), class: 'pjax')
17
+ - else
18
+ %td= label
19
+ - else
20
+ - label = Object.const_defined?(t.table) ? t.table.constantize.model_name.human : t.table
21
+ %td= "#{label} ##{t.item}"
22
+ %td= t.message
23
+ %td= link_to("View changes", "#", class: "changeset", :data => {:url => url_for(action: action(:history_index, abstract_model).action_name, model_name: abstract_model.to_param, version_id: t.version_id)})
@@ -0,0 +1,12 @@
1
+ %table#version.table.table-striped{:data => { :title => "#{@abstract_model} version ##{@version.index + 1} <small>[#{@version.event}]</small>", :rollbackurl => url_for(action: action(:history_index, @abstract_model).action_name, model_name: @abstract_model.to_param, version_id: @version.id)}}
2
+ %thead
3
+ %tr
4
+ %th Field
5
+ %th{:colspan => 3} Changes
6
+ %tbody
7
+ - @version.changeset.sort.each do |changes|
8
+ %tr
9
+ %td= changes[0]
10
+ %td.original.hide= changes[1][0]
11
+ %td.changed.hide= changes[1][1]
12
+ %td.diff
@@ -0,0 +1,58 @@
1
+ = stylesheet_link_tag 'rails_admin/ra.history'
2
+ = javascript_include_tag 'rails_admin/diff_match_patch'
3
+ = javascript_include_tag 'rails_admin/jquery.pretty-text-diff'
4
+ = javascript_include_tag 'rails_admin/ra.history'
5
+
6
+ - params = request.params.except(:action, :controller, :model_name)
7
+ - query = params[:query]
8
+ - filter = params[:filter]
9
+ - sort = params[:sort]
10
+ - sort_reverse = params[:sort_reverse]
11
+ - path_method = params[:id] ? "history_show_path" : "history_index_path"
12
+
13
+ = form_tag("", method: "get", class: "search pjax-form form-inline") do
14
+ .well
15
+ .input-group
16
+ %input.form-control.input-small{name: "query", type: "search", value: query, placeholder: "#{t("admin.misc.filter")}", class: 'input-small'}
17
+ %span.input-group-btn
18
+ %button.btn.btn-primary{type: "submit", :'data-disable-with' => "<i class='icon-white icon-refresh'></i> ".html_safe + t("admin.misc.refresh")}
19
+ %i.icon-white.icon-refresh
20
+ = t("admin.misc.refresh")
21
+ %table#history.table.table-striped.table-condensed
22
+ %thead
23
+ %tr
24
+ - columns = []
25
+ - columns << { property_name: "created_at", css_class: "created_at",link_text: t('admin.table_headers.created_at') }
26
+ - columns << { property_name: "username", css_class: "username", link_text: t('admin.table_headers.username') }
27
+ - columns << { property_name: "item", css_class: "item", link_text: t('admin.table_headers.item') } if @general
28
+ - columns << { property_name: "message", css_class: "message", link_text: t('admin.table_headers.message') }
29
+ - columns << { property_name: "rollback", css_class: "rollback", link_text: t('admin.table_headers.rollback') }
30
+
31
+ - columns.each do |column|
32
+ - property_name = column[:property_name]
33
+ - selected = (sort == property_name)
34
+ - sort_direction = (sort_reverse ? "headerSortUp" : "headerSortDown" if selected)
35
+ - sort_location = send(path_method, params.except("sort_reverse").merge(model_name: @abstract_model.to_param, sort: property_name).merge(selected && sort_reverse != "true" ? {sort_reverse: "true"} : {}))
36
+ %th{class: "header pjax #{column[:css_class]} #{sort_direction if selected}", :'data-href' => sort_location}= column[:link_text]
37
+ %tbody
38
+ - @history.each_with_index do |object, index|
39
+ %tr
40
+ - unless object.created_at.nil?
41
+ %td= l(object.created_at, format: :long, default: l(object.created_at, format: :long, locale: :en))
42
+ %td= object.username
43
+ - if @general
44
+ - if o = @abstract_model.get(object.item)
45
+ - label = o.send(@abstract_model.config.object_label_method)
46
+ - if show_action = action(:show, @abstract_model, o)
47
+ %td= link_to(label, url_for(action: show_action.action_name, model_name: @abstract_model.to_param, id: o.id), class: 'pjax')
48
+ - else
49
+ %td= label
50
+ - else
51
+ %td= "#{@abstract_model.config.label} ##{object.item}"
52
+ %td= object.message.in?(['delete', 'new']) ? t("admin.actions.#{object.message}.done").capitalize : object.message
53
+ %td= link_to("View changes", "#", class: "changeset", :data => {:url => url_for(action: action(:history_index, @abstract_model).action_name, model_name: @abstract_model.to_param, version_id: object.version_id)})
54
+
55
+ - unless params[:all] || !@history.respond_to?(:current_page)
56
+ = paginate(@history, theme: 'twitter-bootstrap', remote: true)
57
+ = link_to(t("admin.misc.show_all"), send(path_method, params.merge(all: true)), class: "show-all btn pjax") unless (tc = @history.total_count) <= @history.size || tc > 100
58
+
@@ -0,0 +1,4 @@
1
+ en:
2
+ admin:
3
+ table_headers:
4
+ rollback: "Rollback"
@@ -0,0 +1,11 @@
1
+ require "rails_admin_history_rollback/engine"
2
+
3
+ module RailsAdminHistoryRollback
4
+ end
5
+
6
+ require 'rails_admin/config/actions'
7
+ require 'rails_admin/extension'
8
+ require 'rails_admin/extensions/paper_trail'
9
+
10
+ require "rails_admin_history_rollback/extensions/paper_trail/auditing_adapter"
11
+ require "rails_admin_history_rollback/config/actions/history_index"
@@ -0,0 +1,76 @@
1
+ module RailsAdmin
2
+ module Config
3
+ module Actions
4
+ class HistoryIndex < Base
5
+ RailsAdmin::Config::Actions.register(self)
6
+
7
+ register_instance_option :authorization_key do
8
+ :history
9
+ end
10
+
11
+ register_instance_option :collection do
12
+ true
13
+ end
14
+
15
+ register_instance_option :http_methods do
16
+ [:get, :put] # NEW / ROLLBACK
17
+ end
18
+
19
+ register_instance_option :route_fragment do
20
+ 'history'
21
+ end
22
+
23
+ register_instance_option :controller do
24
+ proc do
25
+ @general = true
26
+ @history = @auditing_adapter && @auditing_adapter.listing_for_model(@abstract_model, params[:query], params[:sort], params[:sort_reverse], params[:all], params[:page]) || []
27
+ @version = PaperTrail::Version.find(params[:version_id]) if params[:version_id] rescue false
28
+
29
+ if request.get? # SHOW
30
+
31
+ if @version
32
+ render partial: 'version', layout: false
33
+ else
34
+ render @action.template_name
35
+ end
36
+
37
+ elsif request.put? # ROLLBACK
38
+ begin
39
+ if @version.event == "create"
40
+ @record = @version.item_type.constantize.find(@version.item_id)
41
+ @result = @record.destroy
42
+ else
43
+ @record = @version.reify
44
+ @result = @record.save
45
+ end
46
+
47
+ if @result
48
+ if @version.event == "create"
49
+ flash[:success] = "Rolled back newly-created record by destroying it."
50
+ else
51
+ flash[:success] = "Rolled back changes to this record."
52
+ end
53
+ else
54
+ flash[:error] = "Couldn't rollback. Sorry."
55
+ end
56
+ rescue ActiveRecord::RecordNotFound
57
+ flash[:error] = "Version does not exist."
58
+ redirect_to :action => :history_index
59
+ end
60
+
61
+ redirect_to :action => :history_index
62
+ end
63
+ end
64
+ end
65
+
66
+ register_instance_option :template_name do
67
+ :history
68
+ end
69
+
70
+ register_instance_option :link_icon do
71
+ 'icon-book'
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,12 @@
1
+ module RailsAdminHistoryRollback
2
+ class Engine < ::Rails::Engine
3
+ initializer "RailsAdminHistoryRollback precompile hook" do |app|
4
+ app.config.assets.precompile += [
5
+ 'rails_admin/diff_match_patch.js',
6
+ 'rails_admin/jquery.pretty-text-diff.js',
7
+ 'rails_admin/ra.history.js',
8
+ 'rails_admin/ra.history.css'
9
+ ]
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,17 @@
1
+ module RailsAdmin
2
+ module Extensions
3
+ module PaperTrail
4
+ class VersionProxy
5
+ def message
6
+ @message = @version.event
7
+ end
8
+ def version_id
9
+ @version.id
10
+ end
11
+ end
12
+ class AuditingAdapter
13
+ COLUMN_MAPPING[:rollback] = :id
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,3 @@
1
+ module RailsAdminHistoryRollback
2
+ VERSION = "0.0.2"
3
+ end
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rails_admin_history_rollback
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Rikki Pitt
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 4.2.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 4.2.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: rails_admin
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.6.6
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 0.6.6
41
+ - !ruby/object:Gem::Dependency
42
+ name: paper_trail
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 3.0.6
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 3.0.6
55
+ description: Enables users to rollback to any history version recorded by paper_trail.
56
+ Versions are graphically diff'ed to help with rolling back.
57
+ email:
58
+ - rikkipitt@gmail.com
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - MIT-LICENSE
64
+ - Rakefile
65
+ - app/assets/javascripts/rails_admin/diff_match_patch.js
66
+ - app/assets/javascripts/rails_admin/jquery.pretty-text-diff.js
67
+ - app/assets/javascripts/rails_admin/ra.history.js
68
+ - app/assets/stylesheets/rails_admin/ra.history.css
69
+ - app/views/rails_admin/main/_dashboard_history.html.haml
70
+ - app/views/rails_admin/main/_version.html.haml
71
+ - app/views/rails_admin/main/history.html.haml
72
+ - config/locales/history_rollback.en.yml
73
+ - lib/rails_admin_history_rollback.rb
74
+ - lib/rails_admin_history_rollback/config/actions/history_index.rb
75
+ - lib/rails_admin_history_rollback/engine.rb
76
+ - lib/rails_admin_history_rollback/extensions/paper_trail/auditing_adapter.rb
77
+ - lib/rails_admin_history_rollback/version.rb
78
+ homepage: https://github.com/rikkipitt/rails_admin_history_rollback
79
+ licenses:
80
+ - MIT
81
+ metadata: {}
82
+ post_install_message:
83
+ rdoc_options: []
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ requirements: []
97
+ rubyforge_project:
98
+ rubygems_version: 2.4.5
99
+ signing_key:
100
+ specification_version: 4
101
+ summary: History rollback with paper_trail for rails_admin
102
+ test_files: []