/** * Module containing core application logic. * @param {jQuery} $ Insulated jQuery object * @param {JSON} settings Insulated `window.snipeit.settings` object. * @return {IIFE} Immediately invoked. Returns self. */ 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" } }] } }; 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: "", //String - A tooltip template tooltipTemplate: "<%=value %> <%=label%> " }; //----------------- //- END PIE CHART - //----------------- var baseUrl = $('meta[name="baseUrl"]').attr('content'); (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); $('#deleteForm').attr('action', href); $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)); $(document).ready(function () { /* * 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(); } }); /* * iCheck checkbox plugin */ $('input[type="checkbox"].minimal, input[type="radio"].minimal').iCheck({ checkboxClass: 'icheckbox_minimal-blue', radioClass: 'iradio_minimal-blue' }); /* * Select2 */ var iOS = /iPhone|iPad|iPod/.test(navigator.userAgent) && !window.MSStream; if(!iOS) { // Vue collision: Avoid overriding a vue select2 instance // by checking to see if the item has already been select2'd. $('select.select2:not(".select2-hidden-accessible")').each(function (i,obj) { { $(obj).select2(); } }); } $('.datepicker').datepicker(); 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({ /** * Adds an empty placeholder, allowing every select2 instance to be cleared. * This placeholder can be overridden with the "data-placeholder" attribute. */ placeholder: '', allowClear: true, ajax: { // the baseUrl includes a trailing slash url: baseUrl + 'api/v1/' + endpoint + '/selectlist', dataType: 'json', delay: 250, headers: { "X-Requested-With": 'XMLHttpRequest', "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr('content') }, data: function (params) { var data = { search: params.term, page: params.page || 1, assetStatusType: link.data("asset-status-type"), }; return data; }, processResults: function (data, params) { params.page = params.page || 1; 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 }); }); function formatDatalist (datalist) { var loading_markup = ' Loading...'; if (datalist.loading) { return loading_markup; } var markup = "
" ; markup +="
"; if (datalist.image) { markup += "
"; } else { markup += "
"; } markup += "
" + datalist.text + "
"; markup += "
"; return markup; } function formatDataSelection (datalist) { // 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(/Click me $('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 // ------------------------------------------------ // 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"; 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"; }; // File size validation $('#uploadFile').bind('change', function() { $('#upload-file-status').removeClass('text-success').removeClass('text-danger'); $('.goodfile').remove(); $('.badfile').remove(); $('.badfile').remove(); $('.previewSize').hide(); $('#upload-file-info').html(''); var max_size = $('#uploadFile').data('maxsize'); var total_size = 0; for (var i = 0; i < this.files.length; i++) { total_size += this.files[i].size; $('#upload-file-info').append('' + this.files[i].name + ' (' + formatBytes(this.files[i].size) + ') '); } if (total_size > max_size) { $('#upload-file-status').addClass('text-danger').removeClass('help-block').prepend(' ').append(' Upload is ' + formatBytes(total_size) + '.'); } else { $('#upload-file-status').addClass('text-success').removeClass('help-block').prepend(' '); readURL(this); $('#imagePreview').fadeIn(); } }); });