2017-01-11 03:38:55 -08:00
2016-03-25 01:18:05 -07:00
/ * *
* Module containing core application logic .
* @ param { jQuery } $ Insulated jQuery object
* @ param { JSON } settings Insulated ` window.snipeit.settings ` object .
* @ return { IIFE } Immediately invoked . Returns self .
* /
2016-05-24 16:10:04 -07:00
2017-05-31 05:23:26 -07:00
var lineOptions = {
legend : {
position : "bottom"
} ,
scales : {
yAxes : [ {
ticks : {
fontColor : "rgba(0,0,0,0.5)" ,
fontStyle : "bold" ,
beginAtZero : true ,
maxTicksLimit : 5 ,
padding : 20
} ,
gridLines : {
drawTicks : false ,
display : false
}
} ] ,
xAxes : [ {
gridLines : {
zeroLineColor : "transparent"
} ,
ticks : {
padding : 20 ,
fontColor : "rgba(0,0,0,0.5)" ,
fontStyle : "bold"
}
} ]
}
} ;
2016-05-24 16:10:04 -07:00
var pieOptions = {
//Boolean - Whether we should show a stroke on each segment
segmentShowStroke : true ,
//String - The colour of each segment stroke
segmentStrokeColor : "#fff" ,
//Number - The width of each segment stroke
segmentStrokeWidth : 1 ,
//Number - The percentage of the chart that we cut out of the middle
percentageInnerCutout : 50 , // This is 0 for Pie charts
//Number - Amount of animation steps
animationSteps : 100 ,
//String - Animation easing effect
animationEasing : "easeOutBounce" ,
//Boolean - Whether we animate the rotation of the Doughnut
animateRotate : true ,
//Boolean - Whether we animate scaling the Doughnut from the centre
animateScale : false ,
//Boolean - whether to make the chart responsive to window resizing
responsive : true ,
// Boolean - whether to maintain the starting aspect ratio or not when responsive, if set to false, will take up entire container
maintainAspectRatio : false ,
//String - A legend template
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li>" +
"<i class='fa fa-circle-o' style='color: <%=segments[i].fillColor%>'></i>" +
"<%if(segments[i].label){%><%=segments[i].label%><%}%> foo</li><%}%></ul>" ,
//String - A tooltip template
tooltipTemplate : "<%=value %> <%=label%> "
} ;
2017-01-11 03:38:55 -08:00
2016-05-24 16:10:04 -07:00
//-----------------
//- END PIE CHART -
//-----------------
2019-05-23 16:56:22 -07:00
var baseUrl = $ ( 'meta[name="baseUrl"]' ) . attr ( 'content' ) ;
2016-05-24 16:10:04 -07:00
2016-03-25 01:18:05 -07:00
( function ( $ , settings ) {
var Components = { } ;
Components . modals = { } ;
// confirm delete modal
Components . modals . confirmDelete = function ( ) {
var $el = $ ( 'table' ) ;
var events = {
'click' : function ( evnt ) {
var $context = $ ( this ) ;
var $dataConfirmModal = $ ( '#dataConfirmModal' ) ;
var href = $context . attr ( 'href' ) ;
var message = $context . attr ( 'data-content' ) ;
var title = $context . attr ( 'data-title' ) ;
$ ( '#myModalLabel' ) . text ( title ) ;
$dataConfirmModal . find ( '.modal-body' ) . text ( message ) ;
2016-12-19 10:42:33 -08:00
$ ( '#deleteForm' ) . attr ( 'action' , href ) ;
2016-03-25 01:18:05 -07:00
$dataConfirmModal . modal ( {
show : true
} ) ;
return false ;
}
} ;
var render = function ( ) {
$el . on ( 'click' , '.delete-asset' , events [ 'click' ] ) ;
} ;
return {
render : render
} ;
} ;
/ * *
* Application start point
* Component definition stays out of load event , execution only happens .
* /
$ ( function ( ) {
new Components . modals . confirmDelete ( ) . render ( ) ;
} ) ;
} ( jQuery , window . snipeit . settings ) ) ;
2016-05-24 16:10:04 -07:00
2017-01-11 03:55:47 -08:00
2017-01-11 03:38:55 -08:00
$ ( document ) . ready ( function ( ) {
2017-01-11 05:51:13 -08:00
/ *
* Slideout help menu
* /
$ ( '.slideout-menu-toggle' ) . on ( 'click' , function ( event ) {
event . preventDefault ( ) ;
// create menu variables
var slideoutMenu = $ ( '.slideout-menu' ) ;
var slideoutMenuWidth = $ ( '.slideout-menu' ) . width ( ) ;
// toggle open class
slideoutMenu . toggleClass ( "open" ) ;
// slide menu
if ( slideoutMenu . hasClass ( "open" ) ) {
slideoutMenu . show ( ) ;
slideoutMenu . animate ( {
right : "0px"
} ) ;
} else {
slideoutMenu . animate ( {
right : - slideoutMenuWidth
} , "-350px" ) ;
slideoutMenu . fadeOut ( ) ;
}
2017-01-11 03:38:55 -08:00
} ) ;
2017-01-11 05:51:13 -08:00
/ *
* iCheck checkbox plugin
* /
2017-01-11 17:07:27 -08:00
$ ( 'input[type="checkbox"].minimal, input[type="radio"].minimal' ) . iCheck ( {
2017-01-11 05:51:13 -08:00
checkboxClass : 'icheckbox_minimal-blue' ,
radioClass : 'iradio_minimal-blue'
} ) ;
2017-01-11 17:07:27 -08:00
2017-01-11 05:51:13 -08:00
/ *
* Select2
* /
2017-01-11 17:07:27 -08:00
2017-01-11 05:51:13 -08:00
var iOS = /iPhone|iPad|iPod/ . test ( navigator . userAgent ) && ! window . MSStream ;
if ( ! iOS )
{
2017-01-25 21:29:23 -08:00
// Vue collision: Avoid overriding a vue select2 instance
// by checking to see if the item has already been select2'd.
2017-05-31 13:26:48 -07:00
$ ( 'select.select2:not(".select2-hidden-accessible")' ) . each ( function ( i , obj ) {
2017-01-25 21:29:23 -08:00
{
$ ( obj ) . select2 ( ) ;
}
} ) ;
2017-01-11 05:51:13 -08:00
}
$ ( '.datepicker' ) . datepicker ( ) ;
2017-01-11 17:07:27 -08:00
2017-10-26 02:28:17 -07:00
var datepicker = $ . fn . datepicker . noConflict ( ) ; // return $.fn.datepicker to previously assigned value
$ . fn . bootstrapDP = datepicker ;
$ ( '.datepicker' ) . datepicker ( ) ;
// Crazy select2 rich dropdowns with images!
$ ( '.js-data-ajax' ) . each ( function ( i , item ) {
var link = $ ( item ) ;
var endpoint = link . data ( "endpoint" ) ;
var select = link . data ( "select" ) ;
link . select2 ( {
2018-07-16 14:10:54 -07:00
/ * *
* Adds an empty placeholder , allowing every select2 instance to be cleared .
* This placeholder can be overridden with the "data-placeholder" attribute .
* /
placeholder : '' ,
allowClear : true ,
2017-10-26 02:28:17 -07:00
ajax : {
2017-11-08 00:57:43 -08:00
// the baseUrl includes a trailing slash
url : baseUrl + 'api/v1/' + endpoint + '/selectlist' ,
2017-10-26 02:28:17 -07:00
dataType : 'json' ,
2017-11-04 00:48:54 -07:00
delay : 250 ,
2017-10-26 02:28:17 -07:00
headers : {
"X-Requested-With" : 'XMLHttpRequest' ,
"X-CSRF-TOKEN" : $ ( 'meta[name="csrf-token"]' ) . attr ( 'content' )
} ,
data : function ( params ) {
var data = {
search : params . term ,
2018-04-25 02:39:23 -07:00
page : params . page || 1 ,
assetStatusType : link . data ( "asset-status-type" ) ,
2017-10-26 02:28:17 -07:00
} ;
return data ;
} ,
processResults : function ( data , params ) {
params . page = params . page || 1 ;
2017-10-25 20:15:34 -07:00
2017-10-26 02:28:17 -07:00
var answer = {
results : data . items ,
pagination : {
more : "true" //(params.page < data.page_count)
}
} ;
return answer ;
} ,
cache : true
} ,
escapeMarkup : function ( markup ) { return markup ; } , // let our custom formatter work
templateResult : formatDatalist ,
templateSelection : formatDataSelection
2017-10-25 20:15:34 -07:00
} ) ;
2017-10-26 02:28:17 -07:00
2017-10-25 20:15:34 -07:00
} ) ;
2017-10-26 02:28:17 -07:00
function formatDatalist ( datalist ) {
var loading _markup = '<i class="fa fa-spinner fa-spin" aria-hidden="true"></i> Loading...' ;
if ( datalist . loading ) {
return loading _markup ;
}
var markup = "<div class='clearfix'>" ;
markup += "<div class='pull-left' style='padding-right: 10px;'>" ;
if ( datalist . image ) {
2017-12-04 20:19:30 -08:00
markup += "<div style='width: 30px;'><img src='" + datalist . image + "' style='max-height: 20px; max-width: 30px;'></div>" ;
2017-10-26 02:28:17 -07:00
} else {
2017-12-04 20:19:30 -08:00
markup += "<div style='height: 20px; width: 30px;'></div>" ;
2017-10-26 02:28:17 -07:00
}
2017-10-25 20:15:34 -07:00
2017-10-26 02:28:17 -07:00
markup += "</div><div>" + datalist . text + "</div>" ;
markup += "</div>" ;
return markup ;
}
2017-10-25 20:15:34 -07:00
2017-10-26 02:28:17 -07:00
function formatDataSelection ( datalist ) {
2019-03-18 20:49:32 -07:00
// This a heinous workaround for a known bug in Select2.
// Without this, the rich selectlists are vulnerable to XSS.
// Many thanks to @uberbrady for this fix. It ain't pretty,
// but it resolves the issue until Select2 addresses it on their end.
//
// Bug was reported in 2016 :{
// https://github.com/select2/select2/issues/4587
return datalist . text . replace ( />/g , '>' )
. replace ( /</g , '<' )
. replace ( /"/g , '"' )
. replace ( /'/g , ''' ) ;
2017-10-26 02:28:17 -07:00
}
2017-10-25 20:15:34 -07:00
2017-11-21 20:55:57 -08:00
// This handles the radio button selectors for the checkout-to-foo options
// on asset checkout and also on asset edit
2017-11-21 15:58:31 -08:00
$ ( function ( ) {
$ ( 'input[name=checkout_to_type]' ) . on ( "change" , function ( ) {
var assignto _type = $ ( 'input[name=checkout_to_type]:checked' ) . val ( ) ;
var userid = $ ( '#assigned_user option:selected' ) . val ( ) ;
if ( assignto _type == 'asset' ) {
$ ( '#current_assets_box' ) . fadeOut ( ) ;
$ ( '#assigned_asset' ) . show ( ) ;
$ ( '#assigned_user' ) . hide ( ) ;
$ ( '#assigned_location' ) . hide ( ) ;
$ ( '.notification-callout' ) . fadeOut ( ) ;
2017-11-27 21:20:31 -08:00
2017-11-21 15:58:31 -08:00
} else if ( assignto _type == 'location' ) {
$ ( '#current_assets_box' ) . fadeOut ( ) ;
$ ( '#assigned_asset' ) . hide ( ) ;
$ ( '#assigned_user' ) . hide ( ) ;
$ ( '#assigned_location' ) . show ( ) ;
$ ( '.notification-callout' ) . fadeOut ( ) ;
} else {
2017-11-27 21:20:31 -08:00
2017-11-21 15:58:31 -08:00
$ ( '#assigned_asset' ) . hide ( ) ;
$ ( '#assigned_user' ) . show ( ) ;
$ ( '#assigned_location' ) . hide ( ) ;
if ( userid ) {
$ ( '#current_assets_box' ) . fadeIn ( ) ;
}
$ ( '.notification-callout' ) . fadeIn ( ) ;
2017-11-27 21:20:31 -08:00
2017-11-21 15:58:31 -08:00
}
} ) ;
} ) ;
2018-02-13 17:04:50 -08:00
// ------------------------------------------------
// Deep linking for Bootstrap tabs
// ------------------------------------------------
var taburl = document . location . toString ( ) ;
// Allow full page URL to activate a tab's ID
// ------------------------------------------------
// This allows linking to a tab on page load via the address bar.
// So a URL such as, http://snipe-it.local/hardware/2/#my_tab will
// cause the tab on that page with an ID of “my_tab” to be active.
if ( taburl . match ( '#' ) ) {
$ ( '.nav-tabs a[href="#' + taburl . split ( '#' ) [ 1 ] + '"]' ) . tab ( 'show' ) ;
}
// Allow internal page links to activate a tab's ID.
// ------------------------------------------------
// This allows you to link to a tab from anywhere on the page
// including from within another tab. Also note that internal page
// links either inside or out of the tabs need to include data-toggle="tab"
// Ex: <a href="#my_tab" data-toggle="tab">Click me</a>
$ ( 'a[data-toggle="tab"]' ) . click ( function ( e ) {
var href = $ ( this ) . attr ( "href" ) ;
history . pushState ( null , null , href ) ;
e . preventDefault ( ) ;
$ ( 'a[href="' + $ ( this ) . attr ( 'href' ) + '"]' ) . tab ( 'show' ) ;
} ) ;
// ------------------------------------------------
// End Deep Linking for Bootstrap tabs
// ------------------------------------------------
2018-02-17 00:51:22 -08:00
// Image preview
function readURL ( input ) {
if ( input . files && input . files [ 0 ] ) {
var reader = new FileReader ( ) ;
reader . onload = function ( e ) {
$ ( '#imagePreview' ) . attr ( 'src' , e . target . result ) ;
}
reader . readAsDataURL ( input . files [ 0 ] ) ;
}
}
function formatBytes ( bytes ) {
if ( bytes < 1024 ) return bytes + " Bytes" ;
2018-07-16 20:09:53 -07:00
else if ( bytes < 1048576 ) return ( bytes / 1024 ) . toFixed ( 2 ) + " KB" ;
else if ( bytes < 1073741824 ) return ( bytes / 1048576 ) . toFixed ( 2 ) + " MB" ;
else return ( bytes / 1073741824 ) . toFixed ( 2 ) + " GB" ;
2018-02-17 00:51:22 -08:00
} ;
2018-02-16 21:17:41 -08:00
// File size validation
$ ( '#uploadFile' ) . bind ( 'change' , function ( ) {
$ ( '#upload-file-status' ) . removeClass ( 'text-success' ) . removeClass ( 'text-danger' ) ;
$ ( '.goodfile' ) . remove ( ) ;
$ ( '.badfile' ) . remove ( ) ;
2018-02-17 00:51:22 -08:00
$ ( '.badfile' ) . remove ( ) ;
$ ( '.previewSize' ) . hide ( ) ;
2018-07-16 20:09:53 -07:00
$ ( '#upload-file-info' ) . html ( '' ) ;
2018-02-16 21:17:41 -08:00
var max _size = $ ( '#uploadFile' ) . data ( 'maxsize' ) ;
2018-07-16 20:09:53 -07:00
var total _size = 0 ;
2018-02-16 21:17:41 -08:00
2018-07-16 20:09:53 -07:00
for ( var i = 0 ; i < this . files . length ; i ++ ) {
total _size += this . files [ i ] . size ;
$ ( '#upload-file-info' ) . append ( '<span class="label label-default">' + this . files [ i ] . name + ' (' + formatBytes ( this . files [ i ] . size ) + ')</span> ' ) ;
}
if ( total _size > max _size ) {
$ ( '#upload-file-status' ) . addClass ( 'text-danger' ) . removeClass ( 'help-block' ) . prepend ( '<i class="badfile fa fa-times"></i> ' ) . append ( '<span class="previewSize"> Upload is ' + formatBytes ( total _size ) + '.</span>' ) ;
2018-02-16 21:17:41 -08:00
} else {
$ ( '#upload-file-status' ) . addClass ( 'text-success' ) . removeClass ( 'help-block' ) . prepend ( '<i class="goodfile fa fa-check"></i> ' ) ;
2018-02-17 00:51:22 -08:00
readURL ( this ) ;
$ ( '#imagePreview' ) . fadeIn ( ) ;
2018-02-16 21:17:41 -08:00
}
2018-07-16 20:09:53 -07:00
2018-02-16 21:17:41 -08:00
} ) ;
2018-02-13 17:04:50 -08:00
2017-01-11 05:51:13 -08:00
2018-02-17 00:51:22 -08:00
2017-01-11 05:51:13 -08:00
} ) ;