Access module relations from parent (#2553)

* Refactor JS directory structure

* Access Module relations from Parent entity
This commit is contained in:
David Bomba 2018-12-13 22:01:33 +11:00 committed by GitHub
parent bdb0f43d33
commit 95f1d24b8f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 39512 additions and 153321 deletions

View File

@ -0,0 +1,9 @@
<?php
return [
'client' => [
'notes' => function ($self) {
return $self->hasMany('Modules\Notes\Entities\Note');
}
],
];

View File

@ -17,8 +17,10 @@ class NotesTable extends Migration
$table->increments('id');
$table->unsignedInteger('client_id')->index();
$table->unsignedInteger('user_id')->index();
$table->unsignedInteger('company_id')->index();
$table->string('description');
$table->timestamps();
$table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade');
$table->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});

View File

@ -6,13 +6,24 @@ use Illuminate\Database\Eloquent\Model;
class Note extends Model
{
/*
protected $guarded = [
'id',
];
*/
protected $fillable = ["description"];
protected $table = 'notes';
public function client()
{
$this->hasOne(App\Models\Client::class);
return $this->hasOne(App\Models\Client::class);
}
public function notes()
{
return $this->hasMany(Note::class);
}
}

View File

@ -8,7 +8,7 @@ use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Routing\Controller;
use Modules\Notes\Entities\Note;
use Nwidart\Modules\Facades\Module;
use Yajra\DataTables\Facades\DataTables;
use Yajra\DataTables\Html\Builder;
class NotesController extends Controller
@ -58,7 +58,7 @@ class NotesController extends Controller
]);
$data['html'] = $html;
return view('notes::index', $data);
}

View File

@ -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()
{
}

View File

@ -46,8 +46,11 @@ class NotesServiceProvider extends ServiceProvider
protected function registerConfig()
{
$this->publishes([
__DIR__.'/../Config/config.php' => config_path('notes.php'),
__DIR__.'/../Config/config.php' => config_path('modules.notes' . '.php'),
], 'config');
$this->mergeConfigFrom(__DIR__.'/../Config/relations.php', 'modules.relations');
$this->mergeConfigFrom(
__DIR__.'/../Config/config.php', 'notes'
);

View File

@ -0,0 +1,7 @@
<?php
return [
'new_note' => 'New Note',
];
?>

View File

@ -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>

View File

@ -1,3 +1,4 @@
@extends('layouts.master', ['header' => $header])
@section('head')
@parent
@ -13,15 +14,23 @@
{{ Breadcrumbs::render('clients') }}
<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 class="animated fadeIn">
<div class="row col-lg-12 card">
<div class="animated fadeIn" style="padding-top:20px;">
<div class="row col-md-12 card">
{!! $html->table() !!}
</div>
</div>
</div>
</div>
</main>
@endsection

View File

@ -7,13 +7,20 @@ use Illuminate\Database\Eloquent\Model;
class BaseModel extends Model
{
/*
public function setIdAttribute($value)
public function __call($method, $params)
{
$hashids = new Hashids(); //decoded output is _always_ an array.
$hashed_id_array = $hashids->decode($value);
$entity = strtolower(class_basename($this));
$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);
}
*/
}

34904
public/js/client-edit.js vendored

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

19741
public/js/client_edit.js vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

12588
public/js/coreui.js vendored

File diff suppressed because one or more lines are too long

12588
public/js/coreui.min.js vendored

File diff suppressed because one or more lines are too long

11560
public/js/localization.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

13112
public/js/ninja.js vendored

File diff suppressed because it is too large Load Diff

13112
public/js/ninja.min.js vendored

File diff suppressed because it is too large Load Diff

13112
public/js/vendor/app.js vendored

File diff suppressed because it is too large Load Diff

9
resources/js/app.js vendored
View File

@ -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');

View File

@ -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>

View File

@ -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'
});
}

View File

@ -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 axios from 'axios';
import Form from '../utils/form';
import Client from '../models/client-model';
// import Toastr
import Toastr from 'vue-toastr';
@ -11,67 +13,24 @@ require('vue-toastr/src/vue-toastr.scss');
// Register vue component
Vue.component('vue-toastr',Toastr);
declare var client_object: any;
declare var hashed_id: string;
Vue.prototype.trans = string => _.get(i18n, string);
new Vue({
el : '#client_edit',
data: function () {
return {
form: new Form(<Client>client_object)
}
},
mounted(this: any) {
//console.log('mounted')
},
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 => {
/**
* 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('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'));
this.$root.$refs.toastr.e("Error saving client");
window.onload = function () {
});
},
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;
}
}
}
});
const app = new Vue({
el: '#client_edit'
});
}

View File

@ -57,8 +57,8 @@
import Vue from 'vue';
import axios from 'axios';
import Form from '../../src/utils/form';
import Client from '../../src/models/client-model';
import Form from '../../utils/form';
import Client from '../../models/client-model';
export default {
data: function () {

View File

@ -1,7 +1,7 @@
@extends('layouts.master', ['header' => $header])
@section('body')
<main class="main" id="client_e">
<main class="main" id="client_edit">
<!-- Breadcrumb-->
{{ 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>
</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)
<li class="nav-item">
@ -27,6 +23,11 @@
</li>
@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>
<div class="tab-content" id="pills-tabContent">
@ -40,7 +41,9 @@
@foreach($pills as $pill)
<div class="tab-pane fade" id="pills-{{ $pill['alias'] }}" role="tabpanel" aria-labelledby="pills-{{ $pill['alias'] }}-tab">
{{$pill['name']}}
@include($pill['alias'] . '::.edit')
</div>
@endforeach
@ -56,6 +59,6 @@
</main>
<script defer src=" {{ mix('/js/client-edit.js') }}"></script>
<script defer src=" {{ mix('/js/client_edit.min.js') }}"></script>
@endsection

View File

@ -14,9 +14,15 @@
{{ Breadcrumbs::render('clients') }}
<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 class="animated fadeIn">
<div class="row col-lg-12 card">
<div class="row col-md-12 card">
{!! $html->table() !!}

0
storage/app/.gitignore vendored Normal file → Executable file
View File

0
storage/app/public/.gitignore vendored Normal file → Executable file
View File

0
storage/framework/.gitignore vendored Normal file → Executable file
View File

0
storage/framework/cache/.gitignore vendored Normal file → Executable file
View File

0
storage/framework/sessions/.gitignore vendored Normal file → Executable file
View File

0
storage/framework/testing/.gitignore vendored Normal file → Executable file
View File

0
storage/framework/views/.gitignore vendored Normal file → Executable file
View File

0
storage/logs/.gitignore vendored Normal file → Executable file
View File

4
webpack.mix.js vendored
View File

@ -28,14 +28,12 @@ mix.webpackConfig({
});
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/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.scripts([
'public/js/vendor/app.js'
'js/src/bootstrap.js'
], 'public/js/ninja.js');
mix.minify('public/js/ninja.js');