mirror of
https://github.com/snipe/snipe-it.git
synced 2025-02-02 08:21:09 -08:00
Importer: Implement item update and interface improvments (#2507)
* Add support for updating assets to the importer. If an asset with a matching asset tag is found, and the --update flag is passed to the importer, we edit the matching asset with any asset-specific values, and persist to the database. Any missing/blank values are skipped. TODO: Add to web interface, add support in consumables/accessories * Allow deleting of files on the import page. * Extend web interface to allow updating of imported items. This adds a modal dialog to the import process. Currently the dialog allows the choice of update vs ignore, and choosing the item type to import (Accessory, Asset, Consumable). Also use Helper::ParseFloat() for purchase_cost processing. It exists, and fixes issues on my end at least. * Implement editing of consumables and accessories. * Rename getProcessImportFile to postProcessImportFile to reflect how it's now used * Fix copy-pasta error.
This commit is contained in:
parent
0d088f3031
commit
276e0a7114
|
@ -1,25 +1,26 @@
|
|||
<?php
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use League\Csv\Reader;
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Accessory;
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\Category;
|
||||
use App\Models\Company;
|
||||
use App\Models\Consumable;
|
||||
use App\Models\CustomField;
|
||||
use App\Models\Location;
|
||||
use App\Models\Manufacturer;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Statuslabel;
|
||||
use App\Models\Supplier;
|
||||
use App\Models\User;
|
||||
use App\Models\CustomField;
|
||||
use DB;
|
||||
use App\Models\Setting;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use League\Csv\Reader;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
|
||||
ini_set('max_execution_time', 600); //600 seconds = 10 minutes
|
||||
ini_set('memory_limit', '500M');
|
||||
|
@ -102,9 +103,17 @@ class ObjectImportCommand extends Command
|
|||
$this->companies = Company::All(['name', 'id']);
|
||||
$this->status_labels = Statuslabel::All(['name', 'id']);
|
||||
$this->suppliers = Supplier::All(['name', 'id']);
|
||||
$this->assets = Asset::all(['asset_tag']);
|
||||
$this->accessories = Accessory::All(['name']);
|
||||
$this->consumables = Consumable::All(['name']);
|
||||
switch (strtolower($this->option('item-type'))) {
|
||||
case "asset":
|
||||
$this->assets = Asset::all();
|
||||
break;
|
||||
case "accessory":
|
||||
$this->accessories = Accessory::All();
|
||||
break;
|
||||
case "consumable":
|
||||
$this->consumables = Consumable::All();
|
||||
break;
|
||||
}
|
||||
$this->customfields = CustomField::All(['name']);
|
||||
$bar = null;
|
||||
|
||||
|
@ -732,6 +741,24 @@ class ObjectImportCommand extends Command
|
|||
*/
|
||||
public function createAssetIfNotExists(array $row, array $item)
|
||||
{
|
||||
$asset = null;
|
||||
$editingAsset = false;
|
||||
foreach ($this->assets as $tempasset) {
|
||||
if (strcasecmp($tempasset->asset_tag, $item['asset_tag']) == 0) {
|
||||
$this->log('A matching Asset ' . $item['asset_tag'] . ' already exists');
|
||||
if (!$this->option('update')) {
|
||||
$this->log("Skipping item.");
|
||||
return;
|
||||
}
|
||||
$this->log('Updating matching asset with new values');
|
||||
$editingAsset = true;
|
||||
$asset = $tempasset;
|
||||
}
|
||||
}
|
||||
if (is_null($asset)) {
|
||||
$this->log("No Matching Asset, Creating a new one");
|
||||
$asset = new Asset;
|
||||
}
|
||||
$asset_serial = $this->array_smart_fetch($row, "serial number");
|
||||
$asset_image = $this->array_smart_fetch($row, "image");
|
||||
$asset_warranty_months = intval($this->array_smart_fetch($row, "warranty months"));
|
||||
|
@ -747,12 +774,7 @@ class ObjectImportCommand extends Command
|
|||
$this->log('Notes: '.$item["notes"]);
|
||||
$this->log('Warranty Months: ' . $asset_warranty_months);
|
||||
|
||||
foreach ($this->assets as $tempasset) {
|
||||
if (strcasecmp($tempasset->asset_tag, $item['asset_tag']) == 0) {
|
||||
$this->log('A matching Asset ' . $item['asset_tag'] . ' already exists');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($item["status_label"]) {
|
||||
$status_id = $item["status_label"]->id;
|
||||
|
@ -763,12 +785,14 @@ class ObjectImportCommand extends Command
|
|||
$status_id = 1;
|
||||
}
|
||||
|
||||
$asset = new Asset();
|
||||
$asset->name = $item["item_name"];
|
||||
if ($item["purchase_date"] != '') {
|
||||
if (!$editingAsset) {
|
||||
$asset->asset_tag = $item['asset_tag']; // This doesn't need to be guarded for empty because it's the key we use to identify the asset.
|
||||
}
|
||||
if (!empty($item['item_name'])) {
|
||||
$asset->name = $item["item_name"];
|
||||
}
|
||||
if (!empty($item["purchase_date"])) {
|
||||
$asset->purchase_date = $item["purchase_date"];
|
||||
} else {
|
||||
$asset->purchase_date = null;
|
||||
}
|
||||
|
||||
if (array_key_exists('custom_fields', $item)) {
|
||||
|
@ -780,37 +804,53 @@ class ObjectImportCommand extends Command
|
|||
if (!empty($item["purchase_cost"])) {
|
||||
//TODO How to generalize this for not USD?
|
||||
$purchase_cost = substr($item["purchase_cost"], 0, 1) === '$' ? substr($item["purchase_cost"], 1) : $item["purchase_cost"];
|
||||
$asset->purchase_cost = number_format($purchase_cost, 2, '.', '');
|
||||
// $asset->purchase_cost = number_format($purchase_cost, 2, '.', '');
|
||||
$asset->purchase_cost = Helper::ParseFloat($purchase_cost);
|
||||
$this->log("Asset cost parsed: " . $asset->purchase_cost);
|
||||
} else {
|
||||
$asset->purchase_cost = 0.00;
|
||||
}
|
||||
$asset->serial = $asset_serial;
|
||||
$asset->asset_tag = $item['asset_tag'];
|
||||
$asset->warranty_months = $asset_warranty_months;
|
||||
if (!empty($asset_serial)) {
|
||||
$asset->serial = $asset_serial;
|
||||
}
|
||||
if (!empty($asset_warranty_months)) {
|
||||
$asset->warranty_months = $asset_warranty_months;
|
||||
}
|
||||
|
||||
if ($asset_model) {
|
||||
$asset->model_id = $asset_model->id;
|
||||
}
|
||||
|
||||
if ($item["user"]) {
|
||||
$asset->assigned_to = $item["user"]->id;
|
||||
}
|
||||
|
||||
if ($item["location"]) {
|
||||
$asset->rtd_location_id = $item["location"]->id;
|
||||
}
|
||||
|
||||
$asset->user_id = $this->option('user_id');
|
||||
$this->log("status_id: " . $status_id);
|
||||
$asset->status_id = $status_id;
|
||||
if (!empty($status_id)) {
|
||||
$asset->status_id = $status_id;
|
||||
}
|
||||
if ($item["company"]) {
|
||||
$asset->company_id = $item["company"]->id;
|
||||
}
|
||||
$asset->order_number = $item["order_number"];
|
||||
if ($item["order_number"]) {
|
||||
$asset->order_number = $item["order_number"];
|
||||
}
|
||||
if ($supplier) {
|
||||
$asset->supplier_id = $supplier->id;
|
||||
}
|
||||
$asset->notes = $item["notes"];
|
||||
$asset->image = $asset_image;
|
||||
$this->assets->add($asset);
|
||||
if ($item["notes"]) {
|
||||
$asset->notes = $item["notes"];
|
||||
}
|
||||
if (!empty($asset_image)) {
|
||||
$asset->image = $asset_image;
|
||||
}
|
||||
if (!$editingAsset) {
|
||||
$this->assets->add($asset);
|
||||
}
|
||||
if (!$this->option('testrun')) {
|
||||
|
||||
if ($asset->save()) {
|
||||
|
@ -835,17 +875,29 @@ class ObjectImportCommand extends Command
|
|||
*/
|
||||
public function createAccessoryIfNotExists(array $item)
|
||||
{
|
||||
$accessory = null;
|
||||
$editingAccessory = false;
|
||||
$this->log("Creating Accessory");
|
||||
foreach ($this->accessories as $tempaccessory) {
|
||||
if (strcasecmp($tempaccessory->name, $item["item_name"]) == 0) {
|
||||
$this->log('A matching Accessory ' . $item["item_name"] . ' already exists. ');
|
||||
// FUTURE: Adjust quantity on import maybe?
|
||||
return;
|
||||
if (!$this->option('update')) {
|
||||
$this->log("Skipping accessory.");
|
||||
return;
|
||||
}
|
||||
$this->log('Updating matching accessory with new values');
|
||||
$editingAccessory = true;
|
||||
$accessory = $tempaccessory;
|
||||
}
|
||||
}
|
||||
if (is_null($accessory)) {
|
||||
$this->log("No Matching Accessory, Creating a new one");
|
||||
$accessory = new Accessory();
|
||||
}
|
||||
|
||||
$accessory = new Accessory();
|
||||
$accessory->name = $item["item_name"];
|
||||
if (!$editingAccessory) {
|
||||
$accessory->name = $item["item_name"];
|
||||
}
|
||||
|
||||
if (!empty($item["purchase_date"])) {
|
||||
$accessory->purchase_date = $item["purchase_date"];
|
||||
|
@ -853,10 +905,9 @@ class ObjectImportCommand extends Command
|
|||
$accessory->purchase_date = null;
|
||||
}
|
||||
if (!empty($item["purchase_cost"])) {
|
||||
$accessory->purchase_cost = number_format(e($item["purchase_cost"]), 2);
|
||||
} else {
|
||||
$accessory->purchase_cost = 0.00;
|
||||
$accessory->purchase_cost = Helper::ParseFloat($item["purchase_cost"]);
|
||||
}
|
||||
|
||||
if ($item["location"]) {
|
||||
$accessory->location_id = $item["location"]->id;
|
||||
}
|
||||
|
@ -864,20 +915,26 @@ class ObjectImportCommand extends Command
|
|||
if ($item["company"]) {
|
||||
$accessory->company_id = $item["company"]->id;
|
||||
}
|
||||
$accessory->order_number = $item["order_number"];
|
||||
if (!empty($item["order_number"])) {
|
||||
$accessory->order_number = $item["order_number"];
|
||||
}
|
||||
if ($item["category"]) {
|
||||
$accessory->category_id = $item["category"]->id;
|
||||
}
|
||||
|
||||
//TODO: Implement
|
||||
// $accessory->notes = e($item_notes);
|
||||
$accessory->requestable = filter_var($item["requestable"], FILTER_VALIDATE_BOOLEAN);
|
||||
if (!empty($item["requestable"])) {
|
||||
$accessory->requestable = filter_var($item["requestable"], FILTER_VALIDATE_BOOLEAN);
|
||||
}
|
||||
|
||||
//Must have at least zero of the item if we import it.
|
||||
if ($item["quantity"] > -1) {
|
||||
$accessory->qty = $item["quantity"];
|
||||
} else {
|
||||
$accessory->qty = 1;
|
||||
if (!empty($item["quantity"])) {
|
||||
if ($item["quantity"] > -1) {
|
||||
$accessory->qty = $item["quantity"];
|
||||
} else {
|
||||
$accessory->qty = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->option('testrun')) {
|
||||
|
@ -904,18 +961,29 @@ class ObjectImportCommand extends Command
|
|||
*/
|
||||
public function createConsumableIfNotExists(array $item)
|
||||
{
|
||||
$consumable = null;
|
||||
$editingConsumable = false;
|
||||
$this->log("Creating Consumable");
|
||||
foreach ($this->consumables as $tempconsumable) {
|
||||
if (strcasecmp($tempconsumable->name, $item["item_name"]) == 0) {
|
||||
$this->log("A matching consumable " . $item["item_name"] . " already exists");
|
||||
//TODO: Adjust quantity if different maybe?
|
||||
return;
|
||||
if (!$this->option('update')) {
|
||||
$this->log("Skipping consumable.");
|
||||
return;
|
||||
}
|
||||
$this->log('Updating matching consumable with new values');
|
||||
$editingConsumable = true;
|
||||
$consumable = $tempconsumable;
|
||||
}
|
||||
}
|
||||
|
||||
$consumable = new Consumable();
|
||||
$consumable->name = $item["item_name"];
|
||||
|
||||
if (is_null($consumable)) {
|
||||
$this->log("No matching consumable, creating one");
|
||||
$consumable = new Consumable();
|
||||
}
|
||||
if (!$editingConsumable) {
|
||||
$consumable->name = $item["item_name"];
|
||||
}
|
||||
if (!empty($item["purchase_date"])) {
|
||||
$consumable->purchase_date = $item["purchase_date"];
|
||||
} else {
|
||||
|
@ -923,26 +991,37 @@ class ObjectImportCommand extends Command
|
|||
}
|
||||
|
||||
if (!empty($item["purchase_cost"])) {
|
||||
$consumable->purchase_cost = number_format(e($item["purchase_cost"]), 2);
|
||||
} else {
|
||||
$consumable->purchase_cost = 0.00;
|
||||
$consumable->purchase_cost = Helper::ParseFloat($item["purchase_cost"]);
|
||||
}
|
||||
if ($item["location"]) {
|
||||
$consumable->location_id = $item["location"]->id;
|
||||
}
|
||||
$consumable->location_id = $item["location"]->id;
|
||||
$consumable->user_id = $this->option('user_id');
|
||||
$consumable->company_id = $item["company"]->id;
|
||||
$consumable->order_number = $item["order_number"];
|
||||
$consumable->category_id = $item["category"]->id;
|
||||
if ($item["company"]) {
|
||||
$consumable->company_id = $item["company"]->id;
|
||||
}
|
||||
if (!empty($item["order_number"])) {
|
||||
$consumable->order_number = $item["order_number"];
|
||||
}
|
||||
if ($item["category"]) {
|
||||
$consumable->category_id = $item["category"]->id;
|
||||
}
|
||||
// TODO:Implement
|
||||
//$consumable->notes= e($item_notes);
|
||||
$consumable->requestable = filter_var($item["requestable"], FILTER_VALIDATE_BOOLEAN);
|
||||
if (!empty($item["requestable"])) {
|
||||
$consumable->requestable = filter_var($item["requestable"], FILTER_VALIDATE_BOOLEAN);
|
||||
}
|
||||
|
||||
if ($item["quantity"] > -1) {
|
||||
$consumable->qty = $item["quantity"];
|
||||
} else {
|
||||
$consumable->qty = 1;
|
||||
if (!empty($item["quantity"])) {
|
||||
if ($item["quantity"] > -1) {
|
||||
$consumable->qty = $item["quantity"];
|
||||
} else {
|
||||
$consumable->qty = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->option("testrun")) {
|
||||
// dd($consumable);
|
||||
if ($consumable->save()) {
|
||||
$this->log("Consumable " . $item["item_name"] . ' was created');
|
||||
// $this->comment("Consumable " . $item["item_name"] . ' was created');
|
||||
|
@ -985,8 +1064,9 @@ class ObjectImportCommand extends Command
|
|||
array('testrun', null, InputOption::VALUE_NONE, 'If set, will parse and output data without adding to database', null),
|
||||
array('logfile', null, InputOption::VALUE_REQUIRED, 'The path to log output to. storage/logs/importer.log by default', storage_path('logs/importer.log') ),
|
||||
array('item-type', null, InputOption::VALUE_REQUIRED, 'Item Type To import. Valid Options are Asset, Consumable, Or Accessory', 'Asset'),
|
||||
array('web-importer', null, InputOption::VALUE_NONE, 'Internal: packages output for use with the web importer'),
|
||||
array('user_id', null, InputOption::VALUE_REQUIRED, 'ID of user creating items', 1)
|
||||
array('web-importer', null, InputOption::VALUE_NONE, 'Internal: packages output for use with the web importer'),
|
||||
array('user_id', null, InputOption::VALUE_REQUIRED, 'ID of user creating items', 1),
|
||||
array('update', null, InputOption::VALUE_NONE, 'If a matching item is found, update item information'),
|
||||
);
|
||||
|
||||
}
|
||||
|
|
|
@ -927,6 +927,18 @@ class AssetsController extends Controller
|
|||
|
||||
}
|
||||
|
||||
public function getDeleteImportFile($filename)
|
||||
{
|
||||
if (!Company::isCurrentUserAuthorized()) {
|
||||
return redirect()->to('hardware')->with('error', trans('general.insufficient_permissions'));
|
||||
}
|
||||
|
||||
if (unlink(config('app.private_uploads').'/imports/assets/'.$filename)) {
|
||||
return redirect()->back()->with('success', trans('admin/hardware/message.import.file_delete_success'));
|
||||
}
|
||||
return redirect()->back()->with('error', trans('admin/hardware/message.import.file_delete_error'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process the uploaded file
|
||||
|
@ -936,28 +948,47 @@ class AssetsController extends Controller
|
|||
* @since [v2.0]
|
||||
* @return Redirect
|
||||
*/
|
||||
public function getProcessImportFile($filename)
|
||||
public function postProcessImportFile()
|
||||
{
|
||||
// php artisan asset-import:csv path/to/your/file.csv --domain=yourdomain.com --email_format=firstname.lastname
|
||||
$filename = Input::get('filename');
|
||||
$itemType = Input::get('import-type');
|
||||
$updateItems = Input::get('import-update');
|
||||
|
||||
if (!Company::isCurrentUserAuthorized()) {
|
||||
return redirect()->to('hardware')->with('error', trans('general.insufficient_permissions'));
|
||||
}
|
||||
|
||||
$return = Artisan::call(
|
||||
'snipeit:import',
|
||||
['filename'=> config('app.private_uploads').'/imports/assets/'.$filename,
|
||||
$importOptions = ['filename'=> config('app.private_uploads').'/imports/assets/'.$filename,
|
||||
'--email_format'=>'firstname.lastname',
|
||||
'--username_format'=>'firstname.lastname',
|
||||
'--web-importer' => true,
|
||||
'--user_id' => Auth::user()->id
|
||||
]
|
||||
);
|
||||
'--user_id' => Auth::user()->id,
|
||||
'--item-type' => $itemType,
|
||||
];
|
||||
if ($updateItems) {
|
||||
$importOptions['--update'] = true;
|
||||
}
|
||||
|
||||
$return = Artisan::call('snipeit:import', $importOptions);
|
||||
$display_output = Artisan::output();
|
||||
$file = config('app.private_uploads').'/imports/assets/'.str_replace('.csv', '', $filename).'-output-'.date("Y-m-d-his").'.txt';
|
||||
file_put_contents($file, $display_output);
|
||||
// We use hardware instead of asset in the url
|
||||
$redirectTo = "hardware";
|
||||
switch($itemType) {
|
||||
case "asset":
|
||||
$redirectTo = "hardware";
|
||||
break;
|
||||
case "accessory":
|
||||
$redirectTo = "accessories";
|
||||
break;
|
||||
case "consumable":
|
||||
$redirectTo = "consumables";
|
||||
break;
|
||||
}
|
||||
|
||||
if ($return === 0) { //Success
|
||||
return redirect()->to('hardware')->with('success', trans('admin/hardware/message.import.success'));
|
||||
return redirect()->to(route($redirectTo))->with('success', trans('admin/hardware/message.import.success'));
|
||||
} elseif ($return === 1) { // Failure
|
||||
return redirect()->back()->with('import_errors', json_decode($display_output))->with('error', trans('admin/hardware/message.import.error'));
|
||||
}
|
||||
|
|
|
@ -293,9 +293,13 @@ Route::group(
|
|||
'uses' => 'AssetsController@getDeleteImportFile'
|
||||
]);
|
||||
|
||||
Route::get( 'import/process/{filename}', [ 'as' => 'assets/import/process-file',
|
||||
Route::post( 'import/process/', [ 'as' => 'assets/import/process-file',
|
||||
'middleware' => 'authorize:assets.create',
|
||||
'uses' => 'AssetsController@getProcessImportFile'
|
||||
'uses' => 'AssetsController@postProcessImportFile'
|
||||
]);
|
||||
Route::get( 'import/delete/{filename}', [ 'as' => 'assets/import/delete-file',
|
||||
'middleware' => 'authorize:assets.create', // TODO What permissions should this require?
|
||||
'uses' => 'AssetsController@getDeleteImportFile'
|
||||
]);
|
||||
|
||||
Route::get('import',[
|
||||
|
|
|
@ -37,9 +37,11 @@ return array(
|
|||
),
|
||||
|
||||
'import' => array(
|
||||
'error' => 'Some items did not import correctly.',
|
||||
'errorDetail' => 'The following Items were not imported because of errors.',
|
||||
'success' => "Your file has been imported",
|
||||
'error' => 'Some items did not import correctly.',
|
||||
'errorDetail' => 'The following Items were not imported because of errors.',
|
||||
'success' => "Your file has been imported",
|
||||
'file_delete_success' => "Your file has been been successfully deleted",
|
||||
'file_delete_error' => "The file was unable to be deleted",
|
||||
),
|
||||
|
||||
|
||||
|
|
|
@ -9,6 +9,49 @@
|
|||
{{-- Page content --}}
|
||||
@section('content')
|
||||
|
||||
|
||||
{{-- Modal import dialog --}}
|
||||
|
||||
<div class="modal fade" id="importModal">
|
||||
<form id="import-modal-form" class="form-horizontal" method="post" action="{{ route('assets/import/process-file') }}" autocomplete="off" role="form">
|
||||
{{ csrf_field()}}
|
||||
<input type="hidden" id="modal-filename" name="filename" value="">
|
||||
<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">Import File:</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="dynamic-form-row">
|
||||
<div class="col-md-4 col-xs-12">
|
||||
<label for="import-type">Import Type:</label>
|
||||
</div>
|
||||
<div class="col-md-8 col-xs-12">
|
||||
{{ Form::select('import-type', array('asset' => 'Assets', 'accessory' => "Accessories", 'consumable' => "Consumables") , 'asset', array('class'=>'select2 parent', 'style'=>'width:100%','id' =>'import-type')) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="dynamic-form-row">
|
||||
<div class="col-md-4 col-xs-12">
|
||||
<label for="import-update">Update Existing Values?:</label>
|
||||
</div>
|
||||
<div class="col-md-8 col-xs-12">
|
||||
{{ Form::checkbox('import-update') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">{{ trans('button.cancel') }}</button>
|
||||
<!-- <button type="button" class="btn btn-primary" id="modal-save">{{ trans('general.save') }}</button> -->
|
||||
{{Form::submit(trans('general.save'))}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="box">
|
||||
|
@ -40,8 +83,6 @@
|
|||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
|
||||
|
||||
|
||||
<table class="table table-striped" id="upload-table">
|
||||
<thead>
|
||||
<th>File</th>
|
||||
|
@ -56,8 +97,8 @@
|
|||
<td>{{ date("M d, Y g:i A", $file['modified']) }} </td>
|
||||
<td>{{ $file['filesize'] }}</td>
|
||||
<td>
|
||||
<a class="btn btn-info btn-sm" href="import/process/{{ $file['filename'] }}">
|
||||
<i class="fa fa-spinner process"></i> Process</a>
|
||||
<a href="#" data-toggle="modal" data-target="#importModal" data-filename={{$file['filename']}} class="btn btn-sm btn-info"><i class="fa fa-spinner process"></i> Process</a>
|
||||
<a class="btn btn-danger btn-sm" href="import/delete/{{ $file['filename'] }}"><i class="fa fa-trash icon-white"></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
|
@ -66,8 +107,8 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@if (session()->has('import_errors'))
|
||||
<div class="errors-table">
|
||||
<div class="alert alert-warning">
|
||||
|
@ -149,8 +190,7 @@
|
|||
$('.progress-bar-text').html('Finished!');
|
||||
$('.progress-checkmark').fadeIn('fast').html('<i class="fa fa-check fa-3x icon-white" style="color: green"></i>');
|
||||
$.each(data.result.files, function (index, file) {
|
||||
$('<tr><td>' + file.name + '</td><td>Just now</td><td>' + file.filesize + '</td><td><a class="btn btn-info btn-sm" href="import/process/' + file.name + '"><i class="fa fa-spinner process"></i> Process</a></td></tr>').prependTo("#upload-table > tbody");
|
||||
//$('<tr><td>').text(file.name).appendTo(document.body);
|
||||
$('<tr><td>' + file.name + '</td><td>Just now</td><td>' + file.filesize + '</td><td><a class="btn btn-info btn-sm" href="#" data-toggle="modal" data-target="#importModal" data-filename='+ file.name + '><i class="fa fa-spinner process"></i> Process</a><a class="btn btn-danger btn-sm" href="import/delete/' +file.name + '"><i class="fa fa-trash icon-white"></i></a></td></tr>').prependTo("#upload-table > tbody");
|
||||
});
|
||||
}
|
||||
$('#progress').removeClass('active');
|
||||
|
@ -159,6 +199,14 @@
|
|||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Modal Import options handling
|
||||
$('#importModal').on("show.bs.modal", function(event) {
|
||||
var link = $(event.relatedTarget);
|
||||
var filename = link.data('filename');
|
||||
$(this).find('.modal-title').text("Import File: " + filename );
|
||||
$("#modal-filename").val(filename);
|
||||
});
|
||||
</script>
|
||||
@stop
|
||||
|
||||
|
|
Loading…
Reference in a new issue