1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-09 20:52:56 +01:00

Datatables, Base Model, Base Presenter (#2484)

* Fixes for datatables

* Implement a BaseModel

* Working on reusable header data model

* Working on adding session variables

* Clean up header data

* Random Data Seeder

* working on searching datatables across relationships.

* Working on transforming primary keys between client and server facinglogic

* Updated assets
This commit is contained in:
David Bomba 2018-11-02 21:54:46 +11:00 committed by GitHub
parent 2d9f7b3ae6
commit d430600e1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
63 changed files with 631 additions and 293 deletions

View File

@ -49,7 +49,7 @@ class AccountController extends Controller
CreateAccount::dispatchNow($request);
//todo redirect to localization setup workflow
return redirect()->route('user.dashboard');
return redirect()->route('dashboard.index');
}

View File

@ -3,8 +3,10 @@
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Utils\Traits\UserSessionAttributes;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Laravel\Socialite\Facades\Socialite;
use Illuminate\Http\Request;
class LoginController extends Controller
{
@ -20,6 +22,7 @@ class LoginController extends Controller
*/
use AuthenticatesUsers;
use UserSessionAttributes;
/**
* Where to redirect users after login.
@ -38,6 +41,11 @@ class LoginController extends Controller
$this->middleware('guest:user')->except('logout');
}
public function authenticated(Request $request, $user)
{
$this->setCurrentCompanyId($user->companies()->first()->account->default_company_id);
}
public function redirectToProvider($provider)
{
return Socialite::driver($provider)->redirect();

View File

@ -20,16 +20,30 @@ class ClientController extends Controller
{
if (request()->ajax()) {
$clients = Client::select('clients.*', DB::raw("CONCAT(client_contacts.first_name,' ',client_contacts.last_name) as full_name"), 'client_contacts.email')
/*
$clients = Client::query('clients.*', DB::raw("CONCAT(client_contacts.first_name,' ',client_contacts.last_name) as full_name"), 'client_contacts.email')
->leftJoin('client_contacts', function($leftJoin)
{
$leftJoin->on('clients.id', '=', 'client_contacts.client_id')
->where('client_contacts.is_primary', '=', true);
});
*/
$clients = Client::query()->where('company_id', '=', $this->getCurrentCompanyId());
return DataTables::of($clients->get())
->addColumn('full_name', function ($clients) {
return $clients->contacts->where('is_primary', true)->map(function ($contact){
return $contact->first_name . ' ' . $contact->last_name;
})->all();
})
->addColumn('email', function ($clients) {
return $clients->contacts->where('is_primary', true)->map(function ($contact){
return $contact->email;
})->all();
})
->addColumn('action', function ($client) {
return '<a href="#edit-'. $client->id .'" class="btn btn-xs btn-primary"><i class="glyphicon glyphicon-edit"></i> Edit</a>';
return '<a href="/clients/'. $client->present()->id .'/edit" class="btn btn-xs btn-primary"><i class="glyphicon glyphicon-edit"></i> Edit</a>';
})
->addColumn('checkbox', function ($client){
return '<input type="checkbox" name="bulk" value="'. $client->id .'"/>';
@ -52,8 +66,16 @@ class ClientController extends Controller
['data' => 'action', 'name' => 'action', 'title' => '', 'searchable' => false, 'orderable' => false],
]);
$builder->ajax([
'url' => route('clients.index'),
'type' => 'GET',
'data' => 'function(d) { d.key = "value"; }',
]);
return view('client.list', compact('html'));
$data['header'] = $this->headerData();
$data['html'] = $html;
return view('client.list', $data);
}
/**

View File

@ -53,7 +53,7 @@ class CompanyController extends Controller
CreateCompany::dispatchNow($request);
//todo redirect to localization setup workflow
return redirect()->route('user.dashboard');
return redirect()->route('dashboard.index');
}

View File

@ -2,6 +2,8 @@
namespace App\Http\Controllers;
use App\Utils\Traits\MakesHeaderData;
use App\Utils\Traits\UserSessionAttributes;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
@ -9,5 +11,5 @@ use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
use AuthorizesRequests, DispatchesJobs, ValidatesRequests, MakesHeaderData;
}

View File

@ -2,8 +2,11 @@
namespace App\Http\Controllers;
class DashboardController extends Controller
{
/**
* Create a new controller instance.
*
@ -22,7 +25,9 @@ class DashboardController extends Controller
*/
public function index()
{
return view('dashboard.index');
$data['header'] = $this->headerData();
return view('dashboard.index', $data);
}

View File

@ -20,7 +20,7 @@ trait VerifiesUserEmail
Auth::loginUsingId($user->id, true);
return redirect()->route('user.dashboard')->with('message', trans('texts.security_confirmation'));
return redirect()->route('dashboard.index')->with('message', trans('texts.security_confirmation'));
}

View File

@ -0,0 +1,84 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserProfileController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
//
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
//
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
//
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
}
}

View File

@ -25,7 +25,7 @@ class RedirectIfAuthenticated
break;
case 'user':
if (Auth::guard($guard)->check()) {
return redirect()->route('user.dashboard');
return redirect()->route('dashboard.index');
}
break;
default:

View File

@ -0,0 +1,30 @@
<?php
namespace App\Http\Requests\Client;
use App\Http\Requests\Request;
use App\Utils\Traits\MakesHash;
class CreateAccountRequest extends Request
{
use MakesHash;
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function entity()
{
parent::entity(Client::class, $this->decodePrimaryKey(request()))
}
public function authorize()
{
return ! auth()->user(); //todo permissions
}
}

View File

@ -5,13 +5,10 @@ namespace App\Jobs\Account;
use App\Events\Account\AccountCreated;
use App\Jobs\User\CreateUser;
use App\Jobs\Company\CreateCompany;
use App\Models\UserCompany;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Http\Request;
use App\Models\Account;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
class CreateAccount
{

View File

@ -2,17 +2,11 @@
namespace App\Jobs\Company;
use App\Events\Company\CompanyCreated;
use App\Events\UserSignedUp;
use App\Jobs\Account\CreateAccount;
use App\Utils\Traits\MakesHash;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Http\Request;
use App\Models\Account;
use App\Models\Company;
use App\Models\User;
use App\Models\UserCompany;
use Illuminate\Support\Facades\Hash;
class CreateCompany
{

View File

@ -4,12 +4,10 @@ namespace App\Jobs\User;
use App\Events\User\UserCreated;
use App\Models\User;
use App\Models\UserCompany;
use App\Models\CompanyUser;
use App\Utils\Traits\MakesHash;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Http\Request;
use App\Models\Account;
use Illuminate\Support\Facades\Hash;
class CreateUser
{
@ -53,7 +51,7 @@ class CreateUser
$user->save();
UserCompany::create([
CompanyUser::create([
'user_id' => $user->id,
'account_id' => $this->account->id,
'company_id' => $this->company->id,

View File

@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Laracasts\Presenter\PresentableTrait;
class Account extends Model
class Account extends BaseModel
{
use SoftDeletes;
use PresentableTrait;
@ -45,10 +45,6 @@ class Account extends Model
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function companies()
{
return $this->hasMany(Company::class);
}
public function default_company()
{

View File

@ -4,7 +4,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class AccountGateway extends Model
class AccountGateway extends BaseModel
{
//
}

View File

@ -7,7 +7,7 @@ use Illuminate\Database\Eloquent\Model;
/**
* Class Bank.
*/
class Bank extends Model
class Bank extends BaseModel
{
/**
* @var bool

View File

@ -9,7 +9,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
/**
* Class BankAccount.
*/
class BankAccount extends Model
class BankAccount extends BaseModel
{
use SoftDeletes;

View File

@ -8,7 +8,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
/**
* Class BankSubaccount.
*/
class BankSubaccount extends Model
class BankSubaccount extends BaseModel
{
use SoftDeletes;
/**

19
app/Models/BaseModel.php Normal file
View File

@ -0,0 +1,19 @@
<?php
namespace App\Models;
use Hashids\Hashids;
use Illuminate\Database\Eloquent\Model;
class BaseModel extends Model
{
/*
public function setIdAttribute($value)
{
$hashids = new Hashids(); //decoded output is _always_ an array.
$hashed_id_array = $hashids->decode($value);
$this->attributes['id'] = strtolower($hashed_id_array[0]);
}
*/
}

View File

@ -2,10 +2,14 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Laracasts\Presenter\PresentableTrait;
class Client extends Model
class Client extends BaseModel
{
use PresentableTrait;
protected $presenter = 'App\Models\Presenters\ClientPresenter';
public function contacts()
{

View File

@ -2,6 +2,7 @@
namespace App\Models;
use Hashids\Hashids;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
@ -37,4 +38,9 @@ class ClientContact extends Authenticatable
$this->hasOne(Client::class);
}
public function primary_contact()
{
$this->where('is_primary', true);
}
}

View File

@ -4,7 +4,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class ClientLocation extends Model
class ClientLocation extends BaseModel
{
public $timestamps = false;
}

View File

@ -4,9 +4,14 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Models\Traits\AccountTrait;
use Laracasts\Presenter\PresentableTrait;
class Company extends Model
class Company extends BaseModel
{
use PresentableTrait;
protected $presenter = 'App\Models\Presenters\CompanyPresenter';
protected $fillable = [
@ -37,7 +42,7 @@ class Company extends Model
public function account()
{
return $this->hasOne(Account::class);
return $this->belongsTo(Account::class);
}

View File

@ -0,0 +1,18 @@
<?php
namespace App\Models;
class CompanyUser extends BaseModel
{
protected $guarded = ['id'];
public function account()
{
return $this->hasOne(Account::class);
}
public function user()
{
return $this->hasOne(User::class);
}
}

View File

@ -4,7 +4,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Country extends Model
class Country extends BaseModel
{
public $timestamps = false;

View File

@ -4,7 +4,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Currency extends Model
class Currency extends BaseModel
{
public $timestamps = false;

View File

@ -4,7 +4,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Expense extends Model
class Expense extends BaseModel
{
//
}

View File

@ -4,7 +4,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Gateway extends Model
class Gateway extends BaseModel
{
//
}

View File

@ -4,7 +4,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Industry extends Model
class Industry extends BaseModel
{
//
}

View File

@ -4,7 +4,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Invitation extends Model
class Invitation extends BaseModel
{
@ -16,7 +16,7 @@ class Invitation extends Model
public function proposals()
{
return $this->morphedByMany(Proposal::class, 'taggable');
return $this->morphedByMany(Proposal::class, 'inviteable');
}
}

View File

@ -4,7 +4,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Invoice extends Model
class Invoice extends BaseModel
{
//

View File

@ -4,7 +4,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Language extends Model
class Language extends BaseModel
{
public $timestamps = false;

View File

@ -4,7 +4,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Payment extends Model
class Payment extends BaseModel
{
//
}

View File

@ -7,7 +7,7 @@ use Illuminate\Database\Eloquent\Model;
/**
* Class PaymentLibrary.
*/
class PaymentLibrary extends Model
class PaymentLibrary extends BaseModel
{
/**

View File

@ -4,7 +4,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class PaymentType extends Model
class PaymentType extends BaseModel
{
//
}

View File

@ -0,0 +1,9 @@
<?php
namespace App\Models\Presenters;
class ClientPresenter extends EntityPresenter
{
}

View File

@ -0,0 +1,13 @@
<?php
namespace App\Models\Presenters;
class CompanyPresenter extends EntityPresenter
{
public function name()
{
return $this->entity->name ?: trans('texts.untitled_account');
}
}

View File

@ -2,6 +2,8 @@
namespace App\Models\Presenters;
use App\Utils\Traits\MakesHash;
use Hashids\Hashids;
use Laracasts\Presenter\Presenter;
use URL;
use Utils;
@ -9,13 +11,18 @@ use stdClass;
class EntityPresenter extends Presenter
{
use MakesHash;
public function id()
{
return $this->encodePrimaryKey($this->entity->id);
}
public function url()
{
}
public function path()
{

View File

@ -1,6 +1,6 @@
<?php
namespace App\models\Presenters;
namespace App\Models\Presenters;
class UserPresenter extends EntityPresenter
{

View File

@ -4,7 +4,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
class Product extends BaseModel
{
//
}

View File

@ -4,7 +4,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Proposal extends Model
class Proposal extends BaseModel
{
//

View File

@ -4,7 +4,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Task extends Model
class Task extends BaseModel
{
//
}

View File

@ -4,7 +4,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class TaxRate extends Model
class TaxRate extends BaseModel
{
//
}

View File

@ -4,7 +4,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Timezone extends Model
class Timezone extends BaseModel
{
/**
* @var bool

View File

@ -2,6 +2,7 @@
namespace App\Models;
use App\Models\Traits\SetsUserSessionAttributes;
use App\Models\Traits\UserTrait;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Notifications\Notifiable;
@ -21,7 +22,6 @@ class User extends Authenticatable implements MustVerifyEmail
protected $presenter = 'App\Models\Presenters\UserPresenter';
/**
* The attributes that are mass assignable.
*
@ -52,14 +52,11 @@ class User extends Authenticatable implements MustVerifyEmail
'slack_webhook_url',
];
public function account()
{
return $this->hasOne(Account::class);
}
public function user_companies()
public function companies()
{
return $this->hasMany(UserCompany::class);
return $this->belongsToMany(Company::class);
}
public function contacts()

View File

@ -1,11 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class UserCompany extends Model
{
protected $guarded = ['id'];
}

View File

@ -40,4 +40,20 @@ trait MakesHash
return $hashids->encode( str_replace( MultiDB::DB_PREFIX, "", $db ) );
}
public function encodePrimaryKey($value)
{
$hashids = new Hashids();
return $hashids->encode($value);
}
public function decodePrimaryKey($value)
{
$hashids = new Hashids();
$decoded_array = $hashids->decode($value);
return $decoded_array[0];
}
}

View File

@ -0,0 +1,32 @@
<?php
namespace App\Utils\Traits;
use Illuminate\Support\Facades\Auth;
/**
* Class MakesHash
* @package App\Utils\Traits
*/
trait MakesHeaderData
{
use UserSessionAttributes;
public function headerData()
{
//companies
$companies = Auth::user()->companies;
$data['current_company'] = $companies->first(function ($company){
return $company->id == $this->getCurrentCompanyId();
});
$data['companies'] = $companies->reject(function ($company){
return $company->id == $this->getCurrentCompanyId();
});
return $data;
}
}

View File

@ -0,0 +1,19 @@
<?php
namespace App\Utils\Traits;
trait UserSessionAttributes
{
public function setCurrentCompanyId($value)
{
session(['current_company_id' => $value]);
}
public function getCurrentCompanyId()
{
return session('current_company_id');
}
}

178
composer.lock generated
View File

@ -8,16 +8,16 @@
"packages": [
{
"name": "asgrim/ofxparser",
"version": "1.2.1",
"version": "1.2.2",
"source": {
"type": "git",
"url": "https://github.com/asgrim/ofxparser.git",
"reference": "8ba143295be666ae2cac05674f7d526d8e0ebed7"
"reference": "a7cc813eed19df612fc58bbe9fc89837ed98b3bf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/asgrim/ofxparser/zipball/8ba143295be666ae2cac05674f7d526d8e0ebed7",
"reference": "8ba143295be666ae2cac05674f7d526d8e0ebed7",
"url": "https://api.github.com/repos/asgrim/ofxparser/zipball/a7cc813eed19df612fc58bbe9fc89837ed98b3bf",
"reference": "a7cc813eed19df612fc58bbe9fc89837ed98b3bf",
"shasum": ""
},
"require": {
@ -60,20 +60,20 @@
"open financial exchange",
"parser"
],
"time": "2016-09-26T11:36:23+00:00"
"time": "2018-10-29T10:10:13+00:00"
},
{
"name": "davejamesmiller/laravel-breadcrumbs",
"version": "5.1.2",
"version": "5.2.0",
"source": {
"type": "git",
"url": "https://github.com/davejamesmiller/laravel-breadcrumbs.git",
"reference": "f24853b97d9f973a9b936d2692f93b11924415e2"
"reference": "e2ed8b0992231ebc61480c63f095a2cf3b8829a1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/davejamesmiller/laravel-breadcrumbs/zipball/f24853b97d9f973a9b936d2692f93b11924415e2",
"reference": "f24853b97d9f973a9b936d2692f93b11924415e2",
"url": "https://api.github.com/repos/davejamesmiller/laravel-breadcrumbs/zipball/e2ed8b0992231ebc61480c63f095a2cf3b8829a1",
"reference": "e2ed8b0992231ebc61480c63f095a2cf3b8829a1",
"shasum": ""
},
"require": {
@ -110,8 +110,7 @@
"authors": [
{
"name": "Dave James Miller",
"email": "dave@davejamesmiller.com",
"homepage": "https://davejamesmiller.com/"
"email": "dave@davejamesmiller.com"
}
],
"description": "A simple Laravel-style way to create breadcrumbs.",
@ -119,7 +118,7 @@
"keywords": [
"laravel"
],
"time": "2018-09-14T06:29:58+00:00"
"time": "2018-10-30T22:06:33+00:00"
},
{
"name": "dnoegel/php-xdg-base-dir",
@ -862,16 +861,16 @@
},
{
"name": "laravel/framework",
"version": "v5.7.11",
"version": "v5.7.12",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
"reference": "52ee19c53c4fcd7fea8a83aacae5b8bc212ae19b"
"reference": "4cb5bf13e0cd50015f8e6a420a52fa8b90758eb1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/52ee19c53c4fcd7fea8a83aacae5b8bc212ae19b",
"reference": "52ee19c53c4fcd7fea8a83aacae5b8bc212ae19b",
"url": "https://api.github.com/repos/laravel/framework/zipball/4cb5bf13e0cd50015f8e6a420a52fa8b90758eb1",
"reference": "4cb5bf13e0cd50015f8e6a420a52fa8b90758eb1",
"shasum": ""
},
"require": {
@ -1001,7 +1000,7 @@
"framework",
"laravel"
],
"time": "2018-10-24T12:50:20+00:00"
"time": "2018-10-30T14:44:34+00:00"
},
{
"name": "laravel/socialite",
@ -1410,16 +1409,16 @@
},
{
"name": "maatwebsite/excel",
"version": "3.1.2",
"version": "3.1.3",
"source": {
"type": "git",
"url": "https://github.com/Maatwebsite/Laravel-Excel.git",
"reference": "a80179c3f33d06fc0d7f22891d6aae4bb083f8c3"
"reference": "74be22caef59b3479465008f34cdbf231aae58ac"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Maatwebsite/Laravel-Excel/zipball/a80179c3f33d06fc0d7f22891d6aae4bb083f8c3",
"reference": "a80179c3f33d06fc0d7f22891d6aae4bb083f8c3",
"url": "https://api.github.com/repos/Maatwebsite/Laravel-Excel/zipball/74be22caef59b3479465008f34cdbf231aae58ac",
"reference": "74be22caef59b3479465008f34cdbf231aae58ac",
"shasum": ""
},
"require": {
@ -1472,7 +1471,7 @@
"php",
"phpspreadsheet"
],
"time": "2018-10-11T09:21:58+00:00"
"time": "2018-11-01T10:33:16+00:00"
},
{
"name": "markbaker/complex",
@ -2975,7 +2974,7 @@
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.9.0",
"version": "v1.10.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
@ -3033,16 +3032,16 @@
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.9.0",
"version": "v1.10.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8"
"reference": "c79c051f5b3a46be09205c73b80b346e4153e494"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d0cd638f4634c16d8df4508e847f14e9e43168b8",
"reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494",
"reference": "c79c051f5b3a46be09205c73b80b346e4153e494",
"shasum": ""
},
"require": {
@ -3088,20 +3087,20 @@
"portable",
"shim"
],
"time": "2018-08-06T14:22:27+00:00"
"time": "2018-09-21T13:07:52+00:00"
},
{
"name": "symfony/polyfill-php72",
"version": "v1.9.0",
"version": "v1.10.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php72.git",
"reference": "95c50420b0baed23852452a7f0c7b527303ed5ae"
"reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/95c50420b0baed23852452a7f0c7b527303ed5ae",
"reference": "95c50420b0baed23852452a7f0c7b527303ed5ae",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9050816e2ca34a8e916c3a0ae8b9c2fccf68b631",
"reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631",
"shasum": ""
},
"require": {
@ -3143,7 +3142,7 @@
"portable",
"shim"
],
"time": "2018-08-06T14:22:27+00:00"
"time": "2018-09-21T13:07:52+00:00"
},
{
"name": "symfony/process",
@ -3600,21 +3599,22 @@
},
{
"name": "yajra/laravel-datatables",
"version": "v1.1.0",
"version": "v1.2.0",
"source": {
"type": "git",
"url": "https://github.com/yajra/datatables.git",
"reference": "a5e2eaac3d7bc155502a37ab490cbcf0dee63e06"
"reference": "060c1ef2dc8b3e688852698ca263e6130a2239e5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/yajra/datatables/zipball/a5e2eaac3d7bc155502a37ab490cbcf0dee63e06",
"reference": "a5e2eaac3d7bc155502a37ab490cbcf0dee63e06",
"url": "https://api.github.com/repos/yajra/datatables/zipball/060c1ef2dc8b3e688852698ca263e6130a2239e5",
"reference": "060c1ef2dc8b3e688852698ca263e6130a2239e5",
"shasum": ""
},
"require": {
"php": ">=7.0",
"yajra/laravel-datatables-buttons": "3.*|4.*",
"yajra/laravel-datatables-editor": "1.*",
"yajra/laravel-datatables-fractal": "1.*",
"yajra/laravel-datatables-html": "3.*",
"yajra/laravel-datatables-oracle": "8.*"
@ -3641,7 +3641,7 @@
"jquery",
"laravel"
],
"time": "2018-08-15T12:31:12+00:00"
"time": "2018-11-02T03:53:13+00:00"
},
{
"name": "yajra/laravel-datatables-buttons",
@ -3707,6 +3707,68 @@
],
"time": "2018-10-06T02:23:34+00:00"
},
{
"name": "yajra/laravel-datatables-editor",
"version": "v1.5.0",
"source": {
"type": "git",
"url": "https://github.com/yajra/laravel-datatables-editor.git",
"reference": "14db7b99172fa4afc830e6ee4e8093c3f3bc3a61"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/yajra/laravel-datatables-editor/zipball/14db7b99172fa4afc830e6ee4e8093c3f3bc3a61",
"reference": "14db7b99172fa4afc830e6ee4e8093c3f3bc3a61",
"shasum": ""
},
"require": {
"illuminate/console": "5.5.*|5.6.*|5.7.*",
"illuminate/database": "5.5.*|5.6.*|5.7.*",
"illuminate/http": "5.5.*|5.6.*|5.7.*",
"illuminate/validation": "5.5.*|5.6.*|5.7.*",
"php": ">=7.0",
"yajra/laravel-datatables-buttons": "3.*|4.*"
},
"require-dev": {
"orchestra/testbench": "~3.5"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
},
"laravel": {
"providers": [
"Yajra\\DataTables\\EditorServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Yajra\\DataTables\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Arjay Angeles",
"email": "aqangeles@gmail.com"
}
],
"description": "Laravel DataTables Editor plugin for Laravel 5.5+.",
"keywords": [
"JS",
"datatables",
"editor",
"html",
"jquery",
"laravel"
],
"time": "2018-09-05T06:13:38+00:00"
},
{
"name": "yajra/laravel-datatables-fractal",
"version": "v1.2.1",
@ -3767,16 +3829,16 @@
},
{
"name": "yajra/laravel-datatables-html",
"version": "v3.8.0",
"version": "v3.9.0",
"source": {
"type": "git",
"url": "https://github.com/yajra/laravel-datatables-html.git",
"reference": "84a3b61e0ecba78108c55a508db150e8c8db2e59"
"reference": "032e9ab02717ab9ff0339dfa0e3a04dfca4267bd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/yajra/laravel-datatables-html/zipball/84a3b61e0ecba78108c55a508db150e8c8db2e59",
"reference": "84a3b61e0ecba78108c55a508db150e8c8db2e59",
"url": "https://api.github.com/repos/yajra/laravel-datatables-html/zipball/032e9ab02717ab9ff0339dfa0e3a04dfca4267bd",
"reference": "032e9ab02717ab9ff0339dfa0e3a04dfca4267bd",
"shasum": ""
},
"require": {
@ -3822,20 +3884,20 @@
"jquery",
"laravel"
],
"time": "2018-09-05T06:10:14+00:00"
"time": "2018-11-02T01:43:32+00:00"
},
{
"name": "yajra/laravel-datatables-oracle",
"version": "v8.9.1",
"version": "v8.9.2",
"source": {
"type": "git",
"url": "https://github.com/yajra/laravel-datatables.git",
"reference": "851c4d4d307a66a4f8ab5c12444c1eb0104ecc80"
"reference": "3b084b9b7b4aac46f0bfc2d71b9b3a67d794f4e9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/yajra/laravel-datatables/zipball/851c4d4d307a66a4f8ab5c12444c1eb0104ecc80",
"reference": "851c4d4d307a66a4f8ab5c12444c1eb0104ecc80",
"url": "https://api.github.com/repos/yajra/laravel-datatables/zipball/3b084b9b7b4aac46f0bfc2d71b9b3a67d794f4e9",
"reference": "3b084b9b7b4aac46f0bfc2d71b9b3a67d794f4e9",
"shasum": ""
},
"require": {
@ -3893,7 +3955,7 @@
"jquery",
"laravel"
],
"time": "2018-10-05T06:10:33+00:00"
"time": "2018-10-30T14:23:18+00:00"
}
],
"packages-dev": [
@ -4787,16 +4849,16 @@
},
{
"name": "phpunit/php-code-coverage",
"version": "6.1.3",
"version": "6.1.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "4d3ae9b21a7d7e440bd0cf65565533117976859f"
"reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/4d3ae9b21a7d7e440bd0cf65565533117976859f",
"reference": "4d3ae9b21a7d7e440bd0cf65565533117976859f",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
"reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
"shasum": ""
},
"require": {
@ -4846,7 +4908,7 @@
"testing",
"xunit"
],
"time": "2018-10-23T05:59:32+00:00"
"time": "2018-10-31T16:06:48+00:00"
},
{
"name": "phpunit/php-file-iterator",
@ -4990,16 +5052,16 @@
},
{
"name": "phpunit/php-token-stream",
"version": "3.0.0",
"version": "3.0.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
"reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace"
"reference": "c99e3be9d3e85f60646f152f9002d46ed7770d18"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/21ad88bbba7c3d93530d93994e0a33cd45f02ace",
"reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace",
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/c99e3be9d3e85f60646f152f9002d46ed7770d18",
"reference": "c99e3be9d3e85f60646f152f9002d46ed7770d18",
"shasum": ""
},
"require": {
@ -5035,7 +5097,7 @@
"keywords": [
"tokenizer"
],
"time": "2018-02-01T13:16:43+00:00"
"time": "2018-10-30T05:52:18+00:00"
},
{
"name": "phpunit/phpunit",

View File

@ -5,8 +5,8 @@ return [
* Default table attributes when generating the table.
*/
'table' => [
'class' => 'table',
'id' => 'table table-striped table-bordered',
'class' => 'table table-hover',
'id' => 'ninja',
],
/*
* Default condition to determine if a parameter is a callback or not

View File

@ -1,92 +0,0 @@
<?php
use Laravel\Telescope\Watchers;
use Laravel\Telescope\Http\Middleware\Authorize;
return [
'path' => 'telescope',
/*
|--------------------------------------------------------------------------
| Telescope Storage Driver
|--------------------------------------------------------------------------
|
| This configuration options determines the storage driver that will
| be used to store Telescope's data. In addition, you may set any
| custom options as needed by the particular driver you choose.
|
*/
'driver' => env('TELESCOPE_DRIVER', 'database'),
'storage' => [
'database' => [
'connection' => env('DB_CONNECTION', 'mysql'),
]
],
/*
|--------------------------------------------------------------------------
| Record Pruning
|--------------------------------------------------------------------------
|
| This configuration options determines how many Telescope records of
| a given type will be kept in storage. This allows you to control
| the amount of disk space claimed by Telescope's entry storage.
|
| When "null", records will not be pruned.
|
*/
'limit' => env('TELESCOPE_LIMIT', null),
/*
|--------------------------------------------------------------------------
| Telescope Route Middleware
|--------------------------------------------------------------------------
|
| These middleware will be assigned to every Telescope route, giving you
| the chance to add your own middleware to this list or change any of
| the existing middleware. Or, you can simply stick with this list.
|
*/
'middleware' => [
'web',
Authorize::class,
],
/*
|--------------------------------------------------------------------------
| Telescope Watchers
|--------------------------------------------------------------------------
|
| The following array lists the "watchers" that will be registered with
| Telescope. The watchers gather the application's profile data when
| a request or task is executed. Feel free to customize this list.
|
*/
'watchers' => [
Watchers\CacheWatcher::class => env('TELESCOPE_CACHE_WATCHER', true),
Watchers\CommandWatcher::class => env('TELESCOPE_COMMAND_WATCHER', true),
Watchers\DumpWatcher::class => env('TELESCOPE_DUMP_WATCHER', true),
Watchers\EventWatcher::class => env('TELESCOPE_EVENT_WATCHER', true),
Watchers\ExceptionWatcher::class => env('TELESCOPE_EXCEPTION_WATCHER', true),
Watchers\JobWatcher::class => env('TELESCOPE_JOB_WATCHER', true),
Watchers\LogWatcher::class => env('TELESCOPE_LOG_WATCHER', true),
Watchers\MailWatcher::class => env('TELESCOPE_MAIL_WATCHER', true),
Watchers\ModelWatcher::class => env('TELESCOPE_MODEL_WATCHER', true),
Watchers\NotificationWatcher::class => env('TELESCOPE_NOTIFICATION_WATCHER', true),
Watchers\QueryWatcher::class => [
'enabled' => env('TELESCOPE_QUERY_WATCHER', true),
'slow' => 100,
],
Watchers\RedisWatcher::class => env('TELESCOPE_REDIS_WATCHER', true),
Watchers\RequestWatcher::class => env('TELESCOPE_REQUEST_WATCHER', true),
Watchers\ScheduleWatcher::class => env('TELESCOPE_SCHEDULE_WATCHER', true),
],
];

View File

@ -153,7 +153,7 @@ class CreateUsersTable extends Migration
});
Schema::create('user_companies', function (Blueprint $table) {
Schema::create('company_user', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('company_id');
$table->unsignedInteger('account_id');

View File

@ -0,0 +1,93 @@
<?php
use App\Models\Account;
use App\Models\Client;
use App\Models\ClientContact;
use App\Models\User;
use App\Models\UserAccount;
use Illuminate\Database\Seeder;
class RandomDataSeeder extends Seeder
{
use \App\Utils\Traits\MakesHash;
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$this->command->info('Running RandomDataSeeder');
Eloquent::unguard();
$faker = Faker\Factory::create();
$account = factory(\App\Models\Account::class)->create();
$company = factory(\App\Models\Company::class)->create([
'account_id' => $account->id,
]);
$account->default_company_id = $company->id;
$account->save();
$user = factory(\App\Models\User::class)->create([
'email' => $faker->email,
'account_id' => $account->id,
'confirmation_code' => $this->createDbHash(config('database.default'))
]);
$user->companies()->attach($company->id, [
'account_id' => $account->id,
'is_owner' => 1,
'is_admin' => 1,
'is_locked' => 0,
]);
$client = factory(\App\Models\Client::class)->create([
'user_id' => $user->id,
'company_id' => $company->id
]);
ClientContact::create([
'first_name' => $faker->firstName,
'last_name' => $faker->lastName,
'email' => $faker->email,
'company_id' => $company->id,
'password' => Hash::make(config('ninja.testvars.password')),
'email_verified_at' => now(),
'client_id' =>$client->id,
]);
factory(\App\Models\Client::class, 500)->create(['user_id' => $user->id, 'company_id' => $company->id])->each(function ($c) use ($user, $company){
factory(\App\Models\ClientContact::class,1)->create([
'user_id' => $user->id,
'client_id' => $c->id,
'company_id' => $company->id,
'is_primary' => 1
]);
factory(\App\Models\ClientContact::class,100)->create([
'user_id' => $user->id,
'client_id' => $c->id,
'company_id' => $company->id
]);
factory(\App\Models\ClientLocation::class,1)->create([
'client_id' => $c->id,
'is_primary' => 1
]);
factory(\App\Models\ClientLocation::class,100)->create([
'client_id' => $c->id,
]);
});
}
}

View File

@ -18,9 +18,7 @@ class UsersTableSeeder extends Seeder
public function run()
{
//require_once app_path() . '/Constants.php';
$this->command->info('Running UserTableSeeder');
$this->command->info('Running UsersTableSeeder');
Eloquent::unguard();
@ -39,6 +37,13 @@ class UsersTableSeeder extends Seeder
'confirmation_code' => $this->createDbHash(config('database.default'))
]);
$user->companies()->attach($company->id, [
'account_id' => $account->id,
'is_owner' => 1,
'is_admin' => 1,
'is_locked' => 0,
]);
$client = factory(\App\Models\Client::class)->create([
'user_id' => $user->id,
'company_id' => $company->id
@ -55,15 +60,6 @@ class UsersTableSeeder extends Seeder
'client_id' =>$client->id,
]);
\App\Models\UserCompany::create([
'account_id' => $account->id,
'company_id' => $company->id,
'user_id' => $user->id,
'is_owner' => 1,
'is_admin' => 1,
'is_locked' => 0,
]);
factory(\App\Models\Client::class, 50)->create(['user_id' => $user->id, 'company_id' => $company->id])->each(function ($c) use ($user, $company){

File diff suppressed because one or more lines are too long

8
public/js/ninja.js vendored

File diff suppressed because one or more lines are too long

View File

@ -7,7 +7,7 @@
@endsection
@section('header')
@include('header')
@include('header', $header)
@parent
@endsection

View File

@ -1,7 +1,7 @@
@extends('layouts.master')
@section('header')
@include('header')
@include('header', $header)
@endsection
@ -16,8 +16,6 @@
<div class="container-fluid">
</div>
</main>

View File

@ -12,7 +12,7 @@
</button>
<ul class="nav navbar-nav ml-auto">
<li class="nav-item dropdown d-md-down-none">
<li class="nav-item dropdown d-md-down-none" style="padding-left:20px; padding-right: 20px;">
<a class="nav-link" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">
<i class="icon-list"></i>
<span class="badge badge-pill badge-warning">15</span>
@ -26,47 +26,47 @@
<span class="float-right">
<strong>0%</strong>
</span>
</div>
</div>
<span class="progress progress-xs">
<div class="progress-bar bg-info" role="progressbar" style="width: 0%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
<div class="progress-bar bg-info" role="progressbar" style="width: 0%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
</span>
</a>
<a class="dropdown-item" href="#">
<div class="small mb-1">First, wash all car.
</a>
<a class="dropdown-item" href="#">
<div class="small mb-1">First, wash all car.
<span class="float-right">
<strong>25%</strong>
</span>
</div>
</div>
<span class="progress progress-xs">
<div class="progress-bar bg-danger" role="progressbar" style="width: 25%" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div>
</span>
</a>
<a class="dropdown-item" href="#">
<div class="small mb-1">Then wax. Wax on...
</a>
<a class="dropdown-item" href="#">
<div class="small mb-1">Then wax. Wax on...
<span class="float-right">
<strong>50%</strong>
</span>
</div>
</div>
<span class="progress progress-xs">
<div class="progress-bar bg-warning" role="progressbar" style="width: 50%" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100"></div>
<div class="progress-bar bg-warning" role="progressbar" style="width: 50%" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100"></div>
</span>
</a>
<a class="dropdown-item" href="#">
<div class="small mb-1">No questions!
</a>
<a class="dropdown-item" href="#">
<div class="small mb-1">No questions!
<span class="float-right">
<strong>75%</strong>
</span>
</div>
</div>
<span class="progress progress-xs">
<div class="progress-bar bg-info" role="progressbar" style="width: 75%" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100"></div>
</span>
</a>
<a class="dropdown-item" href="#">
<div class="small mb-1">Wax on... wax off. Wax on... wax off.
</a>
<a class="dropdown-item" href="#">
<div class="small mb-1">Wax on... wax off. Wax on... wax off.
<span class="float-right">
<strong>100%</strong>
</span>
</div>
</div>
<span class="progress progress-xs">
<div class="progress-bar bg-success" role="progressbar" style="width: 100%" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100"></div>
</span>
@ -77,32 +77,42 @@
</div>
</li>
<li class="nav-item dropdown d-md-down-none" style="padding-left:20px; padding-right: 20px;">
<a class="nav-link" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-building" aria-hidden="true"></i> {{ $current_company->present()->name() }}
</a>
<div class="dropdown-menu dropdown-menu-right dropdown-menu-lg">
<div class="dropdown-header text-center">
<strong>@lang('texts.manage_companies')</strong>
</div>
@foreach($companies as $company) <!-- List all remaining companies here-->
<a class="dropdown-item" href="#">
<div class="small mb-1">{{ $company->present()->name }}
<span class="float-right">
</span>
</div>
<span class="progress progress-xs">
<div class="progress-bar bg-info" role="progressbar" style="width: 0%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
</span>
</a>
@endforeach
<div class="dropdown-divider"></div>
<!-- Add Company-->
@if(count($companies) < 5)
<a class="dropdown-item" href="{{ route('user.logout') }}">
<i class="fa fa-plus"></i> @lang('texts.add_company')</a>
@endif
</div>
</li>
<li class="nav-item dropdown">
<a class="nav-link" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">
<img class="img-avatar" src="images/logo.png" alt="admin@bootstrapmaster.com"> {{ auth()->user()->present()->name }}
<img class="img-avatar" src="images/logo.png" alt=""> {{ auth()->user()->present()->name }}
</a>
<div class="dropdown-menu dropdown-menu-right">
<!-- if multiple accounts exist, loop through here and display
<div class="dropdown-header text-center">
<strong>Accounts</strong>
</div>
<a class="dropdown-item" href="#">
<i class="fa fa-bell-o"></i> Updates
<span class="badge badge-info">42</span>
</a>
<a class="dropdown-item" href="#">
<i class="fa fa-envelope-o"></i> Messages
<span class="badge badge-success">42</span>
</a>
<a class="dropdown-item" href="#">
<i class="fa fa-tasks"></i> Tasks
<span class="badge badge-danger">42</span>
</a>
<a class="dropdown-item" href="#">
<i class="fa fa-comments"></i> Comments
<span class="badge badge-warning">42</span>
</a>
<!-- if multiple accounts exist, loop through here and display -->
<div class="dropdown-header text-center">
<strong>Settings</strong>
</div>

View File

@ -3,7 +3,7 @@
<ul class="nav">
<li class="nav-item ">
<a class="nav-link" href="{{ route('user.dashboard') }}">
<a class="nav-link" href="{{ route('dashboard.index') }}">
<i class="nav-icon icon-speedometer"></i> @lang('texts.dashboard')
</a>
</li>

View File

@ -2,7 +2,7 @@
// Dashboard
Breadcrumbs::for('dashboard', function ($trail) {
$trail->push(trans('texts.dashboard'), route('user.dashboard'));
$trail->push(trans('texts.dashboard'), route('dashboard.index'));
});
// Dashboard > Client

View File

@ -40,10 +40,11 @@ Route::get('auth/{provider}/callback', 'Auth\LoginController@handleProviderCallb
Route::group(['middleware' => ['auth:user', 'db']], function () {
Route::get('dashboard', 'DashboardController@index')->name('user.dashboard');
Route::resource('dashboard', 'DashboardController'); // name = (dashboard. index / create / show / update / destroy / edit
Route::get('logout', 'Auth\LoginController@logout')->name('user.logout');
Route::resource('invoices', 'InvoiceController'); // name = (invoices. index / create / show / update / destroy / edit
Route::resource('clients', 'ClientController'); // name = (clients. index / create / show / update / destroy / edit
Route::resource('user', 'UserProfileController'); // name = (clients. index / create / show / update / destroy / edit
Route::get('settings', 'SettingsController@index')->name('user.settings');