Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 43cdace9de | |||
| a04af4aead | |||
| e7eec42ab8 | |||
| 063e5c407c | |||
| 3ba02b65fb | |||
| 88dc0700f0 | |||
| 899e2bc9b6 | |||
| 1e4071b51d | |||
| 38961298ed | |||
| ea6a6d098a | |||
| 1f0f9c2441 | |||
| d4fbea3571 | |||
| b32d74de57 | |||
| 4e4144ea74 | |||
| 7b331b26d3 | |||
| e02bea4275 | |||
| 24f5cdc743 | |||
| 08ee02d0cd | |||
| ec1ab6913e | |||
| f40bb7b8b3 | |||
| 17258b73a1 | |||
| 4a5007264e | |||
| bd01b11f4f | |||
| 064c0211db | |||
| 4cb931a93b | |||
| 3df8243d80 | |||
| f57c61dd4d |
@@ -36,7 +36,7 @@ class ViewAssetsController extends AuthorizedController
|
||||
|
||||
public function getRequestableIndex() {
|
||||
|
||||
$assets = Asset::with('model','defaultLoc')->Hardware()->Requestable()->get();
|
||||
$assets = Asset::with('model','defaultLoc')->Hardware()->RequestableAssets()->get();
|
||||
return View::make('frontend/account/requestable-assets', compact('user','assets'));
|
||||
}
|
||||
|
||||
|
||||
@@ -306,7 +306,7 @@ class AssetsController extends AdminController
|
||||
$asset->supplier_id = e(Input::get('supplier_id'));
|
||||
}
|
||||
|
||||
if (e(Input::get('requestable')) == '') {
|
||||
if (e(Input::get('requestable')) == '') {
|
||||
$asset->requestable = 0;
|
||||
} else {
|
||||
$asset->requestable = e(Input::get('requestable'));
|
||||
@@ -604,7 +604,7 @@ class AssetsController extends AdminController
|
||||
// Grab the dropdown list of status
|
||||
$statuslabel_list = Statuslabel::lists('name', 'id');
|
||||
|
||||
$location_list = array('' => '') + Location::lists('name', 'id');
|
||||
$location_list = array('' => '') + Location::lists('name', 'id');
|
||||
|
||||
// get depreciation list
|
||||
$depreciation_list = array('' => '') + Depreciation::lists('name', 'id');
|
||||
@@ -641,4 +641,228 @@ class AssetsController extends AdminController
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Upload the file to the server
|
||||
*
|
||||
* @param int $assetId
|
||||
* @return View
|
||||
**/
|
||||
public function postUpload($assetID = null)
|
||||
{
|
||||
$asset = Asset::find($assetID);
|
||||
|
||||
// the asset is valid
|
||||
$destinationPath = app_path().'/private_uploads';
|
||||
|
||||
if (isset($asset->id)) {
|
||||
|
||||
if (Input::hasFile('assetfile')) {
|
||||
|
||||
foreach(Input::file('assetfile') as $file) {
|
||||
|
||||
$rules = array(
|
||||
'assetfile' => 'required|mimes:png,gif,jpg,jpeg,doc,docx,pdf,txt|max:2000'
|
||||
);
|
||||
$validator = Validator::make(array('assetfile'=> $file), $rules);
|
||||
|
||||
if($validator->passes()){
|
||||
|
||||
$extension = $file->getClientOriginalExtension();
|
||||
$filename = 'hardware-'.$asset->id.'-'.str_random(8);
|
||||
$filename .= '-'.Str::slug($file->getClientOriginalName()).'.'.$extension;
|
||||
$upload_success = $file->move($destinationPath, $filename);
|
||||
|
||||
//Log the deletion of seats to the log
|
||||
$logaction = new Actionlog();
|
||||
$logaction->asset_id = $asset->id;
|
||||
$logaction->asset_type = 'hardware';
|
||||
$logaction->user_id = Sentry::getUser()->id;
|
||||
$logaction->note = e(Input::get('notes'));
|
||||
$logaction->checkedout_to = NULL;
|
||||
$logaction->created_at = date("Y-m-d h:i:s");
|
||||
$logaction->filename = $filename;
|
||||
$log = $logaction->logaction('uploaded');
|
||||
} else {
|
||||
return Redirect::back()->with('error', Lang::get('admin/hardware/message.upload.invalidfiles'));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if ($upload_success) {
|
||||
return Redirect::back()->with('success', Lang::get('admin/hardware/message.upload.success'));
|
||||
} else {
|
||||
return Redirect::back()->with('success', Lang::get('admin/hardware/message.upload.error'));
|
||||
}
|
||||
|
||||
} else {
|
||||
return Redirect::back()->with('success', Lang::get('admin/hardware/message.upload.nofiles'));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
// Prepare the error message
|
||||
$error = Lang::get('admin/hardware/message.does_not_exist', compact('id'));
|
||||
|
||||
// Redirect to the hardware management page
|
||||
return Redirect::route('hardware')->with('error', $error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete the associated file
|
||||
*
|
||||
* @param int $assetId
|
||||
* @return View
|
||||
**/
|
||||
public function getDeleteFile($assetID = null, $fileId = null)
|
||||
{
|
||||
$asset = Asset::find($assetID);
|
||||
$destinationPath = app_path().'/private_uploads';
|
||||
|
||||
// the asset is valid
|
||||
if (isset($asset->id)) {
|
||||
|
||||
$log = Actionlog::find($fileId);
|
||||
$full_filename = $destinationPath.'/'.$log->filename;
|
||||
if (file_exists($full_filename)) {
|
||||
unlink($destinationPath.'/'.$log->filename);
|
||||
}
|
||||
$log->delete();
|
||||
return Redirect::back()->with('success', Lang::get('admin/hardware/message.deletefile.success'));
|
||||
|
||||
} else {
|
||||
// Prepare the error message
|
||||
$error = Lang::get('admin/hardware/message.does_not_exist', compact('id'));
|
||||
|
||||
// Redirect to the hardware management page
|
||||
return Redirect::route('hardware')->with('error', $error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Display/download the uploaded file
|
||||
*
|
||||
* @param int $assetId
|
||||
* @return View
|
||||
**/
|
||||
public function displayFile($assetID = null, $fileId = null)
|
||||
{
|
||||
|
||||
$asset = Asset::find($assetID);
|
||||
|
||||
// the asset is valid
|
||||
if (isset($asset->id)) {
|
||||
$log = Actionlog::find($fileId);
|
||||
$file = $log->get_src();
|
||||
return Response::download($file);
|
||||
} else {
|
||||
// Prepare the error message
|
||||
$error = Lang::get('admin/hardware/message.does_not_exist', compact('id'));
|
||||
|
||||
// Redirect to the hardware management page
|
||||
return Redirect::route('hardware')->with('error', $error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Display bulk edit screen
|
||||
*
|
||||
* @return View
|
||||
**/
|
||||
public function postBulkEdit($assets = null)
|
||||
{
|
||||
|
||||
if (Input::has('edit_asset')) {
|
||||
|
||||
$assets = Input::get('edit_asset');
|
||||
|
||||
$supplier_list = array('' => '') + Supplier::orderBy('name', 'asc')->lists('name', 'id');
|
||||
$statuslabel_list = array('' => '') + Statuslabel::lists('name', 'id');
|
||||
$location_list = array('' => '') + Location::lists('name', 'id');
|
||||
}
|
||||
|
||||
return View::make('backend/hardware/bulk')->with('assets',$assets)->with('supplier_list',$supplier_list)->with('statuslabel_list',$statuslabel_list)->with('location_list',$location_list);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Save bulk edits
|
||||
*
|
||||
* @return View
|
||||
**/
|
||||
public function postBulkSave($assets = null)
|
||||
{
|
||||
|
||||
if (Input::has('bulk_edit')) {
|
||||
|
||||
$assets = Input::get('bulk_edit');
|
||||
|
||||
if ( (Input::has('purchase_date')) || (Input::has('rtd_location_id')) || (Input::has('status_id')) ) {
|
||||
|
||||
foreach ($assets as $key => $value) {
|
||||
|
||||
$update_array = array();
|
||||
|
||||
if (Input::has('purchase_date')) {
|
||||
$update_array['purchase_date'] = e(Input::get('purchase_date'));
|
||||
}
|
||||
|
||||
if (Input::has('rtd_location_id')) {
|
||||
$update_array['rtd_location_id'] = e(Input::get('rtd_location_id'));
|
||||
}
|
||||
|
||||
if (Input::has('status_id')) {
|
||||
$update_array['status_id'] = e(Input::get('status_id'));
|
||||
}
|
||||
|
||||
|
||||
if (DB::table('assets')
|
||||
->where('id', $key)
|
||||
->update($update_array)) {
|
||||
|
||||
$logaction = new Actionlog();
|
||||
$logaction->asset_id = $key;
|
||||
$logaction->asset_type = 'hardware';
|
||||
$logaction->created_at = date("Y-m-d h:i:s");
|
||||
|
||||
if (Input::has('rtd_location_id')) {
|
||||
$logaction->location_id = e(Input::get('rtd_location_id'));
|
||||
}
|
||||
$logaction->user_id = Sentry::getUser()->id;
|
||||
$log = $logaction->logaction('update');
|
||||
|
||||
}
|
||||
|
||||
} // endforeach
|
||||
|
||||
return Redirect::to("hardware")->with('success', Lang::get('admin/hardware/message.update.success'));
|
||||
|
||||
// no values given, nothing to update
|
||||
} else {
|
||||
return Redirect::to("hardware")->with('info',Lang::get('admin/hardware/message.update.nothing_updated'));
|
||||
|
||||
}
|
||||
|
||||
|
||||
} // endif
|
||||
|
||||
return Redirect::to("hardware");
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -369,8 +369,8 @@ class LicensesController extends AdminController
|
||||
|
||||
// Delete the license and the associated license seats
|
||||
DB::table('license_seats')
|
||||
->where('id', $asset->id)
|
||||
->update(array('assigned_to' => NULL));
|
||||
->where('id', $license->id)
|
||||
->update(array('assigned_to' => NULL,'asset_id' => NULL));
|
||||
|
||||
$licenseseats = $license->licenseseats();
|
||||
$licenseseats->delete();
|
||||
@@ -578,7 +578,7 @@ class LicensesController extends AdminController
|
||||
$logaction->checkedout_to = $licenseseat->assigned_to;
|
||||
|
||||
// Update the asset data
|
||||
$licenseseat->assigned_to = '0';
|
||||
$licenseseat->assigned_to = NULL;
|
||||
$licenseseat->asset_id = NULL;
|
||||
|
||||
// Was the asset updated?
|
||||
|
||||
@@ -86,6 +86,7 @@ class SettingsController extends AdminController
|
||||
$setting->per_page = e(Input::get('per_page'));
|
||||
$setting->qr_code = e(Input::get('qr_code', '0'));
|
||||
$setting->display_eol = e(Input::get('display_eol', '0'));
|
||||
$setting->load_remote = e(Input::get('load_remote', '0'));
|
||||
$setting->qr_text = e(Input::get('qr_text'));
|
||||
$setting->auto_increment_prefix = e(Input::get('auto_increment_prefix'));
|
||||
$setting->auto_increment_assets = e(Input::get('auto_increment_assets', '0'));
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddLocalonlyToSettings extends Migration {
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
//
|
||||
Schema::table('settings', function ($table) {
|
||||
$table->boolean('load_remote')->default(1);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
//
|
||||
Schema::table('settings', function ($table) {
|
||||
$table->dropColumn('load_remote');
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -175,8 +175,8 @@ class AssetsSeeder extends Seeder
|
||||
|
||||
|
||||
$asset[] = array(
|
||||
'name' => 'Broke-Ass Laptop',
|
||||
'asset_tag' => 'NNY67567775',
|
||||
'name' => 'Broken Laptop',
|
||||
'asset_tag' => 'NNY6756756775',
|
||||
'model_id' => 2,
|
||||
'serial' => 'WS89080890',
|
||||
'purchase_date' => '2012-01-02',
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
return array(
|
||||
|
||||
'bulk_update' => 'Bulk Update Assets',
|
||||
'bulk_update_help' => 'This form allows you to update multiple assets at once. Only fill in the fields you need to change. Any fields left blank will remain unchanged. ',
|
||||
'bulk_update_warn' => 'You are about to edit the properties of :asset_count assets.',
|
||||
'checkedout_to' => 'Checked Out To',
|
||||
'checkout_to' => 'Checkout to',
|
||||
'cost' => 'Purchase Cost',
|
||||
|
||||
@@ -13,14 +13,28 @@ return array(
|
||||
),
|
||||
|
||||
'update' => array(
|
||||
'error' => 'Asset was not updated, please try again',
|
||||
'success' => 'Asset updated successfully.'
|
||||
'error' => 'Asset was not updated, please try again',
|
||||
'success' => 'Asset updated successfully.',
|
||||
'nothing_updated' => 'No fields were selected, so nothing was updated.',
|
||||
),
|
||||
|
||||
'restore' => array(
|
||||
'error' => 'Asset was not restored, please try again',
|
||||
'success' => 'Asset restored successfully.'
|
||||
),
|
||||
|
||||
'deletefile' => array(
|
||||
'error' => 'File not deleted. Please try again.',
|
||||
'success' => 'File successfully deleted.',
|
||||
),
|
||||
|
||||
'upload' => array(
|
||||
'error' => 'File(s) not uploaded. Please try again.',
|
||||
'success' => 'File(s) successfully uploaded.',
|
||||
'nofiles' => 'You did not select any files for upload',
|
||||
'invalidfiles' => 'One or more of your files is too large or is a filetype that is not allowed. Allowed filetypes are png, gif, jpg, doc, docx, pdf, and txt.',
|
||||
),
|
||||
|
||||
|
||||
'delete' => array(
|
||||
'confirm' => 'Are you sure you wish to delete this asset?',
|
||||
|
||||
@@ -10,6 +10,7 @@ return array(
|
||||
'display_qr' => 'Display QR Codes',
|
||||
'info' => 'These settings let you customize certain aspects of your installation.',
|
||||
'laravel' => 'Laravel Version',
|
||||
'load_remote' => 'This Snipe-IT install can load scripts from the outside world.',
|
||||
'per_page' => 'Results Per Page',
|
||||
'php' => 'PHP Version',
|
||||
'php_gd_info' => 'You must install php-gd to display QR codes, see install instructions.',
|
||||
|
||||
@@ -37,6 +37,7 @@ return array(
|
||||
'deleted' => 'Deleted',
|
||||
'deployed' => 'Deployed',
|
||||
'depreciation_report' => 'Depreciation Report',
|
||||
'download' => 'Download',
|
||||
'depreciation' => 'Depreciation',
|
||||
'editprofile' => 'Edit Your Profile',
|
||||
'eol' => 'EOL',
|
||||
@@ -48,8 +49,8 @@ return array(
|
||||
'gravatar_email' => 'Gravatar Email Address',
|
||||
'history_for' => 'History for',
|
||||
'id' => 'ID',
|
||||
'image_delete' => 'Delete Image',
|
||||
'image_upload' => 'Upload Image',
|
||||
'image_delete' => 'Delete Image',
|
||||
'image_upload' => 'Upload Image',
|
||||
'last_name' => 'Last Name',
|
||||
'license' => 'License',
|
||||
'license_report' => 'License Report',
|
||||
|
||||
+31
-45
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
class Asset extends Elegant
|
||||
class Asset extends Depreciable
|
||||
{
|
||||
use SoftDeletingTrait;
|
||||
protected $dates = ['deleted_at'];
|
||||
@@ -15,29 +15,36 @@ class Asset extends Elegant
|
||||
'notes' => 'alpha_space',
|
||||
'pysical' => 'integer',
|
||||
'supplier_id' => 'integer',
|
||||
//'asset_tag' => 'required|alpha_space|min:3|max:255|unique:assets,asset_tag,{id},deleted_at,NULL',
|
||||
//'email' => 'required|email|unique:users,email,NULL,id,deleted_at,NULL',
|
||||
//'asset_tag' => 'required|alpha_space|min:2|max:255|unique:assets,asset_tag,deleted_at,NULL',
|
||||
'asset_tag' => 'required|alpha_space|min:3|max:255|unique:assets,asset_tag,{id}',
|
||||
'serial' => 'required|alpha_dash|min:3|max:255|unique:assets,serial,{id}',
|
||||
//'serial' => 'required|alpha_dash|min:3|max:255|unique:assets,serial,{id}',
|
||||
'status' => 'integer'
|
||||
);
|
||||
|
||||
/**
|
||||
* Handle depreciation
|
||||
*/
|
||||
public function depreciate()
|
||||
public function depreciation()
|
||||
{
|
||||
return $this->getCurrentValue(
|
||||
Model::find($this->model_id)->depreciation_id,
|
||||
$this->purchase_cost,
|
||||
$this->purchase_date
|
||||
);
|
||||
return $this->model->belongsTo('Depreciation','depreciation_id');
|
||||
}
|
||||
|
||||
public function get_depreciation()
|
||||
{
|
||||
return $this->model->depreciation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get uploads for this asset
|
||||
*/
|
||||
public function uploads()
|
||||
{
|
||||
return $this->hasMany('Actionlog','asset_id')
|
||||
->where('asset_type', '=', 'hardware')
|
||||
->where('action_type', '=', 'uploaded')
|
||||
->whereNotNull('filename')
|
||||
->orderBy('created_at', 'desc');
|
||||
}
|
||||
|
||||
public function assigneduser()
|
||||
{
|
||||
return $this->belongsTo('User', 'assigned_to');
|
||||
return $this->belongsTo('User', 'assigned_to')->withTrashed();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,33 +127,6 @@ class Asset extends Elegant
|
||||
return date_format($date, 'Y-m-d');
|
||||
}
|
||||
|
||||
public function months_until_depreciated()
|
||||
{
|
||||
$today = date("Y-m-d");
|
||||
|
||||
// @link http://www.php.net/manual/en/class.datetime.php
|
||||
$d1 = new DateTime($today);
|
||||
$d2 = new DateTime($this->depreciated_date());
|
||||
|
||||
// @link http://www.php.net/manual/en/class.dateinterval.php
|
||||
$interval = $d1->diff($d2);
|
||||
return $interval;
|
||||
}
|
||||
|
||||
|
||||
public function depreciated_date()
|
||||
{
|
||||
$date = date_create($this->purchase_date);
|
||||
date_add($date, date_interval_create_from_date_string($this->depreciation->months.' months'));
|
||||
return date_format($date, 'Y-m-d');
|
||||
}
|
||||
|
||||
|
||||
public function depreciation()
|
||||
{
|
||||
return $this->model->belongsTo('Depreciation','depreciation_id');
|
||||
}
|
||||
|
||||
public function model()
|
||||
{
|
||||
return $this->belongsTo('Model','model_id');
|
||||
@@ -155,13 +135,13 @@ class Asset extends Elegant
|
||||
/**
|
||||
* Get the license seat information
|
||||
**/
|
||||
public function licenses()
|
||||
public function licenses()
|
||||
{
|
||||
return $this->belongsToMany('License', 'license_seats', 'asset_id', 'license_id');
|
||||
|
||||
}
|
||||
|
||||
public function licenseseats()
|
||||
public function licenseseats()
|
||||
{
|
||||
return $this->hasMany('LicenseSeat', 'asset_id');
|
||||
}
|
||||
@@ -198,9 +178,15 @@ class Asset extends Elegant
|
||||
/**
|
||||
* Get total assets
|
||||
*/
|
||||
public static function autoincrement_asset()
|
||||
public static function autoincrement_asset()
|
||||
{
|
||||
$settings = Setting::getSettings();
|
||||
|
||||
if (isset($asset_tag->id)) {
|
||||
$asset_id = $asset_tag->id;
|
||||
} else {
|
||||
$asset_id = 1;
|
||||
}
|
||||
if ($settings->auto_increment_assets == '1') {
|
||||
$asset_tag = DB::table('assets')
|
||||
->where('physical', '=', '1')
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
class Depreciable extends Elegant
|
||||
{
|
||||
/**
|
||||
* Depreciation Relation, and associated helper methods
|
||||
*/
|
||||
|
||||
//REQUIRES a purchase_date field
|
||||
// and a purchase_cost field
|
||||
|
||||
//REQUIRES a get_depreciation method,
|
||||
//which will return the deprecation.
|
||||
//this is needed because assets get
|
||||
//their depreciation from a model,
|
||||
//whereas licenses have deprecations
|
||||
//directly associated with them.
|
||||
|
||||
//assets will override the following
|
||||
//two methods in order to inherit from
|
||||
//their model instead of directly (like
|
||||
//here)
|
||||
|
||||
public function depreciation()
|
||||
{
|
||||
return $this->belongsTo('Depreciation','depreciation_id');
|
||||
}
|
||||
|
||||
public function get_depreciation()
|
||||
{
|
||||
return $this->depreciation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $purchase_cost
|
||||
* @param $purchase_date1
|
||||
* @return float|int
|
||||
*/
|
||||
|
||||
public function getDepreciatedValue()
|
||||
{
|
||||
if (!$this->get_depreciation()) { // will never happen
|
||||
return $this->purchase_cost;
|
||||
}
|
||||
|
||||
if ($this->get_depreciation()->months <= 0) {
|
||||
return $this->purchase_cost;
|
||||
}
|
||||
|
||||
// fraction of value left
|
||||
$months_remaining = $this->time_until_depreciated()->m + $this->time_until_depreciated()->y; //UGlY
|
||||
$current_value = round(($months_remaining/ $this->get_depreciation()->months) * $this->purchase_cost, 2);
|
||||
|
||||
if ($current_value < 0) {
|
||||
$current_value = 0;
|
||||
}
|
||||
return $current_value;
|
||||
}
|
||||
|
||||
public function time_until_depreciated()
|
||||
{
|
||||
// @link http://www.php.net/manual/en/class.datetime.php
|
||||
$d1 = new DateTime();
|
||||
$d2 = $this->depreciated_date();
|
||||
|
||||
// @link http://www.php.net/manual/en/class.dateinterval.php
|
||||
$interval = $d1->diff($d2);
|
||||
if(!$interval->invert) {
|
||||
return $interval;
|
||||
} else {
|
||||
return new DateInterval("PT0S"); //null interval (zero seconds from now)
|
||||
}
|
||||
}
|
||||
|
||||
public function depreciated_date()
|
||||
{
|
||||
$date = date_create($this->purchase_date);
|
||||
date_add($date, date_interval_create_from_date_string($this->get_depreciation()->months . ' months'));
|
||||
return $date; //date_format($date, 'Y-m-d'); //don't bake-in format, for internationalization
|
||||
}
|
||||
}
|
||||
@@ -12,4 +12,9 @@ class Depreciation extends Elegant
|
||||
{
|
||||
return $this->hasMany('Model', 'depreciation_id')->count();
|
||||
}
|
||||
|
||||
public function has_licenses()
|
||||
{
|
||||
return $this->hasMany('License','depreciation_id')->count();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,36 +30,4 @@ class Elegant extends Eloquent
|
||||
{
|
||||
return str_replace("{id}", $id, $this->rules);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $depreciation_id
|
||||
* @param $purchase_cost
|
||||
* @param $purchase_date1
|
||||
* @return float|int
|
||||
*/
|
||||
protected function getCurrentValue($depreciation_id, $purchase_cost, $purchase_date1)
|
||||
{
|
||||
if (!$depreciation_id) {
|
||||
return $purchase_cost;
|
||||
}
|
||||
|
||||
$depreciation_term = Depreciation::find($depreciation_id)->months;
|
||||
if ($depreciation_term <= 0) {
|
||||
return $purchase_cost;
|
||||
}
|
||||
|
||||
$purchase_date = strtotime($purchase_date1);
|
||||
|
||||
$todaymonthnumber = date("Y") * 12 + (date("m") - 1); //calculate the month number for today as YEAR*12 + (months-1) - number of months since January year 0
|
||||
$purchasemonthnumber = date("Y", $purchase_date) * 12 + (date("m", $purchase_date) - 1); //purchase date calculated similarly
|
||||
$diff_months = $todaymonthnumber - $purchasemonthnumber;
|
||||
|
||||
// fraction of value left
|
||||
$current_value = round((($depreciation_term - $diff_months) / ($depreciation_term)) * $purchase_cost, 2);
|
||||
|
||||
if ($current_value < 0) {
|
||||
$current_value = 0;
|
||||
}
|
||||
return $current_value;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-42
@@ -1,11 +1,11 @@
|
||||
<?php
|
||||
|
||||
class License extends Elegant
|
||||
class License extends Depreciable
|
||||
{
|
||||
use SoftDeletingTrait;
|
||||
protected $dates = ['deleted_at'];
|
||||
|
||||
public $timestamps = true;
|
||||
public $timestamps = true;
|
||||
|
||||
protected $guarded = 'id';
|
||||
protected $table = 'licenses';
|
||||
@@ -155,44 +155,4 @@ class License extends Elegant
|
||||
{
|
||||
return $this->belongsTo('Supplier','supplier_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get depreciation class
|
||||
*/
|
||||
public function depreciation()
|
||||
{
|
||||
return $this->belongsTo('Depreciation','depreciation_id');
|
||||
}
|
||||
|
||||
public function months_until_depreciated()
|
||||
{
|
||||
$today = date("Y-m-d");
|
||||
|
||||
// @link http://www.php.net/manual/en/class.datetime.php
|
||||
$d1 = new DateTime($today);
|
||||
$d2 = new DateTime($this->depreciated_date());
|
||||
|
||||
// @link http://www.php.net/manual/en/class.dateinterval.php
|
||||
$interval = $d1->diff($d2);
|
||||
return $interval;
|
||||
}
|
||||
|
||||
public function depreciated_date()
|
||||
{
|
||||
$date = date_create($this->purchase_date);
|
||||
date_add($date, date_interval_create_from_date_string($this->depreciation->months . ' months'));
|
||||
return date_format($date, 'Y-m-d');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle depreciation
|
||||
*/
|
||||
public function depreciate()
|
||||
{
|
||||
return $this->getCurrentValue(
|
||||
License::find($this->license_id)->depreciation_id,
|
||||
$this->purchase_cost,
|
||||
$this->purchase_date
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,11 +8,11 @@ class Location extends Elegant
|
||||
protected $rules = array(
|
||||
'name' => 'required|alpha_space|min:3|max:255|unique:locations,name,{id}',
|
||||
'city' => 'required|alpha_space|min:3|max:255',
|
||||
'state' => 'required|alpha_space|min:2|max:32',
|
||||
'state' => 'alpha_space|min:2|max:32',
|
||||
'country' => 'required|alpha_space|min:2|max:2|max:2',
|
||||
'address' => 'required|alpha_space|min:5|max:80',
|
||||
'address2' => 'alpha_space|min:5|max:80',
|
||||
'zip' => 'alpha_dash|min:3|max:10',
|
||||
'zip' => 'alpha_space|min:3|max:10',
|
||||
);
|
||||
|
||||
public function has_users()
|
||||
|
||||
+14
-1
@@ -33,7 +33,6 @@ Route::group(array('prefix' => 'hardware', 'namespace' => 'Controllers\Admin', '
|
||||
'uses' => 'AssetsController@getEdit')
|
||||
);
|
||||
|
||||
Route::post('{assetId}/edit', 'AssetsController@postEdit');
|
||||
Route::get('{assetId}/clone', array('as' => 'clone/hardware', 'uses' => 'AssetsController@getClone'));
|
||||
Route::post('{assetId}/clone', 'AssetsController@postCreate');
|
||||
Route::get('{assetId}/delete', array('as' => 'delete/hardware', 'uses' => 'AssetsController@getDelete'));
|
||||
@@ -44,6 +43,20 @@ Route::group(array('prefix' => 'hardware', 'namespace' => 'Controllers\Admin', '
|
||||
Route::get('{assetId}/view', array('as' => 'view/hardware', 'uses' => 'AssetsController@getView'));
|
||||
Route::get('{assetId}/qr_code', array('as' => 'qr_code/hardware', 'uses' => 'AssetsController@getQrCode'));
|
||||
Route::get('{assetId}/restore', array('as' => 'restore/hardware', 'uses' => 'AssetsController@getRestore'));
|
||||
Route::post('{assetId}/upload', array('as' => 'upload/asset', 'uses' => 'AssetsController@postUpload'));
|
||||
Route::get('{assetId}/deletefile/{fileId}', array('as' => 'delete/assetfile', 'uses' => 'AssetsController@getDeleteFile'));
|
||||
Route::get('{assetId}/showfile/{fileId}', array('as' => 'show/assetfile', 'uses' => 'AssetsController@displayFile'));
|
||||
Route::post('{assetId}/edit', 'AssetsController@postEdit');
|
||||
|
||||
Route::post('bulkedit',
|
||||
array('as' => 'hardware/bulkedit',
|
||||
'uses' => 'AssetsController@postBulkEdit'));
|
||||
Route::post('bulksave',
|
||||
array('as' => 'hardware/bulksave',
|
||||
'uses' => 'AssetsController@postBulkSave'));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Asset Model Management
|
||||
|
||||
Executable
+83
@@ -0,0 +1,83 @@
|
||||
@extends('backend/layouts/default')
|
||||
|
||||
{{-- Page title --}}
|
||||
@section('title')
|
||||
@lang('admin/hardware/form.update') ::
|
||||
|
||||
@parent
|
||||
@stop
|
||||
|
||||
{{-- Page content --}}
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="row header">
|
||||
<div class="col-md-12">
|
||||
<a href="{{ URL::previous() }}" class="btn-flat gray pull-right right"><i class="icon-circle-arrow-left icon-white"></i> @lang('general.back')</a>
|
||||
<h3>
|
||||
|
||||
@lang('admin/hardware/form.bulk_update')
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row form-wrapper">
|
||||
<!-- left column -->
|
||||
<div class="col-md-12 column">
|
||||
<p>@lang('admin/hardware/form.bulk_update_help')</p>
|
||||
<p style="color: red"><strong><big>@lang('admin/hardware/form.bulk_update_warn', ['asset_count' => count($assets)])</big></strong></p>
|
||||
|
||||
|
||||
<form class="form-horizontal" method="post" action="{{ route('hardware/bulksave') }}" autocomplete="off" role="form">
|
||||
|
||||
|
||||
<!-- CSRF Token -->
|
||||
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
|
||||
|
||||
|
||||
<!-- Purchase Date -->
|
||||
<div class="form-group {{ $errors->has('purchase_date') ? ' has-error' : '' }}">
|
||||
<label for="purchase_date" class="col-md-2 control-label">@lang('admin/hardware/form.date')</label>
|
||||
<div class="input-group col-md-3">
|
||||
<input type="date" class="datepicker form-control" data-date-format="yyyy-mm-dd" placeholder="Select Date" name="purchase_date" id="purchase_date" value="{{{ Input::old('purchase_date') }}}">
|
||||
<span class="input-group-addon"><i class="icon-calendar"></i></span>
|
||||
{{ $errors->first('purchase_date', '<span class="alert-msg"><i class="icon-remove-sign"></i> :message</span>') }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Status -->
|
||||
<div class="form-group {{ $errors->has('status_id') ? ' has-error' : '' }}">
|
||||
<label for="status_id" class="col-md-2 control-label">@lang('admin/hardware/form.status') <i class='icon-asterisk'></i></label>
|
||||
<div class="col-md-7">
|
||||
{{ Form::select('status_id', $statuslabel_list , Input::old('status_id'), array('class'=>'select2', 'style'=>'width:350px')) }}
|
||||
{{ $errors->first('status_id', '<span class="alert-msg"><i class="icon-remove-sign"></i> :message</span>') }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Default Location -->
|
||||
<div class="form-group {{ $errors->has('status_id') ? ' has-error' : '' }}">
|
||||
<label for="status_id" class="col-md-2 control-label">@lang('admin/hardware/form.default_location')</label>
|
||||
<div class="col-md-7">
|
||||
{{ Form::select('rtd_location_id', $location_list , Input::old('rtd_location_id'), array('class'=>'select2', 'style'=>'width:350px')) }}
|
||||
{{ $errors->first('status_id', '<span class="alert-msg"><i class="icon-remove-sign"></i> :message</span>') }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@foreach ($assets as $key => $value)
|
||||
<input type="hidden" name="bulk_edit[{{{ $key }}}]" value="1">
|
||||
@endforeach
|
||||
|
||||
|
||||
<!-- Form actions -->
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label"></label>
|
||||
<div class="col-md-7">
|
||||
<a class="btn btn-link" href="{{ URL::previous() }}">@lang('button.cancel')</a>
|
||||
<button type="submit" class="btn btn-success"><i class="icon-ok icon-white"></i> @lang('general.save')</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
@@ -90,7 +90,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (isset($asset->model)) && ($asset->model->show_mac_address != 0)
|
||||
|
||||
@if ($asset->model && $asset->model->show_mac_address == '1')
|
||||
<!-- MAC Address -->
|
||||
<div class="form-group {{ $errors->has('mac_address') ? ' has-error' : '' }}">
|
||||
<label for="mac_address" class="col-md-2 control-label">@lang('admin/hardware/form.mac_address')</label>
|
||||
|
||||
@@ -42,39 +42,56 @@
|
||||
|
||||
<div class="row form-wrapper">
|
||||
|
||||
<?php $spanrows = 8; ?>
|
||||
|
||||
|
||||
@if ($assets->count() > 0)
|
||||
|
||||
|
||||
{{ Form::open([
|
||||
'method' => 'POST',
|
||||
'route' => ['hardware/bulkedit'],
|
||||
'class' => 'form-horizontal' ]) }}
|
||||
|
||||
|
||||
|
||||
<div class="table-responsive">
|
||||
<table id="example">
|
||||
|
||||
<thead>
|
||||
<tr role="row">
|
||||
<th class="col-md-1" bSortable="false"></th>
|
||||
<th class="col-md-1" bSortable="true">@lang('admin/hardware/table.asset_tag')</th>
|
||||
<th class="col-md-3" bSortable="true">@lang('admin/hardware/table.asset_model')</th>
|
||||
@if (Setting::getSettings()->display_asset_name)
|
||||
<th class="col-md-3" bSortable="true">@lang('general.name')</th>
|
||||
<?php $spanrows++; ?>
|
||||
@endif
|
||||
<th class="col-md-2" bSortable="true">@lang('admin/hardware/table.serial')</th>
|
||||
|
||||
<th class="col-md-2" bSortable="true">@lang('general.status')</th>
|
||||
|
||||
<th class="col-md-2" bSortable="true">@lang('admin/hardware/table.location')</th>
|
||||
@if (Input::get('Deployed') && Setting::getSettings()->display_checkout_date)
|
||||
<th class="col-md-2" bSortable="true">@lang('admin/hardware/table.checkout_date')</th>
|
||||
<?php $spanrows++; ?>
|
||||
@endif
|
||||
@if (Setting::getSettings()->display_eol)
|
||||
<th class="col-md-2">@lang('admin/hardware/table.eol')</th>
|
||||
<?php $spanrows++; ?>
|
||||
@endif
|
||||
<th class="col-md-1">@lang('admin/hardware/table.change')</th>
|
||||
<th class="col-md-2 actions" bSortable="false">@lang('table.actions')</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="{{{ $spanrows }}}"><button class="btn btn-default" id="bulkEdit" disabled>Bulk Edit</button></td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
<tbody>
|
||||
|
||||
@foreach ($assets as $asset)
|
||||
<tr>
|
||||
<td><input type="checkbox" name="edit_asset[{{ $asset->id }}]" class="one_required"></td>
|
||||
<td><a href="{{ route('view/hardware', $asset->id) }}">{{{ $asset->asset_tag }}}</a></td>
|
||||
<td><a href="{{ route('view/model', $asset->model->id) }}">{{{ $asset->model->name }}}</a></td>
|
||||
|
||||
@@ -160,7 +177,25 @@
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
{{ Form::close() }}
|
||||
|
||||
</div>
|
||||
<script>
|
||||
$(function() {
|
||||
|
||||
$('input.one_required').change(function() {
|
||||
|
||||
var check_checked = $('input.one_required:checked').length;
|
||||
console.warn(check_checked);
|
||||
if (check_checked > 0) {
|
||||
$('#bulkEdit').removeAttr('disabled');
|
||||
}
|
||||
else {
|
||||
$('#bulkEdit').attr('disabled', 'disabled');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@else
|
||||
<div class="col-md-9">
|
||||
<div class="alert alert-info alert-block">
|
||||
|
||||
@@ -119,13 +119,13 @@
|
||||
@lang('admin/hardware/form.months')
|
||||
)</div>
|
||||
<div class="col-md-12" style="padding-bottom: 5px;"><strong>@lang('admin/hardware/form.fully_depreciated'): </strong>
|
||||
{{{ $asset->months_until_depreciated()->m }}}
|
||||
@lang('admin/hardware/form.months')
|
||||
@if ($asset->months_until_depreciated()->y > 0)
|
||||
, {{{ $asset->months_until_depreciated()->y }}}
|
||||
@lang('admin/hardware/form.years')
|
||||
@if ($asset->time_until_depreciated()->y > 0)
|
||||
{{{ $asset->time_until_depreciated()->y }}}
|
||||
@lang('admin/hardware/form.years'),
|
||||
@endif
|
||||
({{{ $asset->depreciated_date() }}})
|
||||
{{{ $asset->time_until_depreciated()->m }}}
|
||||
@lang('admin/hardware/form.months')
|
||||
({{{ $asset->depreciated_date()->format('Y-m-d') }}})
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@@ -187,6 +187,60 @@
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
<div class="col-md-12">
|
||||
|
||||
|
||||
<h6>@lang('general.file_uploads') [ <a href="#" data-toggle="modal" data-target="#uploadFileModal">@lang('button.add')</a> ]</h6>
|
||||
|
||||
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-md-5">@lang('general.notes')</th>
|
||||
<th class="col-md-5"><span class="line"></span>@lang('general.file_name')</th>
|
||||
<th class="col-md-2"></th>
|
||||
<th class="col-md-2"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@if (count($asset->uploads) > 0)
|
||||
@foreach ($asset->uploads as $file)
|
||||
<tr>
|
||||
<td>
|
||||
@if ($file->note) {{{ $file->note }}}
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
{{{ $file->filename }}}
|
||||
</td>
|
||||
<td>
|
||||
@if ($file->filename)
|
||||
<a href="{{ route('show/assetfile', [$asset->id, $file->id]) }}" class="btn btn-default">@lang('general.download')</a>
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
<a class="btn delete-asset btn-danger" href="{{ route('delete/assetfile', [$asset->id, $file->id]) }}"><i class="icon-trash icon-white"></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
@else
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
@lang('general.no_results')
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@endif
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- checked out assets table -->
|
||||
|
||||
@@ -203,7 +257,7 @@
|
||||
<tbody>
|
||||
@if (count($asset->assetlog) > 0)
|
||||
@foreach ($asset->assetlog as $log)
|
||||
@if ((isset($log->checkedout_to)) && ($log->checkedout_to!=0))
|
||||
|
||||
<tr>
|
||||
<td>{{{ $log->created_at }}}</td>
|
||||
<td>
|
||||
@@ -215,13 +269,13 @@
|
||||
<td>
|
||||
@if ((isset($log->checkedout_to)) && ($log->checkedout_to!=0) && ($log->checkedout_to!=''))
|
||||
|
||||
@if ($log->userlog->deleted_at=='')
|
||||
<a href="{{ route('view/user', $log->checkedout_to) }}">
|
||||
{{{ $log->userlog->fullName() }}}
|
||||
</a>
|
||||
@else
|
||||
<del>{{{ $log->userlog->fullName() }}}</del>
|
||||
@endif
|
||||
@if ($log->userlog->deleted_at=='')
|
||||
<a href="{{ route('view/user', $log->checkedout_to) }}">
|
||||
{{{ $log->userlog->fullName() }}}
|
||||
</a>
|
||||
@else
|
||||
<del>{{{ $log->userlog->fullName() }}}</del>
|
||||
@endif
|
||||
|
||||
@endif
|
||||
</td>
|
||||
@@ -230,7 +284,7 @@
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
|
||||
@endforeach
|
||||
@endif
|
||||
<tr>
|
||||
@@ -341,4 +395,43 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="uploadFileModal" tabindex="-1" role="dialog" aria-labelledby="uploadFileModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title" id="uploadFileModalLabel">Upload File</h4>
|
||||
</div>
|
||||
{{ Form::open([
|
||||
'method' => 'POST',
|
||||
'route' => ['upload/asset', $asset->id],
|
||||
'files' => true, 'class' => 'form-horizontal' ]) }}
|
||||
<div class="modal-body">
|
||||
|
||||
<p>Allowed filetypes are png, gif, jpg, doc, docx, pdf, and txt.</p>
|
||||
|
||||
<div class="form-group col-md-12">
|
||||
<div class="input-group col-md-12">
|
||||
<input class="col-md-12 form-control" type="text" name="notes" id="notes" placeholder="Notes">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-md-12">
|
||||
<div class="input-group col-md-12">
|
||||
{{ Form::file('assetfile[]', ['multiple' => 'multiple']) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">@lang('button.cancel')</button>
|
||||
<button type="submit" class="btn btn-primary">@lang('button.upload')</button>
|
||||
</div>
|
||||
{{ Form::close() }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@stop
|
||||
|
||||
@@ -41,14 +41,14 @@
|
||||
<link rel="stylesheet" href="{{ asset('assets/css/compiled/user-profile.css') }}" type="text/css" media="screen" />
|
||||
<link rel="stylesheet" href="{{ asset('assets/css/compiled/form-showcase.css') }}" type="text/css" media="screen" />
|
||||
<link rel="stylesheet" href="{{ asset('assets/css/lib/jquery.dataTables.css') }}" type="text/css" media="screen" />
|
||||
<link rel="stylesheet" href="//cdn.datatables.net/responsive/1.0.2/css/dataTables.responsive.css" type="text/css" media="screen" />
|
||||
<link rel="stylesheet" href="{{ asset('assets/css/compiled/dataTables.responsive.css') }}" type="text/css" media="screen" />
|
||||
|
||||
|
||||
|
||||
<!-- global header javascripts -->
|
||||
<script src="//code.jquery.com/jquery-latest.js"></script>
|
||||
<script src="//cdn.datatables.net/1.10.3/js/jquery.dataTables.min.js"></script>
|
||||
<script src="//cdn.datatables.net/responsive/1.0.2/js/dataTables.responsive.js"></script>
|
||||
<script src="{{ asset('assets/js/jquery-latest.js') }}"></script>
|
||||
<script src="{{ asset('assets/js/jquery.dataTables.min.js') }}"></script>
|
||||
<script src="{{ asset('assets/js/dataTables.responsive.js') }}"></script>
|
||||
|
||||
<script>
|
||||
window.snipeit = {
|
||||
@@ -60,13 +60,15 @@
|
||||
|
||||
|
||||
|
||||
@if (Setting::getSettings()->load_remote=='1')
|
||||
<!-- open sans font -->
|
||||
<link href='//fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/css'>
|
||||
@endif
|
||||
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<script src="{{ asset('assets/js/html5.js') }}"></script>
|
||||
<![endif]-->
|
||||
|
||||
|
||||
<style>
|
||||
|
||||
@section('styles')
|
||||
@@ -285,6 +287,9 @@
|
||||
</ul>
|
||||
</li>
|
||||
@endif
|
||||
|
||||
<li><a href="{{ route('requestable-assets') }}" {{{ (Request::is('view-requestable*') ? ' class="active"' : '') }}} >@lang('admin/hardware/general.requestable') </a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<!-- end sidebar -->
|
||||
@@ -365,7 +370,7 @@
|
||||
<a target="_blank" href="http://docs.snipeitapp.com/">Documentation</a> |
|
||||
<a href="https://crowdin.com/project/snipe-it">Help Translate It! </a> |
|
||||
<a target="_blank" href="https://github.com/snipe/snipe-it/issues?state=open">Report a Bug</a>
|
||||
(v1.2.4)</p>
|
||||
(v1.2.5)</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -73,18 +73,18 @@
|
||||
|
||||
<div class="col-md-6" style="padding-bottom: 5px">
|
||||
<strong>@lang('admin/hardware/form.depreciates_on'): </strong>
|
||||
{{{ $license->depreciated_date() }}}
|
||||
{{{ $license->depreciated_date()->format("Y-m-d") }}}
|
||||
</div>
|
||||
|
||||
<div class="col-md-6" style="padding-bottom: 5px">
|
||||
<strong>@lang('admin/hardware/form.fully_depreciated'): </strong>
|
||||
{{{ $license->months_until_depreciated()->m }}}
|
||||
@if ($license->time_until_depreciated()->y > 0)
|
||||
{{{ $license->time_until_depreciated()->y }}}
|
||||
@lang('admin/hardware/form.years'),
|
||||
@endif
|
||||
{{{ $license->time_until_depreciated()->m }}}
|
||||
@lang('admin/hardware/form.months')
|
||||
|
||||
@if ($license->months_until_depreciated()->y > 0)
|
||||
, {{{ $license->months_until_depreciated()->y }}}
|
||||
@lang('admin/hardware/form.years')
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@@ -191,7 +191,7 @@
|
||||
@else
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
No files uploaded
|
||||
@lang('general.no_results')
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
<!-- City -->
|
||||
<div class="form-group {{ $errors->has('state') ? ' has-error' : '' }}">
|
||||
<label for="state" class="col-md-2 control-label">@lang('admin/locations/table.state')
|
||||
<i class='icon-asterisk'></i></label>
|
||||
|
||||
</label>
|
||||
<div class="col-md-12">
|
||||
<div class="col-xs-2">
|
||||
|
||||
@@ -44,7 +44,8 @@
|
||||
<tr role="row">
|
||||
<th class="col-md-3">@lang('general.name')</th>
|
||||
<th class="col-md-3">@lang('general.asset_tag')</th>
|
||||
<th class="col-md-3">@lang('general.user')</th>
|
||||
<th class="col-md-3">@lang('admin/hardware/table.serial')</th>
|
||||
<th class="col-md-3">@lang('general.user')</th>
|
||||
<th class="col-md-2">@lang('table.actions')</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -55,6 +56,13 @@
|
||||
<td><a href="{{ route('view/hardware', $modelassets->id) }}">{{{ $modelassets->name }}}</a></td>
|
||||
<td><a href="{{ route('view/hardware', $modelassets->id) }}">{{{ $modelassets->asset_tag }}}</a></td>
|
||||
<td>
|
||||
@if ($modelassets->serial)
|
||||
|
||||
{{{ $modelassets->serial }}}
|
||||
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
@if ($modelassets->assigneduser)
|
||||
<a href="{{ route('view/user', $modelassets->assigned_to) }}">
|
||||
{{{ $modelassets->assigneduser->fullName() }}}
|
||||
|
||||
@@ -85,10 +85,15 @@
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
@if ($asset->assigned_to != 0)
|
||||
<a href="{{ route('view/user', $asset->assigned_to) }}">
|
||||
{{{ $asset->assigneduser->fullName() }}}
|
||||
</a>
|
||||
@if ($asset->assigneduser)
|
||||
@if ($asset->assigneduser->deleted_at!='')
|
||||
<del>{{{ $asset->assigneduser->fullName() }}}</del>
|
||||
@else
|
||||
<a href="{{ route('view/user', $asset->assigned_to) }}">
|
||||
{{{ $asset->assigneduser->fullName() }}}
|
||||
</a>
|
||||
@endif
|
||||
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
|
||||
@@ -45,19 +45,29 @@
|
||||
|
||||
@foreach ($assets as $asset)
|
||||
<tr>
|
||||
<td>{{{ $asset->asset_tag }}}</td>
|
||||
<td>
|
||||
@if ($asset->deleted_at!='')
|
||||
<del>{{{ $asset->asset_tag }}}</del>
|
||||
@else
|
||||
{{{ $asset->asset_tag }}}
|
||||
@endif
|
||||
|
||||
</td>
|
||||
<td>{{{ $asset->model->name }}}</td>
|
||||
@if (Setting::getSettings()->display_asset_name)
|
||||
<td>{{{ $asset->name }}}</td>
|
||||
@endif
|
||||
<td>{{ $asset->serial }}</td>
|
||||
<td>
|
||||
@if (isset($asset->assigned_to))
|
||||
@if ($asset->assigned_to != 0)
|
||||
<a href="{{ route('view/user', $asset->assigned_to) }}">
|
||||
@if ($asset->assigneduser)
|
||||
@if ($asset->assigneduser->deleted_at!='')
|
||||
<del>{{{ $asset->assigneduser->fullName() }}}</del>
|
||||
@else
|
||||
<a href="{{ route('view/user', $asset->assigned_to) }}">
|
||||
{{{ $asset->assigneduser->fullName() }}}
|
||||
</a>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
@@ -79,9 +89,9 @@
|
||||
<td class="align-right">@lang('general.currency')
|
||||
{{{ number_format($asset->purchase_cost) }}}</td>
|
||||
<td class="align-right">@lang('general.currency')
|
||||
{{{ number_format($asset->depreciate()) }}}</td>
|
||||
{{{ number_format($asset->getDepreciatedValue()) }}}</td>
|
||||
<td class="align-right">@lang('general.currency')
|
||||
-{{{ number_format(($asset->purchase_cost - $asset->depreciate())) }}}</td>
|
||||
-{{{ number_format(($asset->purchase_cost - $asset->getDepreciatedValue())) }}}</td>
|
||||
@else
|
||||
<td></td>
|
||||
<td></td>
|
||||
|
||||
@@ -86,6 +86,12 @@ padding: 0px 20px;
|
||||
@lang('admin/settings/general.display_checkout_date')
|
||||
</label>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
{{ Form::checkbox('load_remote', '1', Input::old('load_remote', $setting->load_remote)) }}
|
||||
@lang('admin/settings/general.load_remote')
|
||||
</label>
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
<div class="checkbox">
|
||||
@@ -94,6 +100,9 @@ padding: 0px 20px;
|
||||
@lang('admin/settings/general.auto_increment_assets')
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="form-group {{ $errors->has('auto_increment_prefix') ? 'error' : '' }}">
|
||||
{{ Form::label('auto_increment_prefix', Lang::get('admin/settings/general.auto_increment_prefix')) }}
|
||||
|
||||
@@ -71,6 +71,16 @@
|
||||
<td>@lang('general.no')</td>
|
||||
@endif
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>@lang('admin/settings/general.load_remote')</td>
|
||||
|
||||
@if ($setting->load_remote == 1)
|
||||
<td>@lang('general.yes')</td>
|
||||
@else
|
||||
<td>@lang('general.no')</td>
|
||||
@endif
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>@lang('admin/settings/general.auto_increment_prefix')</td>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@extends('frontend/layouts/default')
|
||||
@extends('backend/layouts/default')
|
||||
|
||||
{{-- Page title --}}
|
||||
@section('title')
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@extends('frontend/layouts/default')
|
||||
@extends('backend/layouts/default')
|
||||
|
||||
{{-- Page title --}}
|
||||
@section('title')
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@extends('frontend/layouts/default')
|
||||
@extends('backend/layouts/default')
|
||||
|
||||
{{-- Page title --}}
|
||||
@section('title')
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@extends('frontend/layouts/default')
|
||||
@extends('backend/layouts/default')
|
||||
|
||||
@section('title0')
|
||||
@lang('admin/hardware/general.requestable')
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@extends('frontend/layouts/default')
|
||||
@extends('backend/layouts/default')
|
||||
|
||||
{{-- Page title --}}
|
||||
@section('title')
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@extends('frontend/layouts/default')
|
||||
@extends('backend/layouts/default')
|
||||
|
||||
{{-- Page title --}}
|
||||
@section('title')
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@extends('frontend/layouts/default')
|
||||
@extends('backend/layouts/default')
|
||||
|
||||
{{-- Page title --}}
|
||||
@section('title')
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@extends('frontend/layouts/default')
|
||||
@extends('backend/layouts/default')
|
||||
|
||||
{{-- Page title --}}
|
||||
@section('title')
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@extends('frontend/layouts/default')
|
||||
@extends('backend/layouts/default')
|
||||
|
||||
{{-- Page title --}}
|
||||
@section('title')
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@extends('frontend/layouts/default')
|
||||
@extends('backend/layouts/default')
|
||||
|
||||
{{-- Page content --}}
|
||||
@section('content')
|
||||
|
||||
@@ -1,228 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
|
||||
<!-- Basic Page Needs
|
||||
================================================== -->
|
||||
<meta charset="utf-8" />
|
||||
<title>
|
||||
@section('title')
|
||||
{{{ Setting::getSettings()->site_name }}}
|
||||
@show
|
||||
</title>
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
|
||||
|
||||
<!-- bootstrap -->
|
||||
<link href="{{ asset('assets/css/bootstrap/bootstrap.css') }}" rel="stylesheet" />
|
||||
<link href="{{ asset('assets/css/bootstrap/bootstrap-overrides.css') }}" type="text/css" rel="stylesheet" />
|
||||
|
||||
|
||||
|
||||
<!-- libraries -->
|
||||
<link href="{{ asset('assets/css/lib/uniform.default.css') }}" rel="stylesheet" type="text/css" />
|
||||
<link href="{{ asset('assets/css/lib/select2.css') }}" type="text/css" rel="stylesheet">
|
||||
<link href="{{ asset('assets/css/lib/bootstrap.datepicker.css') }}" type="text/css" rel="stylesheet">
|
||||
<link href="{{ asset('assets/css/lib/font-awesome.css') }}" type="text/css" rel="stylesheet" />
|
||||
|
||||
<!-- global styles -->
|
||||
<link rel="stylesheet" type="text/css" href="{{ asset('assets/css/compiled/layout.css') }}">
|
||||
<link rel="stylesheet" type="text/css" href="{{ asset('assets/css/compiled/elements.css') }}">
|
||||
<link rel="stylesheet" type="text/css" href="{{ asset('assets/css/compiled/icons.css') }}">
|
||||
|
||||
|
||||
<!-- this page specific styles -->
|
||||
<link rel="stylesheet" href="{{ asset('assets/css/compiled/index.css') }}" type="text/css" media="screen" />
|
||||
<link rel="stylesheet" href="{{ asset('assets/css/compiled/user-list.css') }}" type="text/css" media="screen" />
|
||||
<link rel="stylesheet" href="{{ asset('assets/css/compiled/user-profile.css') }}" type="text/css" media="screen" />
|
||||
<link rel="stylesheet" href="{{ asset('assets/css/compiled/form-showcase.css') }}" type="text/css" media="screen" />
|
||||
<link rel="stylesheet" href="{{ asset('assets/css/lib/jquery.dataTables.css') }}" type="text/css" media="screen" />
|
||||
<link rel="stylesheet" href="//cdn.datatables.net/responsive/1.0.2/css/dataTables.responsive.css" type="text/css" media="screen" />
|
||||
|
||||
|
||||
|
||||
<!-- global header javascripts -->
|
||||
<script src="//code.jquery.com/jquery-latest.js"></script>
|
||||
<script src="//cdn.datatables.net/1.10.3/js/jquery.dataTables.min.js"></script>
|
||||
<script src="//cdn.datatables.net/responsive/1.0.2/js/dataTables.responsive.js"></script>
|
||||
|
||||
<script>
|
||||
window.snipeit = {
|
||||
settings: {
|
||||
"per_page": {{{ Setting::getSettings()->per_page }}}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<!-- open sans font -->
|
||||
<link href='//fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/css'>
|
||||
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<style>
|
||||
|
||||
@section('styles')
|
||||
h3 {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
@show
|
||||
|
||||
</style>
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<!-- navbar -->
|
||||
|
||||
|
||||
<!-- navbar -->
|
||||
<header class="navbar navbar-inverse" role="banner">
|
||||
|
||||
<div class="navbar navbar-inverse">
|
||||
<div class="navbar-inner navbar-inverse">
|
||||
<div class="navbar-header">
|
||||
<button class="navbar-toggle" type="button" data-toggle="collapse" id="menu-toggler">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="/">{{{ Setting::getSettings()->site_name }}}</a>
|
||||
</div>
|
||||
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
@if (Sentry::check())
|
||||
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
{{{ Lang::get('general.welcome', array('name' => Sentry::getUser()->first_name)) }}}
|
||||
<b class="caret"></b>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li{{{ (Request::is('account/profile') ? ' class="active"' : '') }}}>
|
||||
<a href="{{ route('view-assets') }}">
|
||||
<i class="icon-check"></i> @lang('general.viewassets')
|
||||
</a>
|
||||
<a href="{{ route('profile') }}">
|
||||
<i class="icon-user"></i> @lang('general.editprofile')
|
||||
</a>
|
||||
<a href="{{ route('change-password') }}">
|
||||
<i class="icon-lock"></i> @lang('general.changepassword')
|
||||
</a>
|
||||
<a href="{{ route('change-email') }}">
|
||||
<i class="icon-envelope"></i> @lang('general.changeemail')
|
||||
</a>
|
||||
</li>
|
||||
<li class="divider"></li>
|
||||
<li>
|
||||
<a href="{{ route('logout') }}">
|
||||
<i class="icon-off"></i>
|
||||
@lang('general.logout')
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
@else
|
||||
<li {{{ (Request::is('auth/signin') ? 'class="active"' : '') }}}><a href="{{ route('signin') }}">@lang('general.sign_in')</a></li>
|
||||
@endif
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<!-- end navbar -->
|
||||
|
||||
@if (Sentry::check())
|
||||
<!-- sidebar -->
|
||||
<div id="sidebar-nav">
|
||||
<ul id="dashboard-menu">
|
||||
|
||||
|
||||
<li><a href="{{ route('requestable-assets') }}" {{{ (Request::is('view-requestable*') ? ' class="active"' : '') }}} >@lang('admin/hardware/general.requestable')</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<!-- end sidebar -->
|
||||
|
||||
@endif
|
||||
|
||||
|
||||
<!-- main container -->
|
||||
<div class="content">
|
||||
<div id="pad-wrapper">
|
||||
|
||||
<!-- Notifications -->
|
||||
@include('frontend/notifications')
|
||||
|
||||
<!-- Content -->
|
||||
@yield('content')
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<div class="col-md-2">
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div class="col-md-9">
|
||||
<div class="container">
|
||||
|
||||
<div class="muted credit" style="position:absolute;margin-top:1px;left:80px;margin-right:100px;">
|
||||
<a target="_blank" href="http://snipeitapp.com">Snipe IT</a> is a free open source
|
||||
project by <a target="_blank" href="http://twitter.com/snipeyhead">@snipeyhead</a>.</div>
|
||||
<div class="muted credit" style="position:absolute;margin-top:1px;right:80px;margin-left:100px;">
|
||||
<a target="_blank" href="https://github.com/snipe/snipe-it">Fork it</a> |
|
||||
<a target="_blank" href="http://docs.snipeitapp.com/">Documentation</a> |
|
||||
<a href="https://crowdin.com/project/snipe-it">Help Translate It! </a> |
|
||||
<a target="_blank" href="https://github.com/snipe/snipe-it/issues?state=open">Report a Bug</a>
|
||||
(v1.2.4)</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<!-- end main container -->
|
||||
|
||||
<div class="modal fade" id="dataConfirmModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h4 class="modal-title" id="myModalLabel"></h4>
|
||||
</div>
|
||||
<div class="modal-body"></div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button><a class="btn btn-danger" id="dataConfirmOK">@lang('general.yes')</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- scripts -->
|
||||
<script src="{{ asset('assets/js/bootstrap.min.js') }}"></script>
|
||||
<script src="{{ asset('assets/js/jquery.knob.js') }}"></script>
|
||||
<script src="{{ asset('assets/js/select2.min.js') }}"></script>
|
||||
<script src="{{ asset('assets/js/jquery.uniform.min.js') }}"></script>
|
||||
<script src="{{ asset('assets/js/bootstrap.datepicker.js') }}"></script>
|
||||
<script src="{{ asset('assets/js/theme.js') }}"></script>
|
||||
<script src="{{ asset('assets/js/snipeit.js') }}"></script>
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
+2
-1
@@ -26,7 +26,8 @@
|
||||
"intervention/image": "dev-master"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "*"
|
||||
"phpunit/phpunit": "*",
|
||||
"mockery/mockery": "0.9.*"
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
|
||||
Generated
+119
-53
@@ -4,7 +4,7 @@
|
||||
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "b2d1b48bc514e40f1a4ef04cd86aa86f",
|
||||
"hash": "4242b20dc02d70aa7d97a211ea1e58b8",
|
||||
"packages": [
|
||||
{
|
||||
"name": "bacon/bacon-qr-code",
|
||||
@@ -1194,12 +1194,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Seldaek/monolog.git",
|
||||
"reference": "7583a2b96b9fda7ece90e34a23cd46e4858b3352"
|
||||
"reference": "f05ed3a44a8e40533d4cf60a0669db6b1887b499"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/7583a2b96b9fda7ece90e34a23cd46e4858b3352",
|
||||
"reference": "7583a2b96b9fda7ece90e34a23cd46e4858b3352",
|
||||
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/f05ed3a44a8e40533d4cf60a0669db6b1887b499",
|
||||
"reference": "f05ed3a44a8e40533d4cf60a0669db6b1887b499",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1258,7 +1258,7 @@
|
||||
"logging",
|
||||
"psr-3"
|
||||
],
|
||||
"time": "2015-01-29 16:05:08"
|
||||
"time": "2015-02-11 14:20:33"
|
||||
},
|
||||
{
|
||||
"name": "nesbot/carbon",
|
||||
@@ -1756,12 +1756,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Config.git",
|
||||
"reference": "1624dd47e1f4dc89ae4e7ca4a0476325042f8e82"
|
||||
"reference": "a634f4e901f5d20696020980cae70d8d94c6193d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Config/zipball/1624dd47e1f4dc89ae4e7ca4a0476325042f8e82",
|
||||
"reference": "1624dd47e1f4dc89ae4e7ca4a0476325042f8e82",
|
||||
"url": "https://api.github.com/repos/symfony/Config/zipball/a634f4e901f5d20696020980cae70d8d94c6193d",
|
||||
"reference": "a634f4e901f5d20696020980cae70d8d94c6193d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1795,7 +1795,7 @@
|
||||
],
|
||||
"description": "Symfony Config Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2015-01-25 04:39:35"
|
||||
"time": "2015-02-11 07:17:51"
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
@@ -1804,12 +1804,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Console.git",
|
||||
"reference": "767a4be52d062d49bb0ef5f593f5f5d06b2f5ff3"
|
||||
"reference": "a43e750b4c74f3bdfca77c79c343033d35a6cd6e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Console/zipball/767a4be52d062d49bb0ef5f593f5f5d06b2f5ff3",
|
||||
"reference": "767a4be52d062d49bb0ef5f593f5f5d06b2f5ff3",
|
||||
"url": "https://api.github.com/repos/symfony/Console/zipball/a43e750b4c74f3bdfca77c79c343033d35a6cd6e",
|
||||
"reference": "a43e750b4c74f3bdfca77c79c343033d35a6cd6e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1850,7 +1850,7 @@
|
||||
],
|
||||
"description": "Symfony Console Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2015-02-05 06:31:40"
|
||||
"time": "2015-02-08 07:07:45"
|
||||
},
|
||||
{
|
||||
"name": "symfony/css-selector",
|
||||
@@ -2022,12 +2022,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/EventDispatcher.git",
|
||||
"reference": "e9298668dce8dd219d1ee2290c7f313954f1f984"
|
||||
"reference": "2dc33aff298b20ad099ac456034aebc5055f02fb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/e9298668dce8dd219d1ee2290c7f313954f1f984",
|
||||
"reference": "e9298668dce8dd219d1ee2290c7f313954f1f984",
|
||||
"url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/2dc33aff298b20ad099ac456034aebc5055f02fb",
|
||||
"reference": "2dc33aff298b20ad099ac456034aebc5055f02fb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2071,7 +2071,7 @@
|
||||
],
|
||||
"description": "Symfony EventDispatcher Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2015-02-05 06:58:17"
|
||||
"time": "2015-02-11 07:17:51"
|
||||
},
|
||||
{
|
||||
"name": "symfony/filesystem",
|
||||
@@ -2080,12 +2080,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Filesystem.git",
|
||||
"reference": "e681ca515e1e668a551b089177867e62e03d7d2d"
|
||||
"reference": "177e0a8e29fab3f0556f7a973b5a42935e42a4d7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Filesystem/zipball/e681ca515e1e668a551b089177867e62e03d7d2d",
|
||||
"reference": "e681ca515e1e668a551b089177867e62e03d7d2d",
|
||||
"url": "https://api.github.com/repos/symfony/Filesystem/zipball/177e0a8e29fab3f0556f7a973b5a42935e42a4d7",
|
||||
"reference": "177e0a8e29fab3f0556f7a973b5a42935e42a4d7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2118,7 +2118,7 @@
|
||||
],
|
||||
"description": "Symfony Filesystem Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2015-01-09 06:51:41"
|
||||
"time": "2015-02-11 07:17:51"
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
@@ -2174,12 +2174,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/HttpFoundation.git",
|
||||
"reference": "749f478499b89aaf53bdd6c80743fc0c3a72cce4"
|
||||
"reference": "79b2385ee420944ab89c6972acae9c7c8cb9a412"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/749f478499b89aaf53bdd6c80743fc0c3a72cce4",
|
||||
"reference": "749f478499b89aaf53bdd6c80743fc0c3a72cce4",
|
||||
"url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/79b2385ee420944ab89c6972acae9c7c8cb9a412",
|
||||
"reference": "79b2385ee420944ab89c6972acae9c7c8cb9a412",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2218,7 +2218,7 @@
|
||||
],
|
||||
"description": "Symfony HttpFoundation Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2015-02-05 06:31:40"
|
||||
"time": "2015-02-08 07:07:45"
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-kernel",
|
||||
@@ -2227,12 +2227,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/HttpKernel.git",
|
||||
"reference": "122057675f27f41b25b5811523516cc018eb28ed"
|
||||
"reference": "b481edb3c476dcd2040443f38292c1fadd2fac88"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/HttpKernel/zipball/122057675f27f41b25b5811523516cc018eb28ed",
|
||||
"reference": "122057675f27f41b25b5811523516cc018eb28ed",
|
||||
"url": "https://api.github.com/repos/symfony/HttpKernel/zipball/b481edb3c476dcd2040443f38292c1fadd2fac88",
|
||||
"reference": "b481edb3c476dcd2040443f38292c1fadd2fac88",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2292,7 +2292,7 @@
|
||||
],
|
||||
"description": "Symfony HttpKernel Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2015-02-02 14:03:24"
|
||||
"time": "2015-02-08 07:08:16"
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
@@ -2301,12 +2301,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Process.git",
|
||||
"reference": "daaa39a0d7462c225f711b20dc8f5896bdab92ff"
|
||||
"reference": "00a1308e8b5aec5eba7c8f1708426a78f929be8c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Process/zipball/daaa39a0d7462c225f711b20dc8f5896bdab92ff",
|
||||
"reference": "daaa39a0d7462c225f711b20dc8f5896bdab92ff",
|
||||
"url": "https://api.github.com/repos/symfony/Process/zipball/00a1308e8b5aec5eba7c8f1708426a78f929be8c",
|
||||
"reference": "00a1308e8b5aec5eba7c8f1708426a78f929be8c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2339,7 +2339,7 @@
|
||||
],
|
||||
"description": "Symfony Process Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2015-02-05 08:31:48"
|
||||
"time": "2015-02-08 07:07:45"
|
||||
},
|
||||
{
|
||||
"name": "symfony/routing",
|
||||
@@ -2348,12 +2348,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Routing.git",
|
||||
"reference": "8743280059d6d74db4a7fb58bbe049bd795195a9"
|
||||
"reference": "46142c34ea830f47429df6e15faec3a33292d618"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Routing/zipball/8743280059d6d74db4a7fb58bbe049bd795195a9",
|
||||
"reference": "8743280059d6d74db4a7fb58bbe049bd795195a9",
|
||||
"url": "https://api.github.com/repos/symfony/Routing/zipball/46142c34ea830f47429df6e15faec3a33292d618",
|
||||
"reference": "46142c34ea830f47429df6e15faec3a33292d618",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2407,7 +2407,7 @@
|
||||
"uri",
|
||||
"url"
|
||||
],
|
||||
"time": "2015-02-05 06:31:40"
|
||||
"time": "2015-02-08 07:07:45"
|
||||
},
|
||||
{
|
||||
"name": "symfony/security-core",
|
||||
@@ -2479,12 +2479,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Stopwatch.git",
|
||||
"reference": "f6ce5e09596ec0493ef42acf5eb0b38218733e48"
|
||||
"reference": "2883cdac7f23a0355760e485d6906528ad1e9504"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Stopwatch/zipball/f6ce5e09596ec0493ef42acf5eb0b38218733e48",
|
||||
"reference": "f6ce5e09596ec0493ef42acf5eb0b38218733e48",
|
||||
"url": "https://api.github.com/repos/symfony/Stopwatch/zipball/2883cdac7f23a0355760e485d6906528ad1e9504",
|
||||
"reference": "2883cdac7f23a0355760e485d6906528ad1e9504",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2517,7 +2517,7 @@
|
||||
],
|
||||
"description": "Symfony Stopwatch Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2015-01-09 06:51:41"
|
||||
"time": "2015-02-11 07:17:51"
|
||||
},
|
||||
{
|
||||
"name": "symfony/translation",
|
||||
@@ -2639,12 +2639,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Yaml.git",
|
||||
"reference": "02ba3dc638c5d3f0ab3b47ddb74f98c11dcc0c60"
|
||||
"reference": "43aac3461a5679f486f7c96e4d7e780a59fec997"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Yaml/zipball/02ba3dc638c5d3f0ab3b47ddb74f98c11dcc0c60",
|
||||
"reference": "02ba3dc638c5d3f0ab3b47ddb74f98c11dcc0c60",
|
||||
"url": "https://api.github.com/repos/symfony/Yaml/zipball/43aac3461a5679f486f7c96e4d7e780a59fec997",
|
||||
"reference": "43aac3461a5679f486f7c96e4d7e780a59fec997",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2677,7 +2677,7 @@
|
||||
],
|
||||
"description": "Symfony Yaml Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2015-01-25 04:39:35"
|
||||
"time": "2015-02-11 07:17:51"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
@@ -2735,6 +2735,72 @@
|
||||
],
|
||||
"time": "2015-01-16 19:29:51"
|
||||
},
|
||||
{
|
||||
"name": "mockery/mockery",
|
||||
"version": "dev-master",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/padraic/mockery.git",
|
||||
"reference": "f770ab0cf167cccf1a701f28411fbfc9971ff90e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/padraic/mockery/zipball/f770ab0cf167cccf1a701f28411fbfc9971ff90e",
|
||||
"reference": "f770ab0cf167cccf1a701f28411fbfc9971ff90e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"lib-pcre": ">=7.0",
|
||||
"php": ">=5.3.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"hamcrest/hamcrest-php": "~1.1",
|
||||
"phpunit/phpunit": "~4.0",
|
||||
"satooshi/php-coveralls": "~0.7@dev"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "0.9.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Mockery": "library/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Pádraic Brady",
|
||||
"email": "padraic.brady@gmail.com",
|
||||
"homepage": "http://blog.astrumfutura.com"
|
||||
},
|
||||
{
|
||||
"name": "Dave Marshall",
|
||||
"email": "dave.marshall@atstsolutions.co.uk",
|
||||
"homepage": "http://davedevelopment.co.uk"
|
||||
}
|
||||
],
|
||||
"description": "Mockery is a simple yet flexible PHP mock object framework for use in unit testing with PHPUnit, PHPSpec or any other testing framework. Its core goal is to offer a test double framework with a succinct API capable of clearly defining all possible object operations and interactions using a human readable Domain Specific Language (DSL). Designed as a drop in alternative to PHPUnit's phpunit-mock-objects library, Mockery is easy to integrate with PHPUnit and can operate alongside phpunit-mock-objects without the World ending.",
|
||||
"homepage": "http://github.com/padraic/mockery",
|
||||
"keywords": [
|
||||
"BDD",
|
||||
"TDD",
|
||||
"library",
|
||||
"mock",
|
||||
"mock objects",
|
||||
"mockery",
|
||||
"stub",
|
||||
"test",
|
||||
"test double",
|
||||
"testing"
|
||||
],
|
||||
"time": "2015-02-11 12:43:02"
|
||||
},
|
||||
{
|
||||
"name": "phpdocumentor/reflection-docblock",
|
||||
"version": "dev-master",
|
||||
@@ -2790,12 +2856,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpspec/prophecy.git",
|
||||
"reference": "d647e27524f9f7edc37baf63a114b52f5975808f"
|
||||
"reference": "3a9204c44667c302049ab4eadb02daab789e19ed"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/d647e27524f9f7edc37baf63a114b52f5975808f",
|
||||
"reference": "d647e27524f9f7edc37baf63a114b52f5975808f",
|
||||
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/3a9204c44667c302049ab4eadb02daab789e19ed",
|
||||
"reference": "3a9204c44667c302049ab4eadb02daab789e19ed",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2842,7 +2908,7 @@
|
||||
"spy",
|
||||
"stub"
|
||||
],
|
||||
"time": "2015-01-26 10:50:16"
|
||||
"time": "2015-02-09 17:43:38"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
@@ -3094,12 +3160,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "2b1e1e267d0286538b1762aa2c79a96ae1e583c8"
|
||||
"reference": "7c1de6a854a36ba330b352a005a4f5f928619f53"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/2b1e1e267d0286538b1762aa2c79a96ae1e583c8",
|
||||
"reference": "2b1e1e267d0286538b1762aa2c79a96ae1e583c8",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/7c1de6a854a36ba330b352a005a4f5f928619f53",
|
||||
"reference": "7c1de6a854a36ba330b352a005a4f5f928619f53",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3158,7 +3224,7 @@
|
||||
"testing",
|
||||
"xunit"
|
||||
],
|
||||
"time": "2015-02-06 05:41:08"
|
||||
"time": "2015-02-09 06:38:12"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit-mock-objects",
|
||||
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
table.dataTable.dtr-inline.collapsed tbody td:first-child,
|
||||
table.dataTable.dtr-inline.collapsed tbody th:first-child {
|
||||
position: relative;
|
||||
padding-left: 30px;
|
||||
cursor: pointer;
|
||||
}
|
||||
table.dataTable.dtr-inline.collapsed tbody td:first-child:before,
|
||||
table.dataTable.dtr-inline.collapsed tbody th:first-child:before {
|
||||
top: 8px;
|
||||
left: 4px;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
display: block;
|
||||
position: absolute;
|
||||
color: white;
|
||||
border: 2px solid white;
|
||||
border-radius: 16px;
|
||||
text-align: center;
|
||||
line-height: 14px;
|
||||
box-shadow: 0 0 3px #444;
|
||||
box-sizing: content-box;
|
||||
content: '+';
|
||||
background-color: #31b131;
|
||||
}
|
||||
table.dataTable.dtr-inline.collapsed tbody td:first-child.dataTables_empty:before,
|
||||
table.dataTable.dtr-inline.collapsed tbody th:first-child.dataTables_empty:before {
|
||||
display: none;
|
||||
}
|
||||
table.dataTable.dtr-inline.collapsed tbody tr.parent td:first-child:before,
|
||||
table.dataTable.dtr-inline.collapsed tbody tr.parent th:first-child:before {
|
||||
content: '-';
|
||||
background-color: #d33333;
|
||||
}
|
||||
table.dataTable.dtr-inline.collapsed tbody tr.child td:before {
|
||||
display: none;
|
||||
}
|
||||
table.dataTable.dtr-column tbody td.control,
|
||||
table.dataTable.dtr-column tbody th.control {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
}
|
||||
table.dataTable.dtr-column tbody td.control:before,
|
||||
table.dataTable.dtr-column tbody th.control:before {
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
margin-top: -10px;
|
||||
margin-left: -10px;
|
||||
display: block;
|
||||
position: absolute;
|
||||
color: white;
|
||||
border: 2px solid white;
|
||||
border-radius: 16px;
|
||||
text-align: center;
|
||||
line-height: 14px;
|
||||
box-shadow: 0 0 3px #444;
|
||||
box-sizing: content-box;
|
||||
content: '+';
|
||||
background-color: #31b131;
|
||||
}
|
||||
table.dataTable.dtr-column tbody tr.parent td.control:before,
|
||||
table.dataTable.dtr-column tbody tr.parent th.control:before {
|
||||
content: '-';
|
||||
background-color: #d33333;
|
||||
}
|
||||
table.dataTable tr.child {
|
||||
padding: 0.5em 1em;
|
||||
}
|
||||
table.dataTable tr.child:hover {
|
||||
background: transparent !important;
|
||||
}
|
||||
table.dataTable tr.child ul {
|
||||
display: inline-block;
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
table.dataTable tr.child ul li {
|
||||
border-bottom: 1px solid #efefef;
|
||||
padding: 0.5em 0;
|
||||
}
|
||||
table.dataTable tr.child ul li:first-child {
|
||||
padding-top: 0;
|
||||
}
|
||||
table.dataTable tr.child ul li:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
table.dataTable tr.child span.dtr-title {
|
||||
display: inline-block;
|
||||
min-width: 75px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src: local('Open Sans Light'), local('OpenSans-Light'), url(http://fonts.gstatic.com/s/opensans/v10/DXI1ORHCpsQm3Vp6mXoaTZS3E-kSBmtLoNJPDtbj2Pk.ttf) format('truetype');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Open Sans'), local('OpenSans'), url(http://fonts.gstatic.com/s/opensans/v10/cJZKeOuBrn4kERxqtaUH3SZ2oysoEQEeKwjgmXLRnTc.ttf) format('truetype');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
src: local('Open Sans Semibold'), local('OpenSans-Semibold'), url(http://fonts.gstatic.com/s/opensans/v10/MTP_ySUJH_bn48VBG8sNSpS3E-kSBmtLoNJPDtbj2Pk.ttf) format('truetype');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('Open Sans Bold'), local('OpenSans-Bold'), url(http://fonts.gstatic.com/s/opensans/v10/k3k702ZOKiLJc3WVjuplzJS3E-kSBmtLoNJPDtbj2Pk.ttf) format('truetype');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 800;
|
||||
src: local('Open Sans Extrabold'), local('OpenSans-Extrabold'), url(http://fonts.gstatic.com/s/opensans/v10/EInbV5DfGHOiMmvb1Xr-hpS3E-kSBmtLoNJPDtbj2Pk.ttf) format('truetype');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
src: local('Open Sans Light Italic'), local('OpenSansLight-Italic'), url(http://fonts.gstatic.com/s/opensans/v10/PRmiXeptR36kaC0GEAetxt6Naowg1QhaIq8kLGtQSos.ttf) format('truetype');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
src: local('Open Sans Italic'), local('OpenSans-Italic'), url(http://fonts.gstatic.com/s/opensans/v10/xjAJXh38I15wypJXxuGMBiwlidHJgAgmTjOEEzwu1L8.ttf) format('truetype');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
src: local('Open Sans Semibold Italic'), local('OpenSans-SemiboldItalic'), url(http://fonts.gstatic.com/s/opensans/v10/PRmiXeptR36kaC0GEAetxs1QGe9x6ME_FQCWJB3n6z8.ttf) format('truetype');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: local('Open Sans Bold Italic'), local('OpenSans-BoldItalic'), url(http://fonts.gstatic.com/s/opensans/v10/PRmiXeptR36kaC0GEAetxjdGNerWpg2Hn6A-BxWgZ_I.ttf) format('truetype');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 800;
|
||||
src: local('Open Sans Extrabold Italic'), local('OpenSans-ExtraboldItalic'), url(http://fonts.gstatic.com/s/opensans/v10/PRmiXeptR36kaC0GEAetxkdJXfhP-2RmnAuS9A2rxpE.ttf) format('truetype');
|
||||
}
|
||||
|
||||
Executable
+802
@@ -0,0 +1,802 @@
|
||||
/*! Responsive 1.0.2
|
||||
* 2014 SpryMedia Ltd - datatables.net/license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @summary Responsive
|
||||
* @description Responsive tables plug-in for DataTables
|
||||
* @version 1.0.2
|
||||
* @file dataTables.responsive.js
|
||||
* @author SpryMedia Ltd (www.sprymedia.co.uk)
|
||||
* @contact www.sprymedia.co.uk/contact
|
||||
* @copyright Copyright 2014 SpryMedia Ltd.
|
||||
*
|
||||
* This source file is free software, available under the following license:
|
||||
* MIT license - http://datatables.net/license/mit
|
||||
*
|
||||
* This source file is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
|
||||
*
|
||||
* For details please refer to: http://www.datatables.net
|
||||
*/
|
||||
|
||||
(function(window, document, undefined) {
|
||||
|
||||
|
||||
var factory = function( $, DataTable ) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Responsive is a plug-in for the DataTables library that makes use of
|
||||
* DataTables' ability to change the visibility of columns, changing the
|
||||
* visibility of columns so the displayed columns fit into the table container.
|
||||
* The end result is that complex tables will be dynamically adjusted to fit
|
||||
* into the viewport, be it on a desktop, tablet or mobile browser.
|
||||
*
|
||||
* Responsive for DataTables has two modes of operation, which can used
|
||||
* individually or combined:
|
||||
*
|
||||
* * Class name based control - columns assigned class names that match the
|
||||
* breakpoint logic can be shown / hidden as required for each breakpoint.
|
||||
* * Automatic control - columns are automatically hidden when there is no
|
||||
* room left to display them. Columns removed from the right.
|
||||
*
|
||||
* In additional to column visibility control, Responsive also has built into
|
||||
* options to use DataTables' child row display to show / hide the information
|
||||
* from the table that has been hidden. There are also two modes of operation
|
||||
* for this child row display:
|
||||
*
|
||||
* * Inline - when the control element that the user can use to show / hide
|
||||
* child rows is displayed inside the first column of the table.
|
||||
* * Column - where a whole column is dedicated to be the show / hide control.
|
||||
*
|
||||
* Initialisation of Responsive is performed by:
|
||||
*
|
||||
* * Adding the class `responsive` or `dt-responsive` to the table. In this case
|
||||
* Responsive will automatically be initialised with the default configuration
|
||||
* options when the DataTable is created.
|
||||
* * Using the `responsive` option in the DataTables configuration options. This
|
||||
* can also be used to specify the configuration options, or simply set to
|
||||
* `true` to use the defaults.
|
||||
*
|
||||
* @class
|
||||
* @param {object} settings DataTables settings object for the host table
|
||||
* @param {object} [opts] Configuration options
|
||||
* @requires jQuery 1.7+
|
||||
* @requires DataTables 1.10.1+
|
||||
*
|
||||
* @example
|
||||
* $('#example').DataTable( {
|
||||
* responsive: true
|
||||
* } );
|
||||
* } );
|
||||
*/
|
||||
var Responsive = function ( settings, opts ) {
|
||||
// Sanity check that we are using DataTables 1.10 or newer
|
||||
if ( ! DataTable.versionCheck || ! DataTable.versionCheck( '1.10.1' ) ) {
|
||||
throw 'DataTables Responsive requires DataTables 1.10.1 or newer';
|
||||
}
|
||||
|
||||
this.s = {
|
||||
dt: new DataTable.Api( settings ),
|
||||
columns: []
|
||||
};
|
||||
|
||||
// Check if responsive has already been initialised on this table
|
||||
if ( this.s.dt.settings()[0].responsive ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// details is an object, but for simplicity the user can give it as a string
|
||||
if ( opts && typeof opts.details === 'string' ) {
|
||||
opts.details = { type: opts.details };
|
||||
}
|
||||
|
||||
this.c = $.extend( true, {}, Responsive.defaults, DataTable.defaults.responsive, opts );
|
||||
settings.responsive = this;
|
||||
this._constructor();
|
||||
};
|
||||
|
||||
Responsive.prototype = {
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Constructor
|
||||
*/
|
||||
|
||||
/**
|
||||
* Initialise the Responsive instance
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_constructor: function ()
|
||||
{
|
||||
var that = this;
|
||||
var dt = this.s.dt;
|
||||
|
||||
dt.settings()[0]._responsive = this;
|
||||
|
||||
// Use DataTables' private throttle function to avoid processor thrashing
|
||||
$(window).on( 'resize.dtr orientationchange.dtr', dt.settings()[0].oApi._fnThrottle( function () {
|
||||
that._resize();
|
||||
} ) );
|
||||
|
||||
// Destroy event handler
|
||||
dt.on( 'destroy.dtr', function () {
|
||||
$(window).off( 'resize.dtr orientationchange.dtr' );
|
||||
} );
|
||||
|
||||
// Reorder the breakpoints array here in case they have been added out
|
||||
// of order
|
||||
this.c.breakpoints.sort( function (a, b) {
|
||||
return a.width < b.width ? 1 :
|
||||
a.width > b.width ? -1 : 0;
|
||||
} );
|
||||
|
||||
// Determine which columns are already hidden, and should therefore
|
||||
// remain hidden. TODO - should this be done? See thread 22677
|
||||
//
|
||||
// this.s.alwaysHidden = dt.columns(':hidden').indexes();
|
||||
|
||||
this._classLogic();
|
||||
this._resizeAuto();
|
||||
|
||||
// First pass - draw the table for the current viewport size
|
||||
this._resize();
|
||||
|
||||
// Details handler
|
||||
var details = this.c.details;
|
||||
if ( details.type ) {
|
||||
that._detailsInit();
|
||||
this._detailsVis();
|
||||
|
||||
dt.on( 'column-visibility.dtr', function () {
|
||||
that._detailsVis();
|
||||
} );
|
||||
|
||||
$(dt.table().node()).addClass( 'dtr-'+details.type );
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Private methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* Calculate the visibility for the columns in a table for a given
|
||||
* breakpoint. The result is pre-determined based on the class logic if
|
||||
* class names are used to control all columns, but the width of the table
|
||||
* is also used if there are columns which are to be automatically shown
|
||||
* and hidden.
|
||||
*
|
||||
* @param {string} breakpoint Breakpoint name to use for the calculation
|
||||
* @return {array} Array of boolean values initiating the visibility of each
|
||||
* column.
|
||||
* @private
|
||||
*/
|
||||
_columnsVisiblity: function ( breakpoint )
|
||||
{
|
||||
var dt = this.s.dt;
|
||||
var columns = this.s.columns;
|
||||
var i, ien;
|
||||
|
||||
// Class logic - determine which columns are in this breakpoint based
|
||||
// on the classes. If no class control (i.e. `auto`) then `-` is used
|
||||
// to indicate this to the rest of the function
|
||||
var display = $.map( columns, function ( col ) {
|
||||
return col.auto && col.minWidth === null ?
|
||||
false :
|
||||
col.auto === true ?
|
||||
'-' :
|
||||
$.inArray( breakpoint, col.includeIn ) !== -1;
|
||||
} );
|
||||
|
||||
// Auto column control - first pass: how much width is taken by the
|
||||
// ones that must be included from the non-auto columns
|
||||
var requiredWidth = 0;
|
||||
for ( i=0, ien=display.length ; i<ien ; i++ ) {
|
||||
if ( display[i] === true ) {
|
||||
requiredWidth += columns[i].minWidth;
|
||||
}
|
||||
}
|
||||
|
||||
// Second pass, use up any remaining width for other columns
|
||||
var widthAvailable = dt.table().container().offsetWidth;
|
||||
var usedWidth = widthAvailable - requiredWidth;
|
||||
|
||||
for ( i=0, ien=display.length ; i<ien ; i++ ) {
|
||||
// Control column needs to always be included. This makes it sub-
|
||||
// optimal in terms of using the available with, but to stop layout
|
||||
// thrashing or overflow
|
||||
if ( columns[i].control ) {
|
||||
usedWidth -= columns[i].minWidth;
|
||||
}
|
||||
else if ( display[i] === '-' ) {
|
||||
// Otherwise, remove the width
|
||||
display[i] = usedWidth - columns[i].minWidth < 0 ?
|
||||
false :
|
||||
true;
|
||||
|
||||
// Continue counting down the width, so a smaller column to the
|
||||
// left won't be shown
|
||||
usedWidth -= columns[i].minWidth;
|
||||
}
|
||||
}
|
||||
|
||||
// Determine if the 'control' column should be shown (if there is one).
|
||||
// This is the case when there is a hidden column (that is not the
|
||||
// control column). The two loops look inefficient here, but they are
|
||||
// trivial and will fly through. We need to know the outcome from the
|
||||
// first , before the action in the second can be taken
|
||||
var showControl = false;
|
||||
|
||||
for ( i=0, ien=columns.length ; i<ien ; i++ ) {
|
||||
if ( ! columns[i].control && ! columns[i].never && ! display[i] ) {
|
||||
showControl = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for ( i=0, ien=columns.length ; i<ien ; i++ ) {
|
||||
if ( columns[i].control ) {
|
||||
display[i] = showControl;
|
||||
}
|
||||
}
|
||||
|
||||
// Finally we need to make sure that there is at least one column that
|
||||
// is visible
|
||||
if ( $.inArray( true, display ) === -1 ) {
|
||||
display[0] = true;
|
||||
}
|
||||
|
||||
return display;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Create the internal `columns` array with information about the columns
|
||||
* for the table. This includes determining which breakpoints the column
|
||||
* will appear in, based upon class names in the column, which makes up the
|
||||
* vast majority of this method.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_classLogic: function ()
|
||||
{
|
||||
var that = this;
|
||||
var calc = {};
|
||||
var breakpoints = this.c.breakpoints;
|
||||
var columns = this.s.dt.columns().eq(0).map( function (i) {
|
||||
var className = this.column(i).header().className;
|
||||
|
||||
return {
|
||||
className: className,
|
||||
includeIn: [],
|
||||
auto: false,
|
||||
control: false,
|
||||
never: className.match(/\bnever\b/) ? true : false
|
||||
};
|
||||
} );
|
||||
|
||||
// Simply add a breakpoint to `includeIn` array, ensuring that there are
|
||||
// no duplicates
|
||||
var add = function ( colIdx, name ) {
|
||||
var includeIn = columns[ colIdx ].includeIn;
|
||||
|
||||
if ( $.inArray( name, includeIn ) === -1 ) {
|
||||
includeIn.push( name );
|
||||
}
|
||||
};
|
||||
|
||||
var column = function ( colIdx, name, operator, matched ) {
|
||||
var size, i, ien;
|
||||
|
||||
if ( ! operator ) {
|
||||
columns[ colIdx ].includeIn.push( name );
|
||||
}
|
||||
else if ( operator === 'max-' ) {
|
||||
// Add this breakpoint and all smaller
|
||||
size = that._find( name ).width;
|
||||
|
||||
for ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {
|
||||
if ( breakpoints[i].width <= size ) {
|
||||
add( colIdx, breakpoints[i].name );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( operator === 'min-' ) {
|
||||
// Add this breakpoint and all larger
|
||||
size = that._find( name ).width;
|
||||
|
||||
for ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {
|
||||
if ( breakpoints[i].width >= size ) {
|
||||
add( colIdx, breakpoints[i].name );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( operator === 'not-' ) {
|
||||
// Add all but this breakpoint (xxx need extra information)
|
||||
|
||||
for ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {
|
||||
if ( breakpoints[i].name.indexOf( matched ) === -1 ) {
|
||||
add( colIdx, breakpoints[i].name );
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Loop over each column and determine if it has a responsive control
|
||||
// class
|
||||
columns.each( function ( col, i ) {
|
||||
var classNames = col.className.split(' ');
|
||||
var hasClass = false;
|
||||
|
||||
// Split the class name up so multiple rules can be applied if needed
|
||||
for ( var k=0, ken=classNames.length ; k<ken ; k++ ) {
|
||||
var className = $.trim( classNames[k] );
|
||||
|
||||
if ( className === 'all' ) {
|
||||
// Include in all
|
||||
hasClass = true;
|
||||
col.includeIn = $.map( breakpoints, function (a) {
|
||||
return a.name;
|
||||
} );
|
||||
return;
|
||||
}
|
||||
else if ( className === 'none' || className === 'never' ) {
|
||||
// Include in none (default) and no auto
|
||||
hasClass = true;
|
||||
return;
|
||||
}
|
||||
else if ( className === 'control' ) {
|
||||
// Special column that is only visible, when one of the other
|
||||
// columns is hidden. This is used for the details control
|
||||
hasClass = true;
|
||||
col.control = true;
|
||||
return;
|
||||
}
|
||||
|
||||
$.each( breakpoints, function ( j, breakpoint ) {
|
||||
// Does this column have a class that matches this breakpoint?
|
||||
var brokenPoint = breakpoint.name.split('-');
|
||||
var re = new RegExp( '(min\\-|max\\-|not\\-)?('+brokenPoint[0]+')(\\-[_a-zA-Z0-9])?' );
|
||||
var match = className.match( re );
|
||||
|
||||
if ( match ) {
|
||||
hasClass = true;
|
||||
|
||||
if ( match[2] === brokenPoint[0] && match[3] === '-'+brokenPoint[1] ) {
|
||||
// Class name matches breakpoint name fully
|
||||
column( i, breakpoint.name, match[1], match[2]+match[3] );
|
||||
}
|
||||
else if ( match[2] === brokenPoint[0] && ! match[3] ) {
|
||||
// Class name matched primary breakpoint name with no qualifier
|
||||
column( i, breakpoint.name, match[1], match[2] );
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
// If there was no control class, then automatic sizing is used
|
||||
if ( ! hasClass ) {
|
||||
col.auto = true;
|
||||
}
|
||||
} );
|
||||
|
||||
this.s.columns = columns;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Initialisation for the details handler
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_detailsInit: function ()
|
||||
{
|
||||
var that = this;
|
||||
var dt = this.s.dt;
|
||||
var details = this.c.details;
|
||||
|
||||
// The inline type always uses the first child as the target
|
||||
if ( details.type === 'inline' ) {
|
||||
details.target = 'td:first-child';
|
||||
}
|
||||
|
||||
// type.target can be a string jQuery selector or a column index
|
||||
var target = details.target;
|
||||
var selector = typeof target === 'string' ? target : 'td';
|
||||
|
||||
// Click handler to show / hide the details rows when they are available
|
||||
$( dt.table().body() ).on( 'click', selector, function (e) {
|
||||
// If the table is not collapsed (i.e. there is no hidden columns)
|
||||
// then take no action
|
||||
if ( ! $(dt.table().node()).hasClass('collapsed' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check that the row is actually a DataTable's controlled node
|
||||
if ( ! dt.row( $(this).closest('tr') ).length ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// For column index, we determine if we should act or not in the
|
||||
// handler - otherwise it is already okay
|
||||
if ( typeof target === 'number' ) {
|
||||
var targetIdx = target < 0 ?
|
||||
dt.columns().eq(0).length + target :
|
||||
target;
|
||||
|
||||
if ( dt.cell( this ).index().column !== targetIdx ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// $().closest() includes itself in its check
|
||||
var row = dt.row( $(this).closest('tr') );
|
||||
|
||||
if ( row.child.isShown() ) {
|
||||
row.child( false );
|
||||
$( row.node() ).removeClass( 'parent' );
|
||||
}
|
||||
else {
|
||||
var info = that.c.details.renderer( dt, row[0] );
|
||||
row.child( info, 'child' ).show();
|
||||
$( row.node() ).addClass( 'parent' );
|
||||
}
|
||||
} );
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Update the child rows in the table whenever the column visibility changes
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_detailsVis: function ()
|
||||
{
|
||||
var that = this;
|
||||
var dt = this.s.dt;
|
||||
|
||||
// Find how many columns are hidden
|
||||
var hiddenColumns = dt.columns().indexes().filter( function ( idx ) {
|
||||
var col = dt.column( idx );
|
||||
|
||||
if ( col.visible() ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Only counts as hidden if it doesn't have the `never` class
|
||||
return $( col.header() ).hasClass( 'never' ) ? null : idx;
|
||||
} );
|
||||
var haveHidden = true;
|
||||
|
||||
if ( hiddenColumns.length === 0 || ( hiddenColumns.length === 1 && this.s.columns[ hiddenColumns[0] ].control ) ) {
|
||||
haveHidden = false;
|
||||
}
|
||||
|
||||
if ( haveHidden ) {
|
||||
// Got hidden columns
|
||||
$( dt.table().node() ).addClass('collapsed');
|
||||
|
||||
// Show all existing child rows
|
||||
dt.rows().eq(0).each( function (idx) {
|
||||
var row = dt.row( idx );
|
||||
|
||||
if ( row.child() ) {
|
||||
var info = that.c.details.renderer( dt, row[0] );
|
||||
|
||||
// The renderer can return false to have no child row
|
||||
if ( info === false ) {
|
||||
row.child.hide();
|
||||
}
|
||||
else {
|
||||
row.child( info, 'child' ).show();
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
else {
|
||||
// No hidden columns
|
||||
$( dt.table().node() ).removeClass('collapsed');
|
||||
|
||||
// Hide all existing child rows
|
||||
dt.rows().eq(0).each( function (idx) {
|
||||
dt.row( idx ).child.hide();
|
||||
} );
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Find a breakpoint object from a name
|
||||
* @param {string} name Breakpoint name to find
|
||||
* @return {object} Breakpoint description object
|
||||
*/
|
||||
_find: function ( name )
|
||||
{
|
||||
var breakpoints = this.c.breakpoints;
|
||||
|
||||
for ( var i=0, ien=breakpoints.length ; i<ien ; i++ ) {
|
||||
if ( breakpoints[i].name === name ) {
|
||||
return breakpoints[i];
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Alter the table display for a resized viewport. This involves first
|
||||
* determining what breakpoint the window currently is in, getting the
|
||||
* column visibilities to apply and then setting them.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_resize: function ()
|
||||
{
|
||||
var dt = this.s.dt;
|
||||
var width = $(window).width();
|
||||
var breakpoints = this.c.breakpoints;
|
||||
var breakpoint = breakpoints[0].name;
|
||||
|
||||
// Determine what breakpoint we are currently at
|
||||
for ( var i=breakpoints.length-1 ; i>=0 ; i-- ) {
|
||||
if ( width <= breakpoints[i].width ) {
|
||||
breakpoint = breakpoints[i].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Show the columns for that break point
|
||||
var columns = this._columnsVisiblity( breakpoint );
|
||||
|
||||
dt.columns().eq(0).each( function ( colIdx, i ) {
|
||||
dt.column( colIdx ).visible( columns[i] );
|
||||
} );
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Determine the width of each column in the table so the auto column hiding
|
||||
* has that information to work with. This method is never going to be 100%
|
||||
* perfect since column widths can change slightly per page, but without
|
||||
* seriously compromising performance this is quite effective.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_resizeAuto: function ()
|
||||
{
|
||||
var dt = this.s.dt;
|
||||
var columns = this.s.columns;
|
||||
|
||||
// Are we allowed to do auto sizing?
|
||||
if ( ! this.c.auto ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Are there any columns that actually need auto-sizing, or do they all
|
||||
// have classes defined
|
||||
if ( $.inArray( true, $.map( columns, function (c) { return c.auto; } ) ) === -1 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Clone the table with the current data in it
|
||||
var tableWidth = dt.table().node().offsetWidth;
|
||||
var columnWidths = dt.columns;
|
||||
var clonedTable = dt.table().node().cloneNode( false );
|
||||
var clonedHeader = $( dt.table().header().cloneNode( false ) ).appendTo( clonedTable );
|
||||
var clonedBody = $( dt.table().body().cloneNode( false ) ).appendTo( clonedTable );
|
||||
|
||||
// This is a bit slow, but we need to get a clone of each row that
|
||||
// includes all columns. As such, try to do this as little as possible.
|
||||
dt.rows( { page: 'current' } ).indexes().flatten().each( function ( idx ) {
|
||||
var clone = dt.row( idx ).node().cloneNode( true );
|
||||
|
||||
if ( dt.columns( ':hidden' ).flatten().length ) {
|
||||
$(clone).append( dt.cells( idx, ':hidden' ).nodes().to$().clone() );
|
||||
}
|
||||
|
||||
$(clone).appendTo( clonedBody );
|
||||
} );
|
||||
|
||||
var cells = dt.columns().header().to$().clone( false ).wrapAll('tr').appendTo( clonedHeader );
|
||||
var inserted = $('<div/>')
|
||||
.css( {
|
||||
width: 1,
|
||||
height: 1,
|
||||
overflow: 'hidden'
|
||||
} )
|
||||
.append( clonedTable )
|
||||
.insertBefore( dt.table().node() );
|
||||
|
||||
// The cloned header now contains the smallest that each column can be
|
||||
dt.columns().eq(0).each( function ( idx ) {
|
||||
columns[idx].minWidth = cells[ idx ].offsetWidth || 0;
|
||||
} );
|
||||
|
||||
inserted.remove();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* List of default breakpoints. Each item in the array is an object with two
|
||||
* properties:
|
||||
*
|
||||
* * `name` - the breakpoint name.
|
||||
* * `width` - the breakpoint width
|
||||
*
|
||||
* @name Responsive.breakpoints
|
||||
* @static
|
||||
*/
|
||||
Responsive.breakpoints = [
|
||||
{ name: 'desktop', width: Infinity },
|
||||
{ name: 'tablet-l', width: 1024 },
|
||||
{ name: 'tablet-p', width: 768 },
|
||||
{ name: 'mobile-l', width: 480 },
|
||||
{ name: 'mobile-p', width: 320 }
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Responsive default settings for initialisation
|
||||
*
|
||||
* @namespace
|
||||
* @name Responsive.defaults
|
||||
* @static
|
||||
*/
|
||||
Responsive.defaults = {
|
||||
/**
|
||||
* List of breakpoints for the instance. Note that this means that each
|
||||
* instance can have its own breakpoints. Additionally, the breakpoints
|
||||
* cannot be changed once an instance has been creased.
|
||||
*
|
||||
* @type {Array}
|
||||
* @default Takes the value of `Responsive.breakpoints`
|
||||
*/
|
||||
breakpoints: Responsive.breakpoints,
|
||||
|
||||
/**
|
||||
* Enable / disable auto hiding calculations. It can help to increase
|
||||
* performance slightly if you disable this option, but all columns would
|
||||
* need to have breakpoint classes assigned to them
|
||||
*
|
||||
* @type {Boolean}
|
||||
* @default `true`
|
||||
*/
|
||||
auto: true,
|
||||
|
||||
/**
|
||||
* Details control. If given as a string value, the `type` property of the
|
||||
* default object is set to that value, and the defaults used for the rest
|
||||
* of the object - this is for ease of implementation.
|
||||
*
|
||||
* The object consists of the following properties:
|
||||
*
|
||||
* * `renderer` - function that is called for display of the child row data.
|
||||
* The default function will show the data from the hidden columns
|
||||
* * `target` - Used as the selector for what objects to attach the child
|
||||
* open / close to
|
||||
* * `type` - `false` to disable the details display, `inline` or `column`
|
||||
* for the two control types
|
||||
*
|
||||
* @type {Object|string}
|
||||
*/
|
||||
details: {
|
||||
renderer: function ( api, rowIdx ) {
|
||||
var data = api.cells( rowIdx, ':hidden' ).eq(0).map( function ( cell ) {
|
||||
var header = $( api.column( cell.column ).header() );
|
||||
var idx = api.cell( cell ).index();
|
||||
|
||||
if ( header.hasClass( 'control' ) || header.hasClass( 'never' ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Use a non-public DT API method to render the data for display
|
||||
// This needs to be updated when DT adds a suitable method for
|
||||
// this type of data retrieval
|
||||
var dtPrivate = api.settings()[0];
|
||||
var cellData = dtPrivate.oApi._fnGetCellData(
|
||||
dtPrivate, idx.row, idx.column, 'display'
|
||||
);
|
||||
|
||||
return '<li data-dtr-index="'+idx.column+'">'+
|
||||
'<span class="dtr-title">'+
|
||||
header.text()+':'+
|
||||
'</span> '+
|
||||
'<span class="dtr-data">'+
|
||||
cellData+
|
||||
'</span>'+
|
||||
'</li>';
|
||||
} ).toArray().join('');
|
||||
|
||||
return data ?
|
||||
$('<ul data-dtr-index="'+rowIdx+'"/>').append( data ) :
|
||||
false;
|
||||
},
|
||||
|
||||
target: 0,
|
||||
|
||||
type: 'inline'
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* API
|
||||
*/
|
||||
var Api = $.fn.dataTable.Api;
|
||||
|
||||
// Doesn't do anything - work around for a bug in DT... Not documented
|
||||
Api.register( 'responsive()', function () {
|
||||
return this;
|
||||
} );
|
||||
|
||||
Api.register( 'responsive.recalc()', function () {
|
||||
this.iterator( 'table', function ( ctx ) {
|
||||
if ( ctx._responsive ) {
|
||||
ctx._responsive._resizeAuto();
|
||||
ctx._responsive._resize();
|
||||
}
|
||||
} );
|
||||
} );
|
||||
|
||||
Api.register( 'responsive.index()', function ( li ) {
|
||||
li = $(li);
|
||||
|
||||
return {
|
||||
column: li.data('dtr-index'),
|
||||
row: li.parent().data('dtr-index')
|
||||
};
|
||||
} );
|
||||
|
||||
|
||||
/**
|
||||
* Version information
|
||||
*
|
||||
* @name Responsive.version
|
||||
* @static
|
||||
*/
|
||||
Responsive.version = '1.0.2';
|
||||
|
||||
|
||||
$.fn.dataTable.Responsive = Responsive;
|
||||
$.fn.DataTable.Responsive = Responsive;
|
||||
|
||||
// Attach a listener to the document which listens for DataTables initialisation
|
||||
// events so we can automatically initialise
|
||||
$(document).on( 'init.dt.dtr', function (e, settings, json) {
|
||||
if ( $(settings.nTable).hasClass( 'responsive' ) ||
|
||||
$(settings.nTable).hasClass( 'dt-responsive' ) ||
|
||||
settings.oInit.responsive ||
|
||||
DataTable.defaults.responsive
|
||||
) {
|
||||
var init = settings.oInit.responsive;
|
||||
|
||||
if ( init !== false ) {
|
||||
new Responsive( settings, $.isPlainObject( init ) ? init : {} );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
return Responsive;
|
||||
}; // /factory
|
||||
|
||||
|
||||
// Define as an AMD module if possible
|
||||
if ( typeof define === 'function' && define.amd ) {
|
||||
define( ['jquery', 'datatables'], factory );
|
||||
}
|
||||
else if ( typeof exports === 'object' ) {
|
||||
// Node/CommonJS
|
||||
factory( require('jquery'), require('datatables') );
|
||||
}
|
||||
else if ( jQuery && !jQuery.fn.dataTable.Responsive ) {
|
||||
// Otherwise simply initialise as normal, stopping multiple evaluation
|
||||
factory( jQuery, jQuery.fn.dataTable );
|
||||
}
|
||||
|
||||
|
||||
})(window, document);
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
HTML5 Shiv v3.7.0 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
|
||||
*/
|
||||
(function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag();
|
||||
a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/[\w\-]+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x<style>article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}</style>";
|
||||
c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="<xyz></xyz>";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode||
|
||||
"undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:"3.7.0",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f);
|
||||
if(g)return a.createDocumentFragment();for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;d<h;d++)c.createElement(e[d]);return c}};l.html5=e;q(f)})(this,document);
|
||||
+10309
File diff suppressed because it is too large
Load Diff
+3493
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user