Access module relations from parent (#2553)
* Refactor JS directory structure * Access Module relations from Parent entity
This commit is contained in:
parent
bdb0f43d33
commit
95f1d24b8f
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'client' => [
|
||||||
|
'notes' => function ($self) {
|
||||||
|
return $self->hasMany('Modules\Notes\Entities\Note');
|
||||||
|
}
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
@ -17,8 +17,10 @@ class NotesTable extends Migration
|
||||||
$table->increments('id');
|
$table->increments('id');
|
||||||
$table->unsignedInteger('client_id')->index();
|
$table->unsignedInteger('client_id')->index();
|
||||||
$table->unsignedInteger('user_id')->index();
|
$table->unsignedInteger('user_id')->index();
|
||||||
|
$table->unsignedInteger('company_id')->index();
|
||||||
$table->string('description');
|
$table->string('description');
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
|
$table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade');
|
||||||
$table->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
|
$table->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
|
||||||
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
|
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,24 @@ use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
class Note extends Model
|
class Note extends Model
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
protected $guarded = [
|
protected $guarded = [
|
||||||
'id',
|
'id',
|
||||||
];
|
];
|
||||||
|
*/
|
||||||
|
protected $fillable = ["description"];
|
||||||
|
|
||||||
|
|
||||||
|
protected $table = 'notes';
|
||||||
|
|
||||||
public function client()
|
public function client()
|
||||||
{
|
{
|
||||||
$this->hasOne(App\Models\Client::class);
|
return $this->hasOne(App\Models\Client::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function notes()
|
||||||
|
{
|
||||||
|
return $this->hasMany(Note::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
use Illuminate\Routing\Controller;
|
use Illuminate\Routing\Controller;
|
||||||
use Modules\Notes\Entities\Note;
|
use Modules\Notes\Entities\Note;
|
||||||
use Nwidart\Modules\Facades\Module;
|
use Yajra\DataTables\Facades\DataTables;
|
||||||
use Yajra\DataTables\Html\Builder;
|
use Yajra\DataTables\Html\Builder;
|
||||||
|
|
||||||
class NotesController extends Controller
|
class NotesController extends Controller
|
||||||
|
|
@ -58,7 +58,7 @@ class NotesController extends Controller
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$data['html'] = $html;
|
$data['html'] = $html;
|
||||||
|
|
||||||
return view('notes::index', $data);
|
return view('notes::index', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Notes\Http\ViewComposers;
|
||||||
|
|
||||||
|
use App\Utils\Traits\UserSessionAttributes;
|
||||||
|
use Illuminate\View\View;
|
||||||
|
|
||||||
|
class ClientEditComposer
|
||||||
|
{
|
||||||
|
use UserSessionAttributes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bind data to the view.
|
||||||
|
*
|
||||||
|
* @param View $view
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function compose(View $view)
|
||||||
|
{
|
||||||
|
$data = $view->getData();
|
||||||
|
|
||||||
|
$view->with('notes::edit', $this->clientEditData);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function clientEditData()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -46,8 +46,11 @@ class NotesServiceProvider extends ServiceProvider
|
||||||
protected function registerConfig()
|
protected function registerConfig()
|
||||||
{
|
{
|
||||||
$this->publishes([
|
$this->publishes([
|
||||||
__DIR__.'/../Config/config.php' => config_path('notes.php'),
|
__DIR__.'/../Config/config.php' => config_path('modules.notes' . '.php'),
|
||||||
], 'config');
|
], 'config');
|
||||||
|
|
||||||
|
$this->mergeConfigFrom(__DIR__.'/../Config/relations.php', 'modules.relations');
|
||||||
|
|
||||||
$this->mergeConfigFrom(
|
$this->mergeConfigFrom(
|
||||||
__DIR__.'/../Config/config.php', 'notes'
|
__DIR__.'/../Config/config.php', 'notes'
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'new_note' => 'New Note',
|
||||||
|
];
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
|
||||||
|
|
||||||
|
<div class="container-fluid">
|
||||||
|
@if($client)
|
||||||
|
<span>{{ $client->name }} </span>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
@foreach($client->notes()->get() as $note)
|
||||||
|
<li> {{ $note->description }} </li>
|
||||||
|
@endforeach
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
@extends('layouts.master', ['header' => $header])
|
||||||
|
|
||||||
@section('head')
|
@section('head')
|
||||||
@parent
|
@parent
|
||||||
|
|
@ -13,15 +14,23 @@
|
||||||
{{ Breadcrumbs::render('clients') }}
|
{{ Breadcrumbs::render('clients') }}
|
||||||
|
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<button class="btn btn-primary btn-lg pull-right">{{ trans('notes::texts.new_note') }}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="ui-view">
|
<div id="ui-view">
|
||||||
<div class="animated fadeIn">
|
<div class="animated fadeIn" style="padding-top:20px;">
|
||||||
<div class="row col-lg-12 card">
|
<div class="row col-md-12 card">
|
||||||
|
|
||||||
{!! $html->table() !!}
|
{!! $html->table() !!}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,20 @@ use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
class BaseModel extends Model
|
class BaseModel extends Model
|
||||||
{
|
{
|
||||||
/*
|
public function __call($method, $params)
|
||||||
public function setIdAttribute($value)
|
|
||||||
{
|
{
|
||||||
$hashids = new Hashids(); //decoded output is _always_ an array.
|
$entity = strtolower(class_basename($this));
|
||||||
$hashed_id_array = $hashids->decode($value);
|
|
||||||
|
|
||||||
$this->attributes['id'] = strtolower($hashed_id_array[0]);
|
if ($entity) {
|
||||||
|
$configPath = "modules.relations.$entity.$method";
|
||||||
|
|
||||||
|
if (config()->has($configPath)) {
|
||||||
|
$function = config()->get($configPath);
|
||||||
|
|
||||||
|
return $function($this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::__call($method, $params);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1,9 +0,0 @@
|
||||||
|
|
||||||
/**
|
|
||||||
* First we will load all of this project's JavaScript dependencies which
|
|
||||||
* includes Vue and other libraries. It is a great starting point when
|
|
||||||
* building robust, powerful web applications using Vue and Laravel.
|
|
||||||
*/
|
|
||||||
|
|
||||||
require('./bootstrap');
|
|
||||||
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="container">
|
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-md-8">
|
|
||||||
<div class="card card-default">
|
|
||||||
<div class="card-header">Example Component</div>
|
|
||||||
|
|
||||||
<div class="card-body">
|
|
||||||
I'm an example component.
|
|
||||||
{{ trans('texts.clients')}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
mounted() {
|
|
||||||
console.log('Component mounted.')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
/* Allows us to use our native translation easily using {{ trans() }} syntax */
|
|
||||||
//const _ = require('lodash');
|
|
||||||
import * as _ from "lodash"
|
|
||||||
declare var i18n;
|
|
||||||
|
|
||||||
import Vue from 'vue';
|
|
||||||
import axios from 'axios';
|
|
||||||
|
|
||||||
// import Toastr
|
|
||||||
import Toastr from 'vue-toastr';
|
|
||||||
// import toastr scss file: need webpack sass-loader
|
|
||||||
require('vue-toastr/src/vue-toastr.scss');
|
|
||||||
// Register vue component
|
|
||||||
Vue.component('vue-toastr',Toastr);
|
|
||||||
|
|
||||||
Vue.prototype.trans = string => _.get(i18n, string);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Next, we will create a fresh Vue application instance and attach it to
|
|
||||||
* the page. Then, you may begin adding components to this application
|
|
||||||
* or customize the JavaScript scaffolding to fit your unique needs.
|
|
||||||
*/
|
|
||||||
Vue.component('example-component', require('../../components/ExampleComponent.vue'));
|
|
||||||
Vue.component('client-edit', require('../../components/client/ClientEdit.vue'));
|
|
||||||
Vue.component('client-address', require('../../components/client/ClientAddress.vue'));
|
|
||||||
Vue.component('generic-address', require('../../components/generic/Address.vue'));
|
|
||||||
Vue.component('client-edit-form', require('../../components/client/ClientEditForm.vue'));
|
|
||||||
Vue.component('contact-edit', require('../../components/client/ClientContactEdit.vue'));
|
|
||||||
|
|
||||||
|
|
||||||
window.onload = function () {
|
|
||||||
|
|
||||||
const app = new Vue({
|
|
||||||
el: '#client_e'
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
//import * as Vue from 'vue';
|
/* Allows us to use our native translation easily using {{ trans() }} syntax */
|
||||||
|
//const _ = require('lodash');
|
||||||
|
import * as _ from "lodash"
|
||||||
|
declare var i18n;
|
||||||
|
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import Form from '../utils/form';
|
|
||||||
import Client from '../models/client-model';
|
|
||||||
|
|
||||||
// import Toastr
|
// import Toastr
|
||||||
import Toastr from 'vue-toastr';
|
import Toastr from 'vue-toastr';
|
||||||
|
|
@ -11,67 +13,24 @@ require('vue-toastr/src/vue-toastr.scss');
|
||||||
// Register vue component
|
// Register vue component
|
||||||
Vue.component('vue-toastr',Toastr);
|
Vue.component('vue-toastr',Toastr);
|
||||||
|
|
||||||
declare var client_object: any;
|
Vue.prototype.trans = string => _.get(i18n, string);
|
||||||
declare var hashed_id: string;
|
|
||||||
|
|
||||||
new Vue({
|
/**
|
||||||
el : '#client_edit',
|
* Next, we will create a fresh Vue application instance and attach it to
|
||||||
data: function () {
|
* the page. Then, you may begin adding components to this application
|
||||||
return {
|
* or customize the JavaScript scaffolding to fit your unique needs.
|
||||||
form: new Form(<Client>client_object)
|
*/
|
||||||
}
|
Vue.component('client-edit', require('../components/client/ClientEdit.vue'));
|
||||||
},
|
Vue.component('client-address', require('../components/client/ClientAddress.vue'));
|
||||||
mounted(this: any) {
|
Vue.component('generic-address', require('../components/generic/Address.vue'));
|
||||||
//console.log('mounted')
|
Vue.component('client-edit-form', require('../components/client/ClientEditForm.vue'));
|
||||||
},
|
Vue.component('contact-edit', require('../components/client/ClientContactEdit.vue'));
|
||||||
beforeMount: function () {
|
|
||||||
//console.log('before mount')
|
|
||||||
},
|
|
||||||
created:function() {
|
|
||||||
//console.dir('created')
|
|
||||||
},
|
|
||||||
updated:function() {
|
|
||||||
//console.dir('updated')
|
|
||||||
},
|
|
||||||
methods:{
|
|
||||||
remove(this:any, contact:any){
|
|
||||||
let index = this.form.contacts.indexOf(contact);
|
|
||||||
this.form.contacts.splice(index, 1);
|
|
||||||
},
|
|
||||||
add(this: any){
|
|
||||||
this.form.contacts.push({first_name: '', last_name: '', email: '', phone: '', id: 0});
|
|
||||||
window.scrollTo(0, document.body.scrollHeight || document.documentElement.scrollHeight);
|
|
||||||
this.$nextTick(() => {
|
|
||||||
let index = this.form.contacts.length - 1;
|
|
||||||
let input = this.$refs.first_name[index];
|
|
||||||
input.focus();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onSubmit() {
|
|
||||||
this.form.put('/clients/' + hashed_id)
|
|
||||||
.then(response => this.$root.$refs.toastr.s("Saved client"))
|
|
||||||
.catch(error => {
|
|
||||||
|
|
||||||
this.$root.$refs.toastr.e("Error saving client");
|
|
||||||
|
window.onload = function () {
|
||||||
|
|
||||||
});
|
const app = new Vue({
|
||||||
},
|
el: '#client_edit'
|
||||||
copy(type: any) {
|
});
|
||||||
if(type.includes('copy_billing')){
|
|
||||||
this.form.shipping_address1 = this.form.address1;
|
}
|
||||||
this.form.shipping_address2 = this.form.address2;
|
|
||||||
this.form.shipping_city = this.form.city;
|
|
||||||
this.form.shipping_state = this.form.state;
|
|
||||||
this.form.shipping_postal_code = this.form.postal_code;
|
|
||||||
this.form.shipping_country_id = this.form.country_id;
|
|
||||||
}else {
|
|
||||||
this.form.address1 = this.form.shipping_address1;
|
|
||||||
this.form.address2 = this.form.shipping_address2;
|
|
||||||
this.form.city = this.form.shipping_city;
|
|
||||||
this.form.state = this.form.shipping_state;
|
|
||||||
this.form.postal_code = this.form.shipping_postal_code;
|
|
||||||
this.form.country_id = this.form.shipping_country_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
|
||||||
|
|
@ -57,8 +57,8 @@
|
||||||
|
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import Form from '../../src/utils/form';
|
import Form from '../../utils/form';
|
||||||
import Client from '../../src/models/client-model';
|
import Client from '../../models/client-model';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data: function () {
|
data: function () {
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
@extends('layouts.master', ['header' => $header])
|
@extends('layouts.master', ['header' => $header])
|
||||||
|
|
||||||
@section('body')
|
@section('body')
|
||||||
<main class="main" id="client_e">
|
<main class="main" id="client_edit">
|
||||||
|
|
||||||
<!-- Breadcrumb-->
|
<!-- Breadcrumb-->
|
||||||
{{ Breadcrumbs::render('clients.edit', $client) }}
|
{{ Breadcrumbs::render('clients.edit', $client) }}
|
||||||
|
|
@ -16,10 +16,6 @@
|
||||||
<a class="nav-link active show" id="pills-home-tab" data-toggle="pill" href="#pills-home" role="tab" aria-controls="pills-home" aria-selected="true"><i class="icon-user"></i> {{ trans('texts.client') }}</a>
|
<a class="nav-link active show" id="pills-home-tab" data-toggle="pill" href="#pills-home" role="tab" aria-controls="pills-home" aria-selected="true"><i class="icon-user"></i> {{ trans('texts.client') }}</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" id="pills-settings-tab" data-toggle="pill" href="#pills-settings" role="tab" aria-controls="pills-settings" aria-selected="false"><i class="icon-settings"></i> {{ trans('texts.settings') }}</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
@foreach($pills as $pill)
|
@foreach($pills as $pill)
|
||||||
|
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
|
|
@ -27,6 +23,11 @@
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" id="pills-settings-tab" data-toggle="pill" href="#pills-settings" role="tab" aria-controls="pills-settings" aria-selected="false"><i class="icon-settings"></i> {{ trans('texts.settings') }}</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div class="tab-content" id="pills-tabContent">
|
<div class="tab-content" id="pills-tabContent">
|
||||||
|
|
@ -40,7 +41,9 @@
|
||||||
@foreach($pills as $pill)
|
@foreach($pills as $pill)
|
||||||
|
|
||||||
<div class="tab-pane fade" id="pills-{{ $pill['alias'] }}" role="tabpanel" aria-labelledby="pills-{{ $pill['alias'] }}-tab">
|
<div class="tab-pane fade" id="pills-{{ $pill['alias'] }}" role="tabpanel" aria-labelledby="pills-{{ $pill['alias'] }}-tab">
|
||||||
{{$pill['name']}}
|
|
||||||
|
@include($pill['alias'] . '::.edit')
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
@ -56,6 +59,6 @@
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script defer src=" {{ mix('/js/client-edit.js') }}"></script>
|
<script defer src=" {{ mix('/js/client_edit.min.js') }}"></script>
|
||||||
|
|
||||||
@endsection
|
@endsection
|
||||||
|
|
@ -14,9 +14,15 @@
|
||||||
{{ Breadcrumbs::render('clients') }}
|
{{ Breadcrumbs::render('clients') }}
|
||||||
|
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<button class="btn btn-primary btn-lg pull-right">{{ trans('texts.new_client') }}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="ui-view">
|
<div id="ui-view">
|
||||||
<div class="animated fadeIn">
|
<div class="animated fadeIn">
|
||||||
<div class="row col-lg-12 card">
|
<div class="row col-md-12 card">
|
||||||
|
|
||||||
{!! $html->table() !!}
|
{!! $html->table() !!}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,14 +28,12 @@ mix.webpackConfig({
|
||||||
});
|
});
|
||||||
|
|
||||||
mix.js('resources/js/src/client/client_edit.ts', 'public/js');
|
mix.js('resources/js/src/client/client_edit.ts', 'public/js');
|
||||||
mix.js('resources/js/src/c/client-edit.ts', 'public/js');
|
|
||||||
mix.js('resources/js/src/client/client_create.ts', 'public/js');
|
mix.js('resources/js/src/client/client_create.ts', 'public/js');
|
||||||
mix.js('resources/js/src/settings/localization.ts', 'public/js');
|
mix.js('resources/js/src/settings/localization.ts', 'public/js');
|
||||||
mix.js('resources/js/app.js', 'public/js/vendor');
|
|
||||||
mix.js('node_modules/@coreui/coreui/dist/js/coreui.js', 'public/js');
|
mix.js('node_modules/@coreui/coreui/dist/js/coreui.js', 'public/js');
|
||||||
|
|
||||||
mix.scripts([
|
mix.scripts([
|
||||||
'public/js/vendor/app.js'
|
'js/src/bootstrap.js'
|
||||||
], 'public/js/ninja.js');
|
], 'public/js/ninja.js');
|
||||||
|
|
||||||
mix.minify('public/js/ninja.js');
|
mix.minify('public/js/ninja.js');
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue