diff --git a/assets/scripts/datatables.min.js b/assets/scripts/datatables.min.js index 0bd8099..83f2aef 100644 --- a/assets/scripts/datatables.min.js +++ b/assets/scripts/datatables.min.js @@ -4,10 +4,10 @@ * * To rebuild or modify this file with the latest versions of the included * software please visit: - * https://datatables.net/download/#dt/jszip-2.5.0/pdfmake-0.1.36/dt-1.10.18/b-1.5.4/b-html5-1.5.4/fc-3.2.5/fh-3.1.4/r-2.2.2/sc-1.5.0/sl-1.2.6 + * https://datatables.net/download/#dt/jszip-2.5.0/pdfmake-0.1.36/dt-1.10.18/b-1.5.4/b-colvis-1.5.4/b-html5-1.5.4/fc-3.2.5/fh-3.1.4/r-2.2.2/sc-1.5.0/sl-1.2.6 * * Included libraries: - * JSZip 2.5.0, pdfmake 0.1.36, DataTables 1.10.18, Buttons 1.5.4, HTML5 export 1.5.4, FixedColumns 3.2.5, FixedHeader 3.1.4, Responsive 2.2.2, Scroller 1.5.0, Select 1.2.6 + * JSZip 2.5.0, pdfmake 0.1.36, DataTables 1.10.18, Buttons 1.5.4, Column visibility 1.5.4, HTML5 export 1.5.4, FixedColumns 3.2.5, FixedHeader 3.1.4, Responsive 2.2.2, Scroller 1.5.0, Select 1.2.6 */ /*! @@ -187,7 +187,7 @@ Z(n.defaults.column);n.models.oSettings={oFeatures:{bAutoWidth:null,bDeferRender aoFooter:[],oPreviousSearch:{},aoPreSearchCols:[],aaSorting:null,aaSortingFixed:[],asStripeClasses:null,asDestroyStripes:[],sDestroyWidth:0,aoRowCallback:[],aoHeaderCallback:[],aoFooterCallback:[],aoDrawCallback:[],aoRowCreatedCallback:[],aoPreDrawCallback:[],aoInitComplete:[],aoStateSaveParams:[],aoStateLoadParams:[],aoStateLoaded:[],sTableId:"",nTable:null,nTHead:null,nTFoot:null,nTBody:null,nTableWrapper:null,bDeferLoading:!1,bInitialised:!1,aoOpenRows:[],sDom:null,searchDelay:null,sPaginationType:"two_button", iStateDuration:0,aoStateSave:[],aoStateLoad:[],oSavedState:null,oLoadedState:null,sAjaxSource:null,sAjaxDataProp:null,bAjaxDataGet:!0,jqXHR:null,json:k,oAjaxData:k,fnServerData:null,aoServerParams:[],sServerMethod:null,fnFormatNumber:null,aLengthMenu:null,iDraw:0,bDrawing:!1,iDrawError:-1,_iDisplayLength:10,_iDisplayStart:0,_iRecordsTotal:0,_iRecordsDisplay:0,oClasses:{},bFiltered:!1,bSorted:!1,bSortCellsTop:null,oInit:null,aoDestroyCallback:[],fnRecordsTotal:function(){return"ssp"==y(this)?1*this._iRecordsTotal: this.aiDisplayMaster.length},fnRecordsDisplay:function(){return"ssp"==y(this)?1*this._iRecordsDisplay:this.aiDisplay.length},fnDisplayEnd:function(){var a=this._iDisplayLength,b=this._iDisplayStart,c=b+a,d=this.aiDisplay.length,e=this.oFeatures,f=e.bPaginate;return e.bServerSide?!1===f||-1===a?b+d:Math.min(b+a,this._iRecordsDisplay):!f||c>d||-1===a?d:c},oInstance:null,sInstance:null,iTabIndex:0,nScrollHead:null,nScrollFoot:null,aLastSort:[],oPlugins:{},rowIdFn:null,rowId:null};n.ext=x={buttons:{}, -classes:{},build:"dt/jszip-2.5.0/pdfmake-0.1.36/dt-1.10.18/b-1.5.4/b-html5-1.5.4/fc-3.2.5/fh-3.1.4/r-2.2.2/sc-1.5.0/sl-1.2.6",errMode:"alert",feature:[],search:[],selector:{cell:[],column:[],row:[]},internal:{},legacy:{ajax:null},pager:{},renderer:{pageButton:{},header:{}},order:{},type:{detect:[],search:{},order:{}},_unique:0,fnVersionCheck:n.fnVersionCheck,iApiIndex:0,oJUIClasses:{},sVersion:n.version};h.extend(x,{afnFiltering:x.search,aTypes:x.type.detect,ofnSearch:x.type.search,oSort:x.type.order,afnSortData:x.order,aoFeatures:x.feature,oApi:x.internal,oStdClasses:x.classes,oPagination:x.pager}); +classes:{},build:"dt/jszip-2.5.0/pdfmake-0.1.36/dt-1.10.18/b-1.5.4/b-colvis-1.5.4/b-html5-1.5.4/fc-3.2.5/fh-3.1.4/r-2.2.2/sc-1.5.0/sl-1.2.6",errMode:"alert",feature:[],search:[],selector:{cell:[],column:[],row:[]},internal:{},legacy:{ajax:null},pager:{},renderer:{pageButton:{},header:{}},order:{},type:{detect:[],search:{},order:{}},_unique:0,fnVersionCheck:n.fnVersionCheck,iApiIndex:0,oJUIClasses:{},sVersion:n.version};h.extend(x,{afnFiltering:x.search,aTypes:x.type.detect,ofnSearch:x.type.search,oSort:x.type.order,afnSortData:x.order,aoFeatures:x.feature,oApi:x.internal,oStdClasses:x.classes,oPagination:x.pager}); h.extend(n.ext.classes,{sTable:"dataTable",sNoFooter:"no-footer",sPageButton:"paginate_button",sPageButtonActive:"current",sPageButtonDisabled:"disabled",sStripeOdd:"odd",sStripeEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"sorting_asc",sSortDesc:"sorting_desc",sSortable:"sorting",sSortableAsc:"sorting_asc_disabled", sSortableDesc:"sorting_desc_disabled",sSortableNone:"sorting_disabled",sSortColumn:"sorting_",sFilterInput:"",sLengthSelect:"",sScrollWrapper:"dataTables_scroll",sScrollHead:"dataTables_scrollHead",sScrollHeadInner:"dataTables_scrollHeadInner",sScrollBody:"dataTables_scrollBody",sScrollFoot:"dataTables_scrollFoot",sScrollFootInner:"dataTables_scrollFootInner",sHeaderTH:"",sFooterTH:"",sSortJUIAsc:"",sSortJUIDesc:"",sSortJUI:"",sSortJUIAscAllowed:"",sSortJUIDescAllowed:"",sSortJUIWrapper:"",sSortIcon:"", sJUIHeader:"",sJUIFooter:""});var Kb=n.ext.pager;h.extend(Kb,{simple:function(){return["previous","next"]},full:function(){return["first","previous","next","last"]},numbers:function(a,b){return[ia(a,b)]},simple_numbers:function(a,b){return["previous",ia(a,b),"next"]},full_numbers:function(a,b){return["first","previous",ia(a,b),"next","last"]},first_last_numbers:function(a,b){return["first",ia(a,b),"last"]},_numbers:ia,numbers_length:7});h.extend(!0,n.ext.renderer,{pageButton:{_:function(a,b,c,d,e, @@ -251,6 +251,18 @@ a.rows(c.rows,d.extend({selected:!0},h)).any()&&d.extend(h,{selected:!0});h=a.ro a.namespace&&(a=b.oInit.buttons||g.defaults.buttons)&&!b._buttons&&(new r(b,a)).container()});g.ext.feature.push({fnInit:function(a){a=new g.Api(a);var b=a.init().buttons||g.defaults.buttons;return(new r(a,b)).container()},cFeature:"B"});return r}); +/*! + Column visibility buttons for Buttons and DataTables. + 2016 SpryMedia Ltd - datatables.net/license +*/ +(function(f){"function"===typeof define&&define.amd?define(["jquery","datatables.net","datatables.net-buttons"],function(c){return f(c,window,document)}):"object"===typeof exports?module.exports=function(c,e){c||(c=window);e&&e.fn.dataTable||(e=require("datatables.net")(c,e).$);e.fn.dataTable.Buttons||require("datatables.net-buttons")(c,e);return f(e,c,c.document)}:f(jQuery,window,document)})(function(f,c,e,h){c=f.fn.dataTable;f.extend(c.ext.buttons,{colvis:function(b,a){return{extend:"collection", +text:function(a){return a.i18n("buttons.colvis","Column visibility")},className:"buttons-colvis",buttons:[{extend:"columnsToggle",columns:a.columns,columnText:a.columnText}]}},columnsToggle:function(b,a){return b.columns(a.columns).indexes().map(function(b){return{extend:"columnToggle",columns:b,columnText:a.columnText}}).toArray()},columnToggle:function(b,a){return{extend:"columnVisibility",columns:a.columns,columnText:a.columnText}},columnsVisibility:function(b,a){return b.columns(a.columns).indexes().map(function(b){return{extend:"columnVisibility", +columns:b,visibility:a.visibility,columnText:a.columnText}}).toArray()},columnVisibility:{columns:h,text:function(b,a,d){return d._columnText(b,d)},className:"buttons-columnVisibility",action:function(b,a,d,g){b=a.columns(g.columns);a=b.visible();b.visible(g.visibility!==h?g.visibility:!(a.length&&a[0]))},init:function(b,a,d){var g=this;a.attr("data-cv-idx",d.columns);b.on("column-visibility.dt"+d.namespace,function(a,c){c.bDestroying||c.nTable!=b.settings()[0].nTable||g.active(b.column(d.columns).visible())}).on("column-reorder.dt"+ +d.namespace,function(c,g,e){1===b.columns(d.columns).count()&&(d.columns=f.inArray(d.columns,e.mapping),a.attr("data-cv-idx",d.columns),a.parent().children("[data-cv-idx]").sort(function(a,b){return 1*a.getAttribute("data-cv-idx")-1*b.getAttribute("data-cv-idx")}).appendTo(a.parent()))});this.active(b.column(d.columns).visible())},destroy:function(b,a,d){b.off("column-visibility.dt"+d.namespace).off("column-reorder.dt"+d.namespace)},_columnText:function(b,a){var d=b.column(a.columns).index(),c=b.settings()[0].aoColumns[d].sTitle.replace(/\n/g, +" ").replace(//gi," ").replace(//g,"").replace(//g,"").replace(/<.*?>/g,"").replace(/^\s+|\s+$/g,"");return a.columnText?a.columnText(b,d,c):c}},colvisRestore:{className:"buttons-colvisRestore",text:function(b){return b.i18n("buttons.colvisRestore","Restore visibility")},init:function(b,a,d){d._visOriginal=b.columns().indexes().map(function(a){return b.column(a).visible()}).toArray()},action:function(b,a,d,c){a.columns().every(function(b){b=a.colReorder&& +a.colReorder.transpose?a.colReorder.transpose(b,"toOriginal"):b;this.visible(c._visOriginal[b])})}},colvisGroup:{className:"buttons-colvisGroup",action:function(b,a,d,c){a.columns(c.show).visible(!0,!1);a.columns(c.hide).visible(!1,!1);a.columns.adjust()},show:[],hide:[]}});return c.Buttons}); + + /*! HTML5 export buttons for Buttons and DataTables. 2016 SpryMedia Ltd - datatables.net/license diff --git a/assets/styles/datatables.min.css b/assets/styles/datatables.min.css index 85efb0c..0af7e47 100644 --- a/assets/styles/datatables.min.css +++ b/assets/styles/datatables.min.css @@ -4,10 +4,10 @@ * * To rebuild or modify this file with the latest versions of the included * software please visit: - * https://datatables.net/download/#dt/jszip-2.5.0/pdfmake-0.1.36/dt-1.10.18/b-1.5.4/b-html5-1.5.4/fc-3.2.5/fh-3.1.4/r-2.2.2/sc-1.5.0/sl-1.2.6 + * https://datatables.net/download/#dt/jszip-2.5.0/pdfmake-0.1.36/dt-1.10.18/b-1.5.4/b-colvis-1.5.4/b-html5-1.5.4/fc-3.2.5/fh-3.1.4/r-2.2.2/sc-1.5.0/sl-1.2.6 * * Included libraries: - * JSZip 2.5.0, pdfmake 0.1.36, DataTables 1.10.18, Buttons 1.5.4, HTML5 export 1.5.4, FixedColumns 3.2.5, FixedHeader 3.1.4, Responsive 2.2.2, Scroller 1.5.0, Select 1.2.6 + * JSZip 2.5.0, pdfmake 0.1.36, DataTables 1.10.18, Buttons 1.5.4, Column visibility 1.5.4, HTML5 export 1.5.4, FixedColumns 3.2.5, FixedHeader 3.1.4, Responsive 2.2.2, Scroller 1.5.0, Select 1.2.6 */ table.dataTable{width:100%;margin:0 auto;clear:both;border-collapse:separate;border-spacing:0}table.dataTable thead th,table.dataTable tfoot th{font-weight:bold}table.dataTable thead th,table.dataTable thead td{padding:10px 18px;border-bottom:1px solid #111}table.dataTable thead th:active,table.dataTable thead td:active{outline:none}table.dataTable tfoot th,table.dataTable tfoot td{padding:10px 18px 6px 18px;border-top:1px solid #111}table.dataTable thead .sorting,table.dataTable thead .sorting_asc,table.dataTable thead .sorting_desc,table.dataTable thead .sorting_asc_disabled,table.dataTable thead .sorting_desc_disabled{cursor:pointer;*cursor:hand;background-repeat:no-repeat;background-position:center right}table.dataTable thead .sorting{background-image:url("DataTables-1.10.18/images/sort_both.png")}table.dataTable thead .sorting_asc{background-image:url("DataTables-1.10.18/images/sort_asc.png")}table.dataTable thead .sorting_desc{background-image:url("DataTables-1.10.18/images/sort_desc.png")}table.dataTable thead .sorting_asc_disabled{background-image:url("DataTables-1.10.18/images/sort_asc_disabled.png")}table.dataTable thead .sorting_desc_disabled{background-image:url("DataTables-1.10.18/images/sort_desc_disabled.png")}table.dataTable tbody tr{background-color:#ffffff}table.dataTable tbody tr.selected{background-color:#B0BED9}table.dataTable tbody th,table.dataTable tbody td{padding:8px 10px}table.dataTable.row-border tbody th,table.dataTable.row-border tbody td,table.dataTable.display tbody th,table.dataTable.display tbody td{border-top:1px solid #ddd}table.dataTable.row-border tbody tr:first-child th,table.dataTable.row-border tbody tr:first-child td,table.dataTable.display tbody tr:first-child th,table.dataTable.display tbody tr:first-child td{border-top:none}table.dataTable.cell-border tbody th,table.dataTable.cell-border tbody td{border-top:1px solid #ddd;border-right:1px solid #ddd}table.dataTable.cell-border tbody tr th:first-child,table.dataTable.cell-border tbody tr td:first-child{border-left:1px solid #ddd}table.dataTable.cell-border tbody tr:first-child th,table.dataTable.cell-border tbody tr:first-child td{border-top:none}table.dataTable.stripe tbody tr.odd,table.dataTable.display tbody tr.odd{background-color:#f9f9f9}table.dataTable.stripe tbody tr.odd.selected,table.dataTable.display tbody tr.odd.selected{background-color:#acbad4}table.dataTable.hover tbody tr:hover,table.dataTable.display tbody tr:hover{background-color:#f6f6f6}table.dataTable.hover tbody tr:hover.selected,table.dataTable.display tbody tr:hover.selected{background-color:#aab7d1}table.dataTable.order-column tbody tr>.sorting_1,table.dataTable.order-column tbody tr>.sorting_2,table.dataTable.order-column tbody tr>.sorting_3,table.dataTable.display tbody tr>.sorting_1,table.dataTable.display tbody tr>.sorting_2,table.dataTable.display tbody tr>.sorting_3{background-color:#fafafa}table.dataTable.order-column tbody tr.selected>.sorting_1,table.dataTable.order-column tbody tr.selected>.sorting_2,table.dataTable.order-column tbody tr.selected>.sorting_3,table.dataTable.display tbody tr.selected>.sorting_1,table.dataTable.display tbody tr.selected>.sorting_2,table.dataTable.display tbody tr.selected>.sorting_3{background-color:#acbad5}table.dataTable.display tbody tr.odd>.sorting_1,table.dataTable.order-column.stripe tbody tr.odd>.sorting_1{background-color:#f1f1f1}table.dataTable.display tbody tr.odd>.sorting_2,table.dataTable.order-column.stripe tbody tr.odd>.sorting_2{background-color:#f3f3f3}table.dataTable.display tbody tr.odd>.sorting_3,table.dataTable.order-column.stripe tbody tr.odd>.sorting_3{background-color:whitesmoke}table.dataTable.display tbody tr.odd.selected>.sorting_1,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_1{background-color:#a6b4cd}table.dataTable.display tbody tr.odd.selected>.sorting_2,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_2{background-color:#a8b5cf}table.dataTable.display tbody tr.odd.selected>.sorting_3,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_3{background-color:#a9b7d1}table.dataTable.display tbody tr.even>.sorting_1,table.dataTable.order-column.stripe tbody tr.even>.sorting_1{background-color:#fafafa}table.dataTable.display tbody tr.even>.sorting_2,table.dataTable.order-column.stripe tbody tr.even>.sorting_2{background-color:#fcfcfc}table.dataTable.display tbody tr.even>.sorting_3,table.dataTable.order-column.stripe tbody tr.even>.sorting_3{background-color:#fefefe}table.dataTable.display tbody tr.even.selected>.sorting_1,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_1{background-color:#acbad5}table.dataTable.display tbody tr.even.selected>.sorting_2,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_2{background-color:#aebcd6}table.dataTable.display tbody tr.even.selected>.sorting_3,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_3{background-color:#afbdd8}table.dataTable.display tbody tr:hover>.sorting_1,table.dataTable.order-column.hover tbody tr:hover>.sorting_1{background-color:#eaeaea}table.dataTable.display tbody tr:hover>.sorting_2,table.dataTable.order-column.hover tbody tr:hover>.sorting_2{background-color:#ececec}table.dataTable.display tbody tr:hover>.sorting_3,table.dataTable.order-column.hover tbody tr:hover>.sorting_3{background-color:#efefef}table.dataTable.display tbody tr:hover.selected>.sorting_1,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_1{background-color:#a2aec7}table.dataTable.display tbody tr:hover.selected>.sorting_2,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_2{background-color:#a3b0c9}table.dataTable.display tbody tr:hover.selected>.sorting_3,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_3{background-color:#a5b2cb}table.dataTable.no-footer{border-bottom:1px solid #111}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}table.dataTable.compact thead th,table.dataTable.compact thead td{padding:4px 17px 4px 4px}table.dataTable.compact tfoot th,table.dataTable.compact tfoot td{padding:4px}table.dataTable.compact tbody th,table.dataTable.compact tbody td{padding:4px}table.dataTable th.dt-left,table.dataTable td.dt-left{text-align:left}table.dataTable th.dt-center,table.dataTable td.dt-center,table.dataTable td.dataTables_empty{text-align:center}table.dataTable th.dt-right,table.dataTable td.dt-right{text-align:right}table.dataTable th.dt-justify,table.dataTable td.dt-justify{text-align:justify}table.dataTable th.dt-nowrap,table.dataTable td.dt-nowrap{white-space:nowrap}table.dataTable thead th.dt-head-left,table.dataTable thead td.dt-head-left,table.dataTable tfoot th.dt-head-left,table.dataTable tfoot td.dt-head-left{text-align:left}table.dataTable thead th.dt-head-center,table.dataTable thead td.dt-head-center,table.dataTable tfoot th.dt-head-center,table.dataTable tfoot td.dt-head-center{text-align:center}table.dataTable thead th.dt-head-right,table.dataTable thead td.dt-head-right,table.dataTable tfoot th.dt-head-right,table.dataTable tfoot td.dt-head-right{text-align:right}table.dataTable thead th.dt-head-justify,table.dataTable thead td.dt-head-justify,table.dataTable tfoot th.dt-head-justify,table.dataTable tfoot td.dt-head-justify{text-align:justify}table.dataTable thead th.dt-head-nowrap,table.dataTable thead td.dt-head-nowrap,table.dataTable tfoot th.dt-head-nowrap,table.dataTable tfoot td.dt-head-nowrap{white-space:nowrap}table.dataTable tbody th.dt-body-left,table.dataTable tbody td.dt-body-left{text-align:left}table.dataTable tbody th.dt-body-center,table.dataTable tbody td.dt-body-center{text-align:center}table.dataTable tbody th.dt-body-right,table.dataTable tbody td.dt-body-right{text-align:right}table.dataTable tbody th.dt-body-justify,table.dataTable tbody td.dt-body-justify{text-align:justify}table.dataTable tbody th.dt-body-nowrap,table.dataTable tbody td.dt-body-nowrap{white-space:nowrap}table.dataTable,table.dataTable th,table.dataTable td{box-sizing:content-box}.dataTables_wrapper{position:relative;clear:both;*zoom:1;zoom:1}.dataTables_wrapper .dataTables_length{float:left}.dataTables_wrapper .dataTables_filter{float:right;text-align:right}.dataTables_wrapper .dataTables_filter input{margin-left:0.5em}.dataTables_wrapper .dataTables_info{clear:both;float:left;padding-top:0.755em}.dataTables_wrapper .dataTables_paginate{float:right;text-align:right;padding-top:0.25em}.dataTables_wrapper .dataTables_paginate .paginate_button{box-sizing:border-box;display:inline-block;min-width:1.5em;padding:0.5em 1em;margin-left:2px;text-align:center;text-decoration:none !important;cursor:pointer;*cursor:hand;color:#333 !important;border:1px solid transparent;border-radius:2px}.dataTables_wrapper .dataTables_paginate .paginate_button.current,.dataTables_wrapper .dataTables_paginate .paginate_button.current:hover{color:#333 !important;border:1px solid #979797;background-color:white;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #fff), color-stop(100%, #dcdcdc));background:-webkit-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-moz-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-ms-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-o-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:linear-gradient(to bottom, #fff 0%, #dcdcdc 100%)}.dataTables_wrapper .dataTables_paginate .paginate_button.disabled,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active{cursor:default;color:#666 !important;border:1px solid transparent;background:transparent;box-shadow:none}.dataTables_wrapper .dataTables_paginate .paginate_button:hover{color:white !important;border:1px solid #111;background-color:#585858;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111));background:-webkit-linear-gradient(top, #585858 0%, #111 100%);background:-moz-linear-gradient(top, #585858 0%, #111 100%);background:-ms-linear-gradient(top, #585858 0%, #111 100%);background:-o-linear-gradient(top, #585858 0%, #111 100%);background:linear-gradient(to bottom, #585858 0%, #111 100%)}.dataTables_wrapper .dataTables_paginate .paginate_button:active{outline:none;background-color:#2b2b2b;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c));background:-webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%);box-shadow:inset 0 0 3px #111}.dataTables_wrapper .dataTables_paginate .ellipsis{padding:0 1em}.dataTables_wrapper .dataTables_processing{position:absolute;top:50%;left:50%;width:100%;height:40px;margin-left:-50%;margin-top:-25px;padding-top:20px;text-align:center;font-size:1.2em;background-color:white;background:-webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255,255,255,0)), color-stop(25%, rgba(255,255,255,0.9)), color-stop(75%, rgba(255,255,255,0.9)), color-stop(100%, rgba(255,255,255,0)));background:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-moz-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-ms-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-o-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%)}.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter,.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_processing,.dataTables_wrapper .dataTables_paginate{color:#333}.dataTables_wrapper .dataTables_scroll{clear:both}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody{*margin-top:-1px;-webkit-overflow-scrolling:touch}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>th,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>td,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>th,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>td{vertical-align:middle}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>th>div.dataTables_sizing,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>td>div.dataTables_sizing,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>th>div.dataTables_sizing,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>td>div.dataTables_sizing{height:0;overflow:hidden;margin:0 !important;padding:0 !important}.dataTables_wrapper.no-footer .dataTables_scrollBody{border-bottom:1px solid #111}.dataTables_wrapper.no-footer div.dataTables_scrollHead table.dataTable,.dataTables_wrapper.no-footer div.dataTables_scrollBody>table{border-bottom:none}.dataTables_wrapper:after{visibility:hidden;display:block;content:"";clear:both;height:0}@media screen and (max-width: 767px){.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_paginate{float:none;text-align:center}.dataTables_wrapper .dataTables_paginate{margin-top:0.5em}}@media screen and (max-width: 640px){.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter{float:none;text-align:center}.dataTables_wrapper .dataTables_filter{margin-top:0.5em}} diff --git a/assets/styles/style.css b/assets/styles/style.css index 6334d36..d72408a 100644 --- a/assets/styles/style.css +++ b/assets/styles/style.css @@ -103,24 +103,29 @@ body.pg-loaded > .inner { margin-right: 10px; } -.modalBodyPassword { +.modalBody { margin: 20px; } -#dlgGeneralError .modalBodyPassword { +#dlgGeneralError .modalBody { height: 100px; } -#dlgCreateWalletPassword .modalBodyPassword, -#dlgCreateWalletPassword .modalBodyPassword { +#dlgDeleteAddressConfirm .modalBody { + height: 100px; +} + +#dlgCreateWalletPassword .modalBody, +#dlgCreateAddressAndName .modalBody { height: 200px; } -#dlgSendWalletPassword .modalBodyPassword { +#dlgSendWalletPassword .modalBody { height: 300px; } -#dlgChangeWalletName .modalBodyPassword { +#dlgChangeWalletName .modalBody, +#dlgChangeAddressName .modalBody { height: 150px; } @@ -136,6 +141,12 @@ body.pg-loaded > .inner { right: 20px; } +.btn-dialog-cancel { + position: absolute; + bottom: 10px; + right: 80px; +} + .modalDialog { display: none; border-bottom: 3px solid #7A1336 !important; @@ -312,11 +323,14 @@ div.sidebar svg { margin: 10px; } -#noWalletsPresent { +#noWalletsPresent, +#noAddressPresent { font-size: 1.3em; } -div.noWalletsWrapper { +div.noWalletsWrapper, +div.noAddressWrapper { + display: flex; align-items: center; justify-content: center; diff --git a/assets/styles/transactions.css b/assets/styles/transactions.css index 1b4e6b7..6af2955 100644 --- a/assets/styles/transactions.css +++ b/assets/styles/transactions.css @@ -1,3 +1,54 @@ +/* + * Table button styles + */ + +.dt-button { + margin-left: 10px !important; + color: #ffffff !important; + background-color: #7A1336 !important; + border: 1px solid #450118 !important; + background-image: none !important; +} + +.dt-button:hover, +.dt-button:focus, +.dt-button.active, +.open .dropdown-toggle.dt-button { + color: #ffffff !important; + background-color: #B01549 !important; + border: 1px solid #450118 !important; + background-image: none !important; +} + +.dt-button.active, +.open .dropdown-toggle.dt-button.dt-button { + background-image: none !important; +} + +.dt-button.disabled, +.dt-button[disabled], +fieldset[disabled] .dt-button, +.dt-button.disabled:hover, +.dt-button[disabled]:hover, +fieldset[disabled] .dt-button:hover, +.dt-button.disabled:focus, +.dt-button[disabled]:focus, +fieldset[disabled] .dt-button:focus, +.dt-button.disabled:active, +.dt-button[disabled]:active, +fieldset[disabled] .dt-button:active, +.dt-button.disabled.active, +.dt-button[disabled].active, +fieldset[disabled] .dt-button.active { + background-color: #7A1336 !important; + border-color: #450118 !important; +} + +.dt-button .badge { + color: #7A1336 !important; + background-color: #ffffff !important; +} + /* * Table styles */ diff --git a/assets/templates/addressBook.html b/assets/templates/addressBook.html new file mode 100644 index 0000000..9aecc91 --- /dev/null +++ b/assets/templates/addressBook.html @@ -0,0 +1,67 @@ +
+ +
+
+ {{#if addressData.length}} + + + + + + + + + + + {{#addressData}} + + + + + + + {{/addressData}} + +
NameAddressActions
{{name}}{{address}}
+ {{else}} +
You don't have any addresses, create a new one
+ {{/if}} +
+ +
+
+
+ + +
+
+ + +
+ +
+
+ + +
+
+
+ + +
+ +
+
+ + +
+
+
+ Do you really want to delete the address? +
+ + +
+
+ + \ No newline at end of file diff --git a/assets/templates/send.html b/assets/templates/send.html index a508beb..1d02017 100644 --- a/assets/templates/send.html +++ b/assets/templates/send.html @@ -60,7 +60,7 @@
-
+
@@ -88,7 +88,7 @@
-
+
\ No newline at end of file diff --git a/assets/templates/wallets.html b/assets/templates/wallets.html index a6dbdbb..ee576be 100644 --- a/assets/templates/wallets.html +++ b/assets/templates/wallets.html @@ -12,6 +12,7 @@ Name Address + Balance @@ -34,7 +35,7 @@
-
+
@@ -50,7 +51,7 @@
-
+
diff --git a/index.html b/index.html index 4b67e8e..0231138 100644 --- a/index.html +++ b/index.html @@ -60,6 +60,9 @@ + @@ -84,6 +87,7 @@ require('./renderer/settings.js'); require('./renderer/wallets.js'); require('./renderer/blockchain.js'); + require('./renderer/addressBook.js'); require('./renderer/transactions.js'); require('./renderer/tableTransactions.js'); @@ -91,7 +95,7 @@
-
+
diff --git a/renderer/addressBook.js b/renderer/addressBook.js new file mode 100644 index 0000000..52b057a --- /dev/null +++ b/renderer/addressBook.js @@ -0,0 +1,159 @@ +const {ipcRenderer} = require('electron'); + +class AddressBook { + constructor() { + } + + setAddressName(address, name) { + console.log(address); + console.log(name); + var addressBook = ipcRenderer.sendSync('getJSONFile', 'addresses.json'); + + if (!addressBook) { + addressBook = { names: {} }; + } + + // set the wallet name from the dialog box + addressBook.names[address] = name; + ipcRenderer.sendSync('setJSONFile', + { + file: 'addresses.json', + data: addressBook + }); + } + + getAddressName(address) { + var addressBook = ipcRenderer.sendSync('getJSONFile', 'addresses.json'); + + if (!addressBook) { + addressBook = { names: {} }; + } + + // set the wallet name from the dialog box + return addressBook.names[address] || ""; + } + + getAddressList() { + var addressBook = ipcRenderer.sendSync('getJSONFile', 'addresses.json'); + + if (!addressBook) { + addressBook = { names: {} }; + } + + return addressBook.names; + } + + deleteAddress(address) { + var addressBook = ipcRenderer.sendSync('getJSONFile', 'addresses.json'); + + if (!addressBook) { + addressBook = { names: {} }; + } else { + delete addressBook.names[address]; + } + + ipcRenderer.sendSync('setJSONFile', + { + file: 'addresses.json', + data: addressBook + }); + } + + enableButtonTooltips() { + } + + renderAddressBook() { + var addressObject = EthoAddressBook.getAddressList(); + var renderData = { addressData: [] }; + + for (var key in addressObject) { + if (addressObject.hasOwnProperty(key)) { + var addressEntry = {}; + addressEntry.name = addressObject[key]; + addressEntry.address = key; + renderData.addressData.push(addressEntry); + } + } + + // render the wallets current state + EthoMainGUI.renderTemplate("addressBook.html", renderData); + $(document).trigger("render_addressBook"); + EthoAddressBook.enableButtonTooltips(); + } +} + +// the event to tell us that the wallets are rendered +$(document).on("render_addressBook", function() { + $("#btnNewAddress").off('click').on('click', function() { + $("#dlgCreateAddressAndName").iziModal(); + $("#addressName").val(""); + $("#addressHash").val(""); + $('#dlgCreateAddressAndName').iziModal('open'); + + function doCreateNewWallet() { + $('#dlgCreateAddressAndName').iziModal('close'); + + EthoAddressBook.setAddressName($("#addressHash").val(), $("#addressName").val()); + EthoAddressBook.renderAddressBook(); + + iziToast.success({ + title: 'Created', + message: 'New address was successfully created', + position: 'topRight', + timeout: 5000 + }); + } + + $("#btnCreateAddressConfirm").off('click').on('click', function() { + doCreateNewWallet(); + }); + + $("#dlgCreateAddressAndName").off('keypress').on('keypress', function(e) { + if(e.which == 13) { + doCreateNewWallet(); + } + }); + }); + + $(".btnChangAddressName").off('click').on('click', function() { + var walletAddress = $(this).attr('data-address'); + var walletName = $(this).attr('data-name'); + + $("#dlgChangeAddressName").iziModal(); + $("#inputAddressName").val(walletName); + $('#dlgChangeAddressName').iziModal('open'); + + function doChangeAddressName() { + EthoAddressBook.setAddressName(walletAddress, $("#inputAddressName").val()); + $('#dlgChangeAddressName').iziModal('close'); + EthoAddressBook.renderAddressBook(); + } + + $("#btnChangeAddressNameConfirm").off('click').on('click', function() { + doChangeAddressName(); + }); + + $("#dlgChangeAddressName").off('keypress').on('keypress', function(e) { + if(e.which == 13) { + doChangeAddressName(); + } + }); + }); + + $(".btnDeleteAddress").off('click').on('click', function() { + $("#dlgDeleteAddressConfirm").iziModal(); + $('#dlgDeleteAddressConfirm').iziModal('open'); + + $("#btnDeleteAddressCancel").off('click').on('click', function() { + $('#dlgDeleteAddressConfirm').iziModal('close'); + }); + + $("#btnDeleteAddressConfirm").off('click').on('click', function() { + EthoAddressBook.deleteAddress($(this).attr('data-address')); + $('#dlgDeleteAddressConfirm').iziModal('close'); + EthoAddressBook.renderAddressBook(); + }); + }); +}); + +EthoAddressBook = new AddressBook(); \ No newline at end of file diff --git a/renderer/maingui.js b/renderer/maingui.js index d33ee19..1ce0efa 100644 --- a/renderer/maingui.js +++ b/renderer/maingui.js @@ -14,7 +14,10 @@ class MainGUI { case "account": $("#mainNavBtnWalletsWrapper").addClass("iconSelected"); break; - case "send": + case "addressBook": + $("#mainNavBtnAddressBoookWrapper").addClass("iconSelected"); + break; + case "send": $("#mainNavBtnSendWrapper").addClass("iconSelected"); break; case "transactions": @@ -69,6 +72,11 @@ $("#mainNavBtnTransactions").click(function() { EthoTransactions.renderTransactions(); }); +$("#mainNavBtnAddressBoook").click(function() { + EthoMainGUI.changeAppState("addressBook"); + EthoAddressBook.renderAddressBook(); +}); + $("#mainNavBtnSend").click(function() { EthoMainGUI.changeAppState("send"); EthoSend.renderSendState(); diff --git a/renderer/send.js b/renderer/send.js index 77e6e73..5b700c0 100644 --- a/renderer/send.js +++ b/renderer/send.js @@ -79,7 +79,7 @@ $(document).on("render_send", function() { }, function(data) { $("#dlgAddressList").iziModal({ width: "800px" }); - EthoMainGUI.renderTemplate("addresslist.html", data, $("#dlgAddressListBody")); + EthoMainGUI.renderTemplate("addressList.html", data, $("#dlgAddressListBody")); $('#dlgAddressList').iziModal('open'); $(".btnSelectToAddress").off('click').on('click', function() { diff --git a/renderer/tableTransactions.js b/renderer/tableTransactions.js index eace89f..6b1862e 100644 --- a/renderer/tableTransactions.js +++ b/renderer/tableTransactions.js @@ -7,12 +7,13 @@ class tableTransactions { // register the sort datetime format $.fn.dataTable.moment('MMM Do YYYY HH:mm:ss'); - var namesType = $.fn.dataTable.absoluteOrder( + var namesType = $.fn.dataTable.absoluteOrderNumber( [ { value: null, position: 'top' } ]); // render the transactions $(id).DataTable({ + "dom": 'Bfrtip', "paging": false, "scrollY": "calc(100vh - 115px)", "responsive": true, @@ -20,6 +21,15 @@ class tableTransactions { "order": [[ 1, "desc" ]], "data": data, "oSearch": {"sSearch": EthoTransactions.getFilter() }, + "buttons": + [ + { + text: 'Refresh', + action: function ( e, dt, node, config ) { + EthoTransactions.renderTransactions(); + } + } + ], "columnDefs": [ { "targets": 0, diff --git a/renderer/transactions.js b/renderer/transactions.js index 760d848..1e10884 100644 --- a/renderer/transactions.js +++ b/renderer/transactions.js @@ -119,22 +119,33 @@ $(document).on("onSyncInterval", function() { counters = {}; } + function finalizeCounters(lastBlock) { + counters.transactions = lastBlock; + + ipcRenderer.sendSync('setJSONFile', + { + file: 'counters.json', + data: counters + }); + } + function doSyncRemainingBlocks() { EthoBlockchain.getBlock("latest", false, function(error) { EthoMainGUI.showGeneralError(error); }, function(block) { - var lastBlock = counters.transactions || 0; + var lastBlock = counters.transactions || 1; if (lastBlock < block.number) { function getNextBlockTransactions(blockNumber, maxBlock) { - EthoBlockchain.getBlock(blockNumber, true, - function(error) { - EthoMainGUI.showGeneralError(error); - }, - function(data) { - if (blockNumber < maxBlock) { + if (blockNumber < maxBlock) { + EthoBlockchain.getBlock(blockNumber, true, + function(error) { + EthoMainGUI.showGeneralError(error); + getNextBlockTransactions(blockNumber + 1 , maxBlock); + }, + function(data) { if (data.transactions) { data.transactions.forEach(element => { if ((EthoWallets.getAddressExists(element.from)) || (EthoWallets.getAddressExists(element.to))) { @@ -151,34 +162,33 @@ $(document).on("onSyncInterval", function() { ipcRenderer.send('storeTransaction', Transaction); $(document).trigger("onNewAccountTransaction"); - if (EthoMainGUI.getAppState() == "transactions") { - //$('#tableTransactionsForAll').DataTable().ajax.reload(); - } + iziToast.info({ + title: 'New Transaction', + message: vsprintf('Transaction from address %s to address %s was just processed', [Transaction.fromaddr, Transaction.toaddr]), + position: 'topRight', + timeout: 10000 + }); } - }); + }); } // call the next iteration for the next block - getNextBlockTransactions(blockNumber + 1 , maxBlock) - } else { - setTimeout(function() { - doSyncRemainingBlocks(); - }, 10000); + getNextBlockTransactions(blockNumber + 1 , maxBlock); } - - } - ); + ); + } else { + finalizeCounters(blockNumber); + + setTimeout(function() { + doSyncRemainingBlocks(); + }, 10000); + } } // call initial call of function getNextBlockTransactions(lastBlock, block.number); } else { - counters.transactions = block.number; - ipcRenderer.sendSync('setJSONFile', - { - file: 'counters.json', - data: counters - }); + finalizeCounters(lastBlock); setTimeout(function() { doSyncRemainingBlocks();