mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-24 02:14:21 -04:00
Import (#3360)
* Fixes for test data * Fixes for tests * Remove legacy vue components * Add routing number to client gateway tokens * working on important documents and company gateways * Import fixes
This commit is contained in:
parent
0e7904a74b
commit
c1d3fd12a8
@ -98,7 +98,7 @@ class Creative extends AbstractDesign
|
||||
<tbody>
|
||||
$table_body
|
||||
<tr>
|
||||
<td colspan="7" ref="note" class="px-4 py-4">$entity.public_notes</td>
|
||||
<td colspan="5" ref="note" class="px-4 py-4">$entity.public_notes</td>
|
||||
<td ref="quantity" class="px-4 py-4 flex flex-col">
|
||||
$total_tax_labels
|
||||
$line_tax_labels
|
||||
|
@ -61,7 +61,7 @@ class InvoiceItemFactory
|
||||
$item->line_total = $item->quantity * $item->cost;
|
||||
$item->is_amount_discount = true;
|
||||
$item->discount = $faker->numberBetween(1, 10);
|
||||
$item->notes = $faker->realText(20);
|
||||
$item->notes = $faker->realText(50);
|
||||
$item->product_key = $faker->word();
|
||||
$item->custom_value1 = $faker->realText(10);
|
||||
$item->custom_value2 = $faker->realText(10);
|
||||
|
@ -7,7 +7,9 @@
|
||||
* @OA\Property(property="company_id", type="string", example="2", description="______"),
|
||||
* @OA\Property(property="client_id", type="string", example="2", description="______"),
|
||||
* @OA\Property(property="token", type="string", example="2", description="______"),
|
||||
* @OA\Property(property="routing_number", type="string", example="2", description="______"),
|
||||
* @OA\Property(property="company_gateway_id", type="string", example="2", description="______"),
|
||||
* @OA\Property(property="is_default", type="boolean", example="true", description="______"),
|
||||
*
|
||||
* )
|
||||
*/
|
||||
|
@ -143,6 +143,7 @@ class Import implements ShouldQueue
|
||||
$validator = Validator::make($data, $rules);
|
||||
|
||||
if ($validator->fails()) {
|
||||
\Log::error($validator->errors());
|
||||
throw new MigrationValidatorFailed($validator->errors());
|
||||
}
|
||||
|
||||
@ -443,12 +444,12 @@ class Import implements ShouldQueue
|
||||
);
|
||||
|
||||
$old_user_key = array_key_exists('user_id', $resource) ?? $this->user->id;
|
||||
|
||||
$key = "invoices_{$resource['id']}";
|
||||
|
||||
$this->ids['quotes'] = [
|
||||
"quotes_{$old_user_key}" => [
|
||||
'old' => $old_user_key,
|
||||
'new' => $invoice->id,
|
||||
]
|
||||
$this->ids['quotes'][$key] = [
|
||||
'old' => $resource['id'],
|
||||
'new' => $invoice->id,
|
||||
];
|
||||
|
||||
}
|
||||
@ -517,10 +518,12 @@ class Import implements ShouldQueue
|
||||
$modified = $resource;
|
||||
|
||||
if (array_key_exists('invoice_id', $resource) && !array_key_exists('invoices', $this->ids)) {
|
||||
\Log::error("ivoice id missing");
|
||||
throw new ResourceDependencyMissing(array_key_first($data), 'invoices');
|
||||
}
|
||||
|
||||
if (array_key_exists('expense_id', $resource) && !array_key_exists('expenses', $this->ids)) {
|
||||
\Log::error("expense id missing");
|
||||
throw new ResourceDependencyMissing(array_key_first($data), 'expenses');
|
||||
}
|
||||
|
||||
@ -534,21 +537,21 @@ class Import implements ShouldQueue
|
||||
}
|
||||
|
||||
if(array_key_exists('expense_id', $resource) && $resource['expense_id']) {
|
||||
$modified['documentable_id'] = $this->transformId('expense', $resource['expense_id']);
|
||||
$modified['documentable_id'] = $this->transformId('expenses', $resource['expense_id']);
|
||||
$modified['documentable_type'] = 'App\\Models\\Expense';
|
||||
}
|
||||
|
||||
$modified['user_id'] = $this->processUserId($resource);
|
||||
$modified['company_id'] = $this->company->id;
|
||||
|
||||
$payment = Document::create($modified);
|
||||
$document = Document::create($modified);
|
||||
|
||||
$old_user_key = array_key_exists('user_id', $resource) ?? $this->user->id;
|
||||
|
||||
$this->ids['payments'] = [
|
||||
"payments_{$old_user_key}" => [
|
||||
$this->ids['documents'] = [
|
||||
"documents_{$old_user_key}" => [
|
||||
'old' => $old_user_key,
|
||||
'new' => $payment->id,
|
||||
'new' => $document->id,
|
||||
]
|
||||
];
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ use App\Models\DateFormat;
|
||||
use App\Models\Filterable;
|
||||
use App\Models\Paymentable;
|
||||
use App\Services\Ledger\LedgerService;
|
||||
use App\Services\Payment\PaymentService;
|
||||
use App\Utils\Number;
|
||||
use App\Utils\Traits\MakesDates;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
@ -175,6 +176,11 @@ class Payment extends BaseModel
|
||||
return new LedgerService($this);
|
||||
}
|
||||
|
||||
public function service()
|
||||
{
|
||||
return new PaymentService($this);
|
||||
}
|
||||
|
||||
public function resolveRouteBinding($value)
|
||||
{
|
||||
return $this
|
||||
|
@ -178,7 +178,7 @@ class StripePaymentDriver extends BasePaymentDriver
|
||||
$payment_meta->exp_year = $stripe_payment_method_obj['card']['exp_year'];
|
||||
$payment_meta->brand = $stripe_payment_method_obj['card']['brand'];
|
||||
$payment_meta->last4 = $stripe_payment_method_obj['card']['last4'];
|
||||
$payment_meta->type = $stripe_payment_method_obj['type'];
|
||||
$payment_meta->type = GatewayType::CREDIT_CARD;
|
||||
}
|
||||
|
||||
$cgt = new ClientGatewayToken;
|
||||
|
@ -5,13 +5,12 @@ use App\Credit;
|
||||
|
||||
class CreditService
|
||||
{
|
||||
|
||||
protected $credit;
|
||||
|
||||
|
||||
public function __construct($credit)
|
||||
{
|
||||
$this->credit = $credit;
|
||||
|
||||
}
|
||||
|
||||
public function getCreditPdf($contact)
|
||||
@ -44,6 +43,7 @@ class CreditService
|
||||
public function save() : ?Credit
|
||||
{
|
||||
$this->credit->save();
|
||||
|
||||
return $this->credit;
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ class UpdateInvoicePayment
|
||||
|
||||
$this->payment
|
||||
->ledger()
|
||||
->updatePaymentBalance($this->payment, ($invoice->balance*-1));
|
||||
->updatePaymentBalance($invoice->balance*-1);
|
||||
|
||||
$this->payment->client
|
||||
->service()
|
||||
@ -66,7 +66,7 @@ class UpdateInvoicePayment
|
||||
|
||||
$this->payment
|
||||
->ledger()
|
||||
->updatePaymentBalance($this->payment, ($invoice->partial*-1));
|
||||
->updatePaymentBalance($invoice->partial*-1);
|
||||
|
||||
$this->payment->client->service()
|
||||
->updateBalance($invoice->partial*-1)
|
||||
@ -85,7 +85,7 @@ class UpdateInvoicePayment
|
||||
|
||||
$this->payment
|
||||
->ledger()
|
||||
->updatePaymentBalance($this->payment, ($invoice->balance*-1));
|
||||
->updatePaymentBalance($invoice->balance*-1);
|
||||
|
||||
$this->payment->client->service()
|
||||
->updateBalance($invoice->balance*-1)
|
||||
|
@ -1128,6 +1128,7 @@ class CreateUsersTable extends Migration
|
||||
$table->unsignedInteger('company_id');
|
||||
$table->unsignedInteger('client_id')->nullable();
|
||||
$table->text('token')->nullable();
|
||||
$table->text('routing_number')->nullable();
|
||||
$table->unsignedInteger('company_gateway_id');
|
||||
$table->string('gateway_customer_reference')->nullable();
|
||||
$table->unsignedInteger('gateway_type_id');
|
||||
|
@ -8,8 +8,6 @@ use App\Events\Invoice\InvoiceWasUpdated;
|
||||
use App\Events\Payment\PaymentWasCreated;
|
||||
use App\Helpers\Invoice\InvoiceSum;
|
||||
use App\Helpers\Invoice\InvoiceSumInclusive;
|
||||
use App\Jobs\Company\UpdateCompanyLedgerWithInvoice;
|
||||
//use App\Jobs\Invoice\UpdateInvoicePayment;
|
||||
use App\Listeners\Credit\CreateCreditInvitation;
|
||||
use App\Listeners\Invoice\CreateInvoiceInvitation;
|
||||
use App\Models\Account;
|
||||
@ -165,7 +163,7 @@ class RandomDataSeeder extends Seeder
|
||||
|
||||
event(new CreateInvoiceInvitation($invoice));
|
||||
|
||||
UpdateCompanyLedgerWithInvoice::dispatchNow($invoice, $invoice->balance, $invoice->company);
|
||||
$invoice->ledger()->updateInvoiceBalance($invoice->balance);
|
||||
|
||||
$invoice->service()->markSent()->save();
|
||||
|
||||
@ -187,7 +185,7 @@ class RandomDataSeeder extends Seeder
|
||||
|
||||
event(new PaymentWasCreated($payment, $payment->company));
|
||||
|
||||
$payment->service()->UpdateInvoicePayment();
|
||||
$payment->service()->updateInvoicePayment();
|
||||
|
||||
// UpdateInvoicePayment::dispatchNow($payment, $payment->company);
|
||||
}
|
||||
|
17
jest.config.js
vendored
17
jest.config.js
vendored
@ -1,17 +0,0 @@
|
||||
module.exports = {
|
||||
"roots": [
|
||||
"resources/js/src"
|
||||
],
|
||||
"transform": {
|
||||
"^.+\\.tsx?$": "ts-jest"
|
||||
},
|
||||
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$",
|
||||
"moduleFileExtensions": [
|
||||
"ts",
|
||||
"tsx",
|
||||
"js",
|
||||
"jsx",
|
||||
"json",
|
||||
"node"
|
||||
],
|
||||
}
|
106
resources/assets/js/vendor/I18n.js
vendored
106
resources/assets/js/vendor/I18n.js
vendored
@ -1,106 +0,0 @@
|
||||
export default class I18n
|
||||
{
|
||||
/**
|
||||
* Initialize a new translation instance.
|
||||
*
|
||||
* @param {string} key
|
||||
* @return {void}
|
||||
*/
|
||||
constructor(key = 'translations')
|
||||
{
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and replace the string of the given key.
|
||||
*
|
||||
* @param {string} key
|
||||
* @param {object} replace
|
||||
* @return {string}
|
||||
*/
|
||||
trans(key, replace = {})
|
||||
{
|
||||
return this._replace(this._extract(key), replace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and pluralize the strings of the given key.
|
||||
*
|
||||
* @param {string} key
|
||||
* @param {number} count
|
||||
* @param {object} replace
|
||||
* @return {string}
|
||||
*/
|
||||
trans_choice(key, count = 1, replace = {})
|
||||
{
|
||||
let translations = this._extract(key, '|').split('|'), translation;
|
||||
|
||||
translations.some(t => translation = this._match(t, count));
|
||||
|
||||
translation = translation || (count > 1 ? translations[1] : translations[0]);
|
||||
|
||||
return this._replace(translation, replace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Match the translation limit with the count.
|
||||
*
|
||||
* @param {string} translation
|
||||
* @param {number} count
|
||||
* @return {string|null}
|
||||
*/
|
||||
_match(translation, count)
|
||||
{
|
||||
let match = translation.match(/^[\{\[]([^\[\]\{\}]*)[\}\]](.*)/);
|
||||
|
||||
if (! match) return;
|
||||
|
||||
if (match[1].includes(',')) {
|
||||
let [from, to] = match[1].split(',');
|
||||
|
||||
if (to === '*' && count >= from) {
|
||||
return match[2];
|
||||
} else if (from === '*' && count <= to) {
|
||||
return match[2];
|
||||
} else if (count >= from && count <= to) {
|
||||
return match[2];
|
||||
}
|
||||
}
|
||||
|
||||
return match[1] == count ? match[2] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the placeholders.
|
||||
*
|
||||
* @param {string} translation
|
||||
* @param {object} replace
|
||||
* @return {string}
|
||||
*/
|
||||
_replace(translation, replace)
|
||||
{
|
||||
for (let placeholder in replace) {
|
||||
translation = translation
|
||||
.replace(`:${placeholder}`, replace[placeholder])
|
||||
.replace(`:${placeholder.toUpperCase()}`, replace[placeholder].toUpperCase())
|
||||
.replace(
|
||||
`:${placeholder.charAt(0).toUpperCase()}${placeholder.slice(1)}`,
|
||||
replace[placeholder].charAt(0).toUpperCase()+replace[placeholder].slice(1)
|
||||
);
|
||||
}
|
||||
|
||||
return translation.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* The extract helper.
|
||||
*
|
||||
* @param {string} key
|
||||
* @param {mixed} value
|
||||
* @return {mixed}
|
||||
*/
|
||||
_extract(key, value = null)
|
||||
{
|
||||
return key.toString().split('.').reduce((t, i) => t[i] || (value || key), window[this.key]);
|
||||
}
|
||||
}
|
81762
resources/assets/js/vue-i18n-locales.generated.js
vendored
81762
resources/assets/js/vue-i18n-locales.generated.js
vendored
File diff suppressed because it is too large
Load Diff
61
resources/js/src/bootstrap.js
vendored
61
resources/js/src/bootstrap.js
vendored
@ -1,61 +0,0 @@
|
||||
// lodash handles our translations
|
||||
import * as get from "lodash.get"
|
||||
|
||||
// import Toastr
|
||||
import Toastr from 'vue-toastr';
|
||||
|
||||
// Import toastr scss file: need webpack sass-loader
|
||||
require('vue-toastr/src/vue-toastr.scss');
|
||||
|
||||
import Vue from 'vue';
|
||||
|
||||
// Register vue component
|
||||
Vue.component('vue-toastr',Toastr);
|
||||
|
||||
// Global translation helper
|
||||
Vue.prototype.trans = string => get(i18n, string);
|
||||
|
||||
|
||||
window.axios = require('axios');
|
||||
window.Vue = require('vue');
|
||||
|
||||
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
|
||||
|
||||
/* Development only*/
|
||||
Vue.config.devtools = true;
|
||||
|
||||
window.axios.defaults.headers.common = {
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
'X-CSRF-TOKEN' : document.querySelector('meta[name="csrf-token"]').getAttribute('content')
|
||||
};
|
||||
|
||||
/**
|
||||
* Next we will register the CSRF Token as a common header with Axios so that
|
||||
* all outgoing HTTP requests automatically have it attached. This is just
|
||||
* a simple convenience so we don't have to attach every token manually.
|
||||
*/
|
||||
|
||||
let token = document.head.querySelector('meta[name="csrf-token"]');
|
||||
|
||||
if (token) {
|
||||
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
|
||||
} else {
|
||||
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
|
||||
}
|
||||
|
||||
/**
|
||||
* Echo exposes an expressive API for subscribing to channels and listening
|
||||
* for events that are broadcast by Laravel. Echo and event broadcasting
|
||||
* allows your team to easily build robust real-time web applications.
|
||||
*/
|
||||
|
||||
// import Echo from 'laravel-echo'
|
||||
|
||||
// window.Pusher = require('pusher-js');
|
||||
|
||||
// window.Echo = new Echo({
|
||||
// broadcaster: 'pusher',
|
||||
// key: process.env.MIX_PUSHER_APP_KEY,
|
||||
// cluster: process.env.MIX_PUSHER_APP_CLUSTER,
|
||||
// encrypted: true
|
||||
// });
|
@ -1,70 +0,0 @@
|
||||
//import * as Vue from 'vue';
|
||||
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';
|
||||
// import toastr scss file: need webpack sass-loader
|
||||
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;
|
||||
|
||||
new Vue({
|
||||
el : '#client_create',
|
||||
data: function () {
|
||||
return {
|
||||
form: new Form(<Client>client_object)
|
||||
}
|
||||
},
|
||||
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.post('/clients/')
|
||||
.then(response => {
|
||||
this.$root.$refs.toastr.s("Created client"); //how are we going to handle translations here?
|
||||
|
||||
window.location.href = '/clients/' + this.form.hashed_id + '/edit';
|
||||
|
||||
})
|
||||
.catch(error => {
|
||||
|
||||
this.$root.$refs.toastr.e("Error saving client");
|
||||
|
||||
});
|
||||
},
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
@ -1,24 +0,0 @@
|
||||
/* Allows us to use our native translation easily using {{ trans() }} syntax */
|
||||
//const _ = require('lodash');
|
||||
|
||||
require('../bootstrap');
|
||||
|
||||
/* Must be declare in every child view*/
|
||||
declare var i18n;
|
||||
|
||||
import Vue from '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'));
|
||||
Vue.component('client-settings', require('../components/client/ClientSettings.vue'));
|
||||
|
||||
window.onload = function () {
|
||||
|
||||
const app = new Vue({
|
||||
el: '#client_edit'
|
||||
});
|
||||
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
require('../bootstrap');
|
||||
|
||||
/* Must be declare in every child view*/
|
||||
declare var i18n;
|
||||
|
||||
import Vue from 'vue';
|
||||
import axios from 'axios';
|
||||
import store from '../store'
|
||||
|
||||
export default store
|
||||
|
||||
Vue.component('client-list', require('../components/client/ClientList.vue'));
|
||||
Vue.component('client-actions', require('../components/client/ClientActions.vue'));
|
||||
Vue.component('vuetable', require('vuetable-2/src/components/Vuetable'));
|
||||
Vue.component('vuetable-pagination', require('vuetable-2/src/components/VuetablePagination'));
|
||||
Vue.component('vuetable-pagination-bootstrap', require('../components/util/VuetablePaginationBootstrap'));
|
||||
Vue.component('vuetable-filter-bar', require('../components/util/VuetableFilterBar'));
|
||||
Vue.component('vuetable-query-filter', require('../components/client/ClientFilters.vue'));
|
||||
Vue.component('vuetable-multi-select', require('../components/util/VuetableMultiSelect.vue'));
|
||||
Vue.component('list-actions', require('../components/util/VueListActions.vue'));
|
||||
|
||||
|
||||
window.onload = function () {
|
||||
|
||||
const app = new Vue({
|
||||
el: '#client_list',
|
||||
store
|
||||
});
|
||||
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
/* Allows us to use our native translation easily using {{ trans() }} syntax */
|
||||
//const _ = require('lodash');
|
||||
|
||||
require('../bootstrap');
|
||||
|
||||
/* Must be declare in every child view*/
|
||||
declare var i18n;
|
||||
|
||||
import Vue from 'vue';
|
||||
|
||||
Vue.component('client-show', require('../components/client/ClientShow.vue'));
|
||||
|
||||
|
||||
window.onload = function () {
|
||||
|
||||
const app = new Vue({
|
||||
el: '#client_show'
|
||||
});
|
||||
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
<template>
|
||||
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenu" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
{{ trans('texts.select') }}
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="dropdownMenu">
|
||||
<a class="dropdown-item" :href="action.url" v-for="action in rowData.actions">{{ action.name }}</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#" @click="itemAction('archive', rowData, rowIndex)" v-if="rowData.deleted_at == null">{{ trans('texts.archive') }}</a>
|
||||
<a class="dropdown-item" href="#" @click="itemAction('restore', rowData, rowIndex)" v-if="rowData.is_deleted == 1 || rowData.deleted_at != null">{{ trans('texts.restore') }}</a>
|
||||
<a class="dropdown-item" href="#" @click="itemAction('delete', rowData, rowIndex)" v-if="rowData.is_deleted == 0">{{ trans('texts.delete') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
rowData: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
rowIndex: {
|
||||
type: Number
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
itemAction (action, data, index) {
|
||||
|
||||
this.$events.fire('single-action', {'action': action, 'ids': [data.id]})
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.custom-actions button.ui.button {
|
||||
padding: 8px 8px;
|
||||
}
|
||||
.custom-actions button.ui.button > i.icon {
|
||||
margin: auto !important;
|
||||
}
|
||||
.dropdown-item {
|
||||
outline:0px;
|
||||
border:0px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
</style>
|
@ -1,180 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" data-toggle="tab" href="#billing" role="tab" aria-controls="billing">{{ trans('texts.billing_address') }}</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="tab" href="#shipping" role="tab" aria-controls="shipping">{{ trans('texts.shipping_address') }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="billing" role="tabpanel">
|
||||
<button type="button" class="btn btn-sm btn-light" v-on:click="$emit('copy', 'copy_shipping')"> {{ trans('texts.copy_shipping') }}</button>
|
||||
<div class="card-body">
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.address1') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" :placeholder="trans('texts.address1')" v-model="client.address1" class="form-control">
|
||||
<div v-if="client.errors.has('address1')" class="text-danger" v-text="client.errors.get('address1')"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.address2') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text":placeholder="trans('texts.address2')" v-model="client.address2" class="form-control">
|
||||
<div v-if="client.errors.has('address2')" class="text-danger" v-text="client.errors.get('address2')"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.city') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text":placeholder="trans('texts.city')" v-model="client.city" class="form-control">
|
||||
<div v-if="client.errors.has('city')" class="text-danger" v-text="client.errors.get('city')"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.state') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" :placeholder="trans('texts.state')" v-model="client.state" class="form-control">
|
||||
<div v-if="client.errors.has('state')" class="text-danger" v-text="client.errors.get('state')"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.postal_code') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" :placeholder="trans('texts.postal_code')" v-model="client.postal_code" class="form-control">
|
||||
<div v-if="client.errors.has('postal_code')" class="text-danger" v-text="client.errors.get('postal_code')"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.country') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<multiselect v-model="billingCountry" :options="options" :placeholder="trans('texts.country')" label="name" track-by="id" @input="onChangeBilling"></multiselect>
|
||||
<div v-if="client.errors.has('country_id')" class="text-danger" v-text="client.errors.get('country_id')"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane" id="shipping" role="tabpanel">
|
||||
<button type="button" class="btn btn-sm btn-light" v-on:click="$emit('copy',' copy_billing')"> {{ trans('texts.copy_billing') }}</button>
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.address1') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" :placeholder="trans('texts.address1')" v-model="client.shipping_address1" class="form-control">
|
||||
<div v-if="client.errors.has('shipping_address1')" class="text-danger" v-text="client.errors.get('shipping_address1')"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.address2') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" :placeholder="trans('texts.address2')" v-model="client.shipping_address2" class="form-control">
|
||||
<div v-if="client.errors.has('shipping_address2')" class="text-danger" v-text="client.errors.get('shipping_address2')"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.city') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" :placeholder="trans('texts.city')" v-model="client.shipping_city" class="form-control">
|
||||
<div v-if="client.errors.has('shipping_city')" class="text-danger" v-text="client.errors.get('shipping_city')"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.state') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" :placeholder="trans('texts.state')" v-model="client.shipping_state" class="form-control">
|
||||
<div v-if="client.errors.has('shipping_state')" class="text-danger" v-text="client.errors.get('shipping_state')"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.postal_code') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" :placeholder="trans('texts.postal_code')" v-model="client.shipping_postal_code" class="form-control">
|
||||
<div v-if="client.errors.has('shipping_postal_code')" class="text-danger" v-text="client.errors.get('shipping_postal_code')"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.country') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<multiselect v-model="shippingCountry" :options="options" :placeholder="trans('texts.country')" label="name" track-by="id" @input="onChangeShipping"></multiselect>
|
||||
<div v-if="client.errors.has('shipping_country_id')" class="text-danger" v-text="client.errors.get('shipping_country_id')"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import Multiselect from 'vue-multiselect'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Multiselect
|
||||
},
|
||||
props: ['client', 'countries'],
|
||||
mounted() {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
options: Object.keys(this.countries).map(i => this.countries[i]),
|
||||
countryArray: Object.keys(this.countries).map(i => this.countries[i])
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
shippingCountry: {
|
||||
set: function() {
|
||||
|
||||
// return this.client.shipping_country_id
|
||||
|
||||
},
|
||||
get: function(value) {
|
||||
|
||||
|
||||
return this.countryArray.filter(obj => {
|
||||
return obj.id === this.client.shipping_country_id
|
||||
})
|
||||
|
||||
}
|
||||
},
|
||||
billingCountry: {
|
||||
set: function() {
|
||||
|
||||
return this.client.country_id
|
||||
|
||||
},
|
||||
get: function(value) {
|
||||
|
||||
return this.countryArray.filter(obj => {
|
||||
return obj.id === this.client.country_id
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
methods: {
|
||||
onChangeShipping(value) {
|
||||
this.client.shipping_country_id = value.id
|
||||
},
|
||||
onChangeBilling(value) {
|
||||
this.client.country_id = value.id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style src="vue-multiselect/dist/vue-multiselect.min.css"></style>
|
@ -1,76 +0,0 @@
|
||||
<template>
|
||||
<div class="card-body">
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.first_name') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input ref="first_name" name="first_name" type="text" :placeholder="trans('texts.first_name')" v-model="contact.first_name" class="form-control">
|
||||
<div v-if="form.errors.has('contacts.'+error_index+'.first_name')" class="text-danger" v-text="form.errors.get('contacts.'+error_index+'.first_name')"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.last_name') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" :placeholder="trans('texts.last_name')" v-model="contact.last_name" class="form-control">
|
||||
<div v-if="form.errors.has('contacts.'+error_index+'.last_name')" class="text-danger" v-text="form.errors.get('contacts.'+error_index+'.last_name')"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.email') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="email" :placeholder="trans('texts.email')" v-model="contact.email" class="form-control">
|
||||
<div v-if="form.errors.has('contacts.'+error_index+'.email')" class="text-danger" v-text="form.errors.get('contacts.'+error_index+'.email')"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.phone') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" :placeholder="trans('texts.phone')" v-model="contact.phone" class="form-control">
|
||||
<div v-if="form.errors.has('contacts.'+error_index+'.phone')" class="text-danger" v-text="form.errors.get('contacts.'+error_index+'.phone')"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row" v-if="!!company.settings.custom_client_contact_label1">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ company.settings.custom_client_contact_label1 }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" :placeholder="trans('texts.custom_value1')" v-model="contact.custom_value1" class="form-control">
|
||||
<div v-if="form.errors.has('contacts.'+error_index+'.custom_value1')" class="text-danger" v-text="form.errors.get('contacts.'+error_index+'.custom_value1')"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row" v-if="!!company.settings.custom_client_contact_label2">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ company.settings.custom_client_contact_label2 }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" :placeholder="trans('texts.custom_value1')" v-model="contact.custom_value2" class="form-control">
|
||||
<div v-if="form.errors.has('contacts.'+error_index+'.custom_value2')" class="text-danger" v-text="form.errors.get('contacts.'+error_index+'.custom_value2')"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row" v-if="!!company.settings.custom_client_contact_label3">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ company.settings.custom_client_contact_label3 }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" :placeholder="trans('texts.custom_value1')" v-model="contact.custom_value3" class="form-control">
|
||||
<div v-if="form.errors.has('contacts.'+error_index+'.custom_value3')" class="text-danger" v-text="form.errors.get('contacts.'+error_index+'.custom_value3')"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row" v-if="!!company.settings.custom_client_contact_label4">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ company.settings.custom_client_contact_label4 }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" :placeholder="trans('texts.custom_value1')" v-model="contact.custom_value4" class="form-control">
|
||||
<div v-if="form.errors.has('contacts.'+error_index+'.custom_value4')" class="text-danger" v-text="form.errors.get('contacts.'+error_index+'.custom_value4')"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="float-right">
|
||||
<button type="button" class="btn btn-danger" v-on:click="$emit('remove',contact)"> {{ trans('texts.remove_contact') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: ['company', 'contact', 'form', 'error_index']
|
||||
}
|
||||
</script>
|
@ -1,72 +0,0 @@
|
||||
<template>
|
||||
<div class="card-body">
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.client_name') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" :placeholder="trans('texts.client_name')" v-model="client.name" class="form-control">
|
||||
<div v-if="client.errors.has('name')" class="text-danger" v-text="client.errors.get('name')"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.id_number') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" name="id_number" :placeholder="trans('texts.id_number')" v-model="client.id_number" class="form-control" id="id_number">
|
||||
<div v-if="client.errors.has('id_number')" class="text-danger" v-text="client.errors.get('id_number')"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.vat_number') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" name="vat_number" :placeholder="trans('texts.vat_number')" v-model="client.vat_number" class="form-control" id="vat_number">
|
||||
<div v-if="client.errors.has('vat_number')" class="text-danger" v-text="client.errors.get('vat_number')"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.website') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" name="website" :placeholder="trans('texts.website')" v-model="client.website" class="form-control" id="websites">
|
||||
<div v-if="client.errors.has('website')" class="text-danger" v-text="client.errors.get('website')"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row" v-if="company.custom_client_label1 && company.custom_client_label1.length >= 1">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ company.custom_client_label1 }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" name="custom_value1" :placeholder="trans('texts.custom_value1')" v-model="client.custom_value1" class="form-control" id="custom_value1">
|
||||
<div v-if="client.errors.has('custom_value1')" class="text-danger" v-text="client.errors.get('custom_value1')"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row" v-if="company.custom_client_label2 && company.custom_client_label2.length >= 1">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ company.custom_client_label2 }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" name="custom_value2" :placeholder="trans('texts.custom_value1')" v-model="client.custom_value2" class="form-control" id="custom_value2">
|
||||
<div v-if="client.errors.has('custom_value2')" class="text-danger" v-text="client.errors.get('custom_value2')"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row" v-if="company.custom_client_label3 && company.custom_client_label3.length >= 1">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ company.custom_client_label3 }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" name="custom_value3" :placeholder="trans('texts.custom_value1')" v-model="client.custom_value3" class="form-control" id="custom_value3">
|
||||
<div v-if="client.errors.has('custom_value3')" class="text-danger" v-text="client.errors.get('custom_value2')"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row" v-if="company.custom_client_label4 && company.custom_client_label4.length >= 1">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ company.custom_client_label2 }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" name="custom_value4" :placeholder="trans('texts.custom_value1')" v-model="client.custom_value4" class="form-control" id="custom_value4">
|
||||
<div v-if="client.errors.has('custom_value4')" class="text-danger" v-text="client.errors.get('custom_value4')"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: ['client','errors', 'company']
|
||||
}
|
||||
</script>
|
@ -1,118 +0,0 @@
|
||||
<template>
|
||||
<form @submit.prevent="onSubmit" @keydown="form.errors.clear($event.target.name)">
|
||||
|
||||
<div class="row">
|
||||
<!-- Client Details and Address Column -->
|
||||
<div class="col-md-6">
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary2">{{ trans('texts.edit_client') }}</div>
|
||||
<client-edit :client="form" :company="company"></client-edit>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary2">{{ trans('texts.address') }}</div>
|
||||
<client-address v-bind:client="form" @copy="copy" :countries="countries"></client-address>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Client Details and Address Column -->
|
||||
|
||||
<!-- Contact Details Column -->
|
||||
<div class="col-md-6">
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary2">{{ trans('texts.contact_information') }}
|
||||
<span class="float-right">
|
||||
<button type="button" class="btn btn-primary btn-sm" @click="add"><i class="fa fa-plus-circle"></i> {{ trans('texts.add_contact') }}</button>
|
||||
</span>
|
||||
</div>
|
||||
<contact-edit v-for="(contact, key, index) in form.contacts"
|
||||
:contact="contact"
|
||||
:form="form"
|
||||
:key="contact.id"
|
||||
:error_index="key"
|
||||
:company="company"
|
||||
@remove="remove"></contact-edit>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Contact Details Column -->
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-12 text-center">
|
||||
|
||||
<button class="btn btn-lg btn-success" type="button" @click="onSubmit"><i class="fa fa-save"></i> {{ trans('texts.save') }}</button>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
import Form from '../../utils/form';
|
||||
import Client from '../../models/client-model';
|
||||
import Vue from 'vue'
|
||||
|
||||
export default {
|
||||
data: function () {
|
||||
return {
|
||||
form: new Form(<Client>this.clientdata)
|
||||
}
|
||||
},
|
||||
props: ['hashed_id', 'clientdata', 'countries', 'company'],
|
||||
beforeMount: function () {
|
||||
},
|
||||
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;
|
||||
//this.$refs.first_name[index].$el.focus();
|
||||
//this.$refs.first_name[index].focus();
|
||||
});
|
||||
},
|
||||
onSubmit() {
|
||||
this.form.put('/clients/' + this.hashed_id)
|
||||
.then(response => this.$root.$refs.toastr.s( Vue.prototype.trans('texts.updated_client') ))
|
||||
.catch(error => {
|
||||
|
||||
this.$root.$refs.toastr.e("Error saving client");
|
||||
|
||||
});
|
||||
},
|
||||
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;
|
||||
}
|
||||
}
|
||||
},
|
||||
created:function() {
|
||||
|
||||
|
||||
},
|
||||
updated:function() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
@ -1,23 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<vuetable-filter-bar></vuetable-filter-bar>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
import Vue from 'vue'
|
||||
|
||||
export default {
|
||||
|
||||
mounted() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style type="text/css">
|
||||
|
||||
</style>
|
@ -1,181 +0,0 @@
|
||||
<template>
|
||||
|
||||
<div>
|
||||
|
||||
<vuetable ref="vuetable"
|
||||
api-url="/clients"
|
||||
:fields="fields"
|
||||
:per-page="perPage"
|
||||
:sort-order="sortOrder"
|
||||
:append-params="moreParams"
|
||||
:css="css.table"
|
||||
pagination-path=""
|
||||
@vuetable:checkbox-toggled="toggledCheckBox()"
|
||||
@vuetable:checkbox-toggled-all="toggledCheckBox()"
|
||||
@vuetable:pagination-data="onPaginationData"></vuetable>
|
||||
|
||||
<div class="vuetable-pagination ui basic segment grid">
|
||||
|
||||
<vuetable-pagination-info ref="paginationInfo"></vuetable-pagination-info>
|
||||
|
||||
<vuetable-pagination ref="pagination"
|
||||
:css="css.pagination"
|
||||
@vuetable-pagination:change-page="onChangePage"></vuetable-pagination>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
import Vuetable from 'vuetable-2/src/components/Vuetable.vue'
|
||||
import VuetablePagination from 'vuetable-2/src/components/VuetablePagination.vue'
|
||||
import VuetablePaginationInfo from 'vuetable-2/src/components/VuetablePaginationInfo.vue'
|
||||
import Vue from 'vue'
|
||||
import VueEvents from 'vue-events'
|
||||
import VuetableCss from '../util/VuetableCss'
|
||||
import axios from 'axios'
|
||||
|
||||
Vue.use(VueEvents)
|
||||
|
||||
declare var bulk_count : number;
|
||||
|
||||
export default {
|
||||
|
||||
components: {
|
||||
Vuetable,
|
||||
VuetablePagination,
|
||||
VuetablePaginationInfo
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
css: VuetableCss,
|
||||
perPage: this.datatable.per_page,
|
||||
sortOrder: this.datatable.sort_order,
|
||||
moreParams: this.$store.getters['client_list/getQueryStringObject'],
|
||||
fields: this.datatable.fields
|
||||
}
|
||||
},
|
||||
props: ['datatable'],
|
||||
mounted() {
|
||||
|
||||
this.$events.$on('filter-set', eventData => this.onFilterSet())
|
||||
this.$events.$on('bulk-action', eventData => this.bulkAction(eventData))
|
||||
this.$events.$on('multi-select', eventData => this.multiSelect(eventData))
|
||||
this.$events.$on('single-action', eventData => this.singleAction(eventData))
|
||||
this.$events.$on('perpage_action', eventData => this.onPerPageUpdate(eventData))
|
||||
|
||||
},
|
||||
methods: {
|
||||
|
||||
onPaginationData (paginationData : any) {
|
||||
|
||||
this.$refs.pagination.setPaginationData(paginationData)
|
||||
this.$refs.paginationInfo.setPaginationData(paginationData)
|
||||
|
||||
},
|
||||
onChangePage (page : any) {
|
||||
|
||||
this.$refs.vuetable.changePage(page)
|
||||
|
||||
},
|
||||
onFilterSet () {
|
||||
|
||||
this.moreParams = this.$store.getters['client_list/getQueryStringObject']
|
||||
Vue.nextTick( () => this.$refs.vuetable.refresh())
|
||||
|
||||
},
|
||||
onPerPageUpdate(per_page){
|
||||
|
||||
this.perPage = Number(per_page)
|
||||
Vue.nextTick( () => this.$refs.vuetable.refresh())
|
||||
|
||||
},
|
||||
bulkAction (action){
|
||||
|
||||
var dataObj = {
|
||||
'action' : action,
|
||||
'ids' : this.$refs.vuetable.selectedTo
|
||||
}
|
||||
|
||||
this.postBulkAction(dataObj)
|
||||
|
||||
},
|
||||
singleAction(dataObj) {
|
||||
|
||||
this.postBulkAction(dataObj)
|
||||
|
||||
},
|
||||
postBulkAction(dataObj) {
|
||||
|
||||
axios.post('/clients/bulk', dataObj)
|
||||
.then((response) => {
|
||||
this.$root.$refs.toastr.s( Vue.prototype.trans('texts.'+dataObj.action+'d_client') )
|
||||
this.$store.commit('client_list/setBulkCount', 0)
|
||||
this.$refs.vuetable.selectedTo = []
|
||||
this.$refs.vuetable.refresh()
|
||||
// console.dir(response)
|
||||
})
|
||||
.catch(function (error) {
|
||||
this.$root.$refs.toastr.e( "A error occurred" )
|
||||
});
|
||||
|
||||
},
|
||||
toggledCheckBox(){
|
||||
this.$store.commit('client_list/setBulkCount', this.$refs.vuetable.selectedTo.length)
|
||||
},
|
||||
multiSelect(value)
|
||||
{
|
||||
this.moreParams = this.$store.getters['client_list/getQueryStringObject']
|
||||
Vue.nextTick( () => this.$refs.vuetable.refresh())
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style type="text/css">
|
||||
|
||||
.pagination {
|
||||
margin: 0;
|
||||
float: right;
|
||||
}
|
||||
.pagination a.page {
|
||||
border: 1px solid lightgray;
|
||||
border-radius: 3px;
|
||||
padding: 5px 10px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
.pagination a.page.active {
|
||||
color: white;
|
||||
background-color: #337ab7;
|
||||
border: 1px solid lightgray;
|
||||
border-radius: 3px;
|
||||
padding: 5px 10px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
.pagination a.btn-nav {
|
||||
border: 1px solid lightgray;
|
||||
border-radius: 3px;
|
||||
padding: 5px 7px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
.pagination a.btn-nav.disabled {
|
||||
color: lightgray;
|
||||
border: 1px solid lightgray;
|
||||
border-radius: 3px;
|
||||
padding: 5px 7px;
|
||||
margin-right: 2px;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.pagination-info {
|
||||
float: left;
|
||||
}
|
||||
th {
|
||||
background: #777777;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
</style>
|
@ -1,421 +0,0 @@
|
||||
<template>
|
||||
|
||||
<div class="row" style="background:#fff; padding:20px;">
|
||||
|
||||
<div class="col-2" style="border: 0px; border-style:solid;">
|
||||
|
||||
<affix class="menu sidebar-menu" relative-element-selector="#example-content" :offset="{ top: 50, bottom:100 }" :scroll-affix="false" style="width: 200px">
|
||||
<div class="menu-label">
|
||||
<h3 style="color:#5d5d5d;">{{ trans('texts.settings') }}</h3>
|
||||
</div>
|
||||
<scrollactive
|
||||
class="menu-list"
|
||||
active-class="is-active"
|
||||
:offset="50"
|
||||
:duration="800"
|
||||
:exact="true"
|
||||
>
|
||||
<ul class="list-inline justify-content-left">
|
||||
<li class="menu-li"><a href="#intro" class="scrollactive-item" >{{trans('t.client_settings')}}</a></li>
|
||||
<li class="menu-li"><a href="#standard-affix" class="scrollactive-item" >{{trans('texts.messages')}}</a></li>
|
||||
<li class="menu-li"><a href="#scroll-affix" class="scrollactive-item" >{{trans('texts.classify')}}</a></li>
|
||||
</ul>
|
||||
</scrollactive>
|
||||
</affix>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col-10">
|
||||
|
||||
<div id="example-content">
|
||||
|
||||
<section id="intro">
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary2">{{ trans('t.client_settings') }}</div>
|
||||
<div class="card-body px-3">
|
||||
<div class="form-group row client_form">
|
||||
<label for="name" class="col-sm-5 text-left">
|
||||
<div>{{ trans('texts.currency') }}</div>
|
||||
<div style="margin-top:1px; line-height:1.4; color:#939393;">{{ trans('help.client_currency') }}</div>
|
||||
</label>
|
||||
<div class="col-sm-7">
|
||||
<multiselect v-model="settings.currency_id" :options="options_currency" label="name" track-by="id" :allow-empty="true" @select="currencySettingChange()"></multiselect>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row client_form d-flex justify-content-center">
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" id="inline-radio1" type="radio" name="symbol" value="1" v-model="settings.show_currency_symbol" @click="setCurrencySymbol()">
|
||||
<label class="form-check-label" for="show_currency_symbol-radio1">{{ trans('texts.currency_symbol') }}: {{ currency_symbol_example }}</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" id="inline-radio2" type="radio" name="code" value="1" v-model="settings.show_currency_code" @click="setCurrencyCode()">
|
||||
<label class="form-check-label" for="show_currency_code">{{ trans('texts.currency_code') }}: {{ currency_code_example }}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row client_form">
|
||||
<label for="language" class="col-sm-5 text-left">
|
||||
<div>{{ trans('texts.language') }}</div>
|
||||
<div style="margin-top:1px; line-height:1.4; color:#939393;">{{ trans('help.client_language')}}</div>
|
||||
</label>
|
||||
<div class="col-sm-7">
|
||||
<multiselect v-model="settings.language_id" :options="options_language" :placeholder="placeHolderLanguage()" label="name" track-by="id" :allow-empty="true"></multiselect>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row client_form">
|
||||
<label for="payment_terms" class="col-sm-5 text-left">
|
||||
<div>{{ trans('texts.payment_terms') }}</div>
|
||||
<div style="margin-top:1px; line-height:1.4; color:#939393;">{{ trans('help.client_payment_terms')}}</div>
|
||||
</label>
|
||||
<div class="col-sm-7">
|
||||
<multiselect v-model="settings.payment_terms" :options="options_payment_term" :placeholder="placeHolderPaymentTerm()" label="name" track-by="num_days" :allow-empty="true"></multiselect>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row client_form">
|
||||
<label for="name" class="col-sm-5 col-form-label text-left">
|
||||
<div>{{ trans('texts.task_rate') }}</div>
|
||||
<div style="margin-top:1px; line-height:1.4; color:#939393;">{{ trans('texts.task_rate_help')}}</div>
|
||||
</label>
|
||||
<div class="col-sm-7">
|
||||
<input type="text" :placeholder="trans('texts.task_rate')" class="form-control" v-model="settings.task_rate">
|
||||
<div v-if="" class="text-danger" v-text=""></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row client_form">
|
||||
<label for="name" class="col-sm-5 col-form-label text-left">{{ trans('texts.send_client_reminders') }}</label>
|
||||
<div class="col-sm-7">
|
||||
<label class="switch switch-label switch-pill switch-info">
|
||||
<input class="switch-input" type="checkbox" checked="" v-model="settings.send_reminders">
|
||||
<span class="switch-slider" data-checked="✓" data-unchecked="✕"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row client_form">
|
||||
<label for="name" class="col-sm-5 col-form-label text-left">{{ trans('texts.show_tasks_in_portal') }}</label>
|
||||
<div class="col-sm-7">
|
||||
<label class="switch switch-label switch-pill switch-info">
|
||||
<input class="switch-input" type="checkbox" checked="" v-model="settings.show_tasks_in_portal">
|
||||
<span class="switch-slider" data-checked="✓" data-unchecked="✕"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="standard-affix">
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary2">{{ trans('texts.messages') }}</div>
|
||||
<div class="card-body">
|
||||
<div class="form-group row client_form">
|
||||
<label for="name" class="col-sm-5 col-form-label text-left">
|
||||
<div>{{ trans('texts.dashboard') }}</div>
|
||||
<div style="margin-top:1px; line-height:1.4; color:#939393;">{{ trans('help.client_dashboard')}}</div>
|
||||
</label>
|
||||
<div class="col-sm-7">
|
||||
<textarea class="form-control" id="textarea-input" label="dashboard" v-model="settings.custom_message_dashboard"rows="9" :placeholder="placeHolderMessage('custom_message_dashboard')"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row client_form">
|
||||
<label for="name" class="col-sm-5 col-form-label text-left">
|
||||
<div>{{ trans('texts.unpaid_invoice') }}</div>
|
||||
<div style="margin-top:1px; line-height:1.4; color:#939393;">{{ trans('help.client_unpaid_invoice')}}</div>
|
||||
</label>
|
||||
<div class="col-sm-7">
|
||||
<textarea class="form-control" id="textarea-input" label="unpaid_invoice" v-model="settings.custom_message_unpaid_invoice"rows="9" :placeholder="placeHolderMessage('custom_message_unpaid_invoice')"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row client_form">
|
||||
<label for="name" class="col-sm-5 col-form-label text-left">
|
||||
<div>{{ trans('texts.paid_invoice') }}</div>
|
||||
<div style="margin-top:1px; line-height:1.4; color:#939393;">{{trans('help.client_paid_invoice')}}</div>
|
||||
</label>
|
||||
<div class="col-sm-7">
|
||||
<textarea class="form-control" id="textarea-input" label="paid_invoice" v-model="settings.custom_message_paid_invoice" rows="9" :placeholder="placeHolderMessage('custom_message_paid_invoice')"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row client_form">
|
||||
<label class="col-sm-5 col-form-label text-left" for="unapproved_quote">
|
||||
<div>{{ trans('texts.unapproved_quote') }}</div>
|
||||
<div style="margin-top:1px; line-height:1.4; color:#939393;">{{trans('help.client_unapproved_quote')}}</div>
|
||||
</label>
|
||||
<div class="col-md-7">
|
||||
<textarea class="form-control" id="textarea-input" label="unapproved_quote" v-model="settings.custom_message_unapproved_quote" rows="9" :placeholder="placeHolderMessage('custom_message_unapproved_quote')"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="scroll-affix">
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary2">{{ trans('texts.classify') }}</div>
|
||||
<div class="card-body">
|
||||
<div class="form-group row client_form">
|
||||
<label for="name" class="col-sm-5 col-form-label text-left">{{ trans('texts.industry') }}</label>
|
||||
<div class="col-sm-7">
|
||||
<multiselect :options="options_industry" :placeholder="placeHolderIndustry()" label="name" track-by="id" v-model="settings.industry_id"></multiselect>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row client_form">
|
||||
<label for="name" class="col-sm-5 col-form-label text-left">{{ trans('texts.size_id') }}</label>
|
||||
<div class="col-sm-7">
|
||||
<multiselect :options="options_size" :placeholder="placeHolderSize()" label="name" track-by="id" v-model="settings.size_id"></multiselect>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
import Vue from 'vue'
|
||||
import { Affix } from 'vue-affix'
|
||||
var VueScrollactive = require('vue-scrollactive')
|
||||
import NumberFormat from '../../utils/number-format'
|
||||
import Multiselect from 'vue-multiselect'
|
||||
import ClientSettings from '../../utils/client-settings'
|
||||
|
||||
Vue.use(VueScrollactive);
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Affix,
|
||||
Multiselect,
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
options_currency: Object.keys(this.currencies).map(i => this.currencies[i]),
|
||||
options_language: Object.keys(this.languages).map(i => this.languages[i]),
|
||||
options_payment_term: Object.keys(this.payment_terms).map(i => this.payment_terms[i]),
|
||||
options_industry: Object.keys(this.industries).map(i => this.industries[i]),
|
||||
options_size: this.sizes,
|
||||
settings: this.client_settings
|
||||
}
|
||||
},
|
||||
props: ['client_settings', 'currencies', 'languages', 'payment_terms', 'industries', 'sizes', 'company'],
|
||||
mounted() {
|
||||
|
||||
//console.dir(this.settings)
|
||||
this.updateCurrencyExample()
|
||||
},
|
||||
computed: {
|
||||
currency_code_example: {
|
||||
get: function() {
|
||||
return this.updateCurrencyExample(false)
|
||||
},
|
||||
set: function() {
|
||||
}
|
||||
},
|
||||
currency_symbol_example: {
|
||||
get: function() {
|
||||
return this.updateCurrencyExample(true)
|
||||
},
|
||||
set: function() {
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setObjectValue(key, value){
|
||||
|
||||
if(value === null)
|
||||
this.settings[key] = null
|
||||
else
|
||||
this.settings[key] = value
|
||||
|
||||
},
|
||||
placeHolderCurrency(){
|
||||
|
||||
var currency = this.options_currency.find(obj => {
|
||||
return obj.id == this.company.settings_object.currency_id
|
||||
})
|
||||
|
||||
if(currency)
|
||||
return currency.name
|
||||
else
|
||||
return Vue.prototype.trans('texts.currency_id')
|
||||
|
||||
},
|
||||
placeHolderPaymentTerm(){
|
||||
|
||||
var payment_terms = this.payment_terms.find(obj => {
|
||||
return obj.num_days == this.company.settings_object.payment_terms
|
||||
})
|
||||
|
||||
if(payment_terms)
|
||||
return payment_terms.name
|
||||
else
|
||||
return Vue.prototype.trans('texts.payment_terms')
|
||||
|
||||
},
|
||||
placeHolderIndustry(){
|
||||
|
||||
return Vue.prototype.trans('texts.industry_id')
|
||||
|
||||
},
|
||||
placeHolderSize(){
|
||||
|
||||
return Vue.prototype.trans('texts.size_id')
|
||||
|
||||
},
|
||||
placeHolderLanguage(){
|
||||
|
||||
var language = this.languages.find(obj => {
|
||||
return obj.id == this.company.settings_object.language_id
|
||||
})
|
||||
|
||||
if(language)
|
||||
return language.name
|
||||
else
|
||||
return Vue.prototype.trans('texts.language_id')
|
||||
|
||||
},
|
||||
placeHolderMessage(message_setting : string) {
|
||||
|
||||
if(this.company.settings_object[message_setting] && this.company.settings_object[message_setting].length >=1) {
|
||||
|
||||
return this.company.settings_object[message_setting]
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
setCurrencyCode() {
|
||||
this.settings.show_currency_symbol = false;
|
||||
this.settings.show_currency_code = true;
|
||||
|
||||
this.currencySettingChange()
|
||||
|
||||
},
|
||||
setCurrencySymbol() {
|
||||
|
||||
this.settings.show_currency_symbol = true;
|
||||
this.settings.show_currency_code = false;
|
||||
|
||||
this.currencySettingChange()
|
||||
|
||||
},
|
||||
updateCurrencyExample(currency_symbol) {
|
||||
|
||||
|
||||
var currency = this.options_currency.find(obj => {
|
||||
return obj.id == this.company.settings_object.currency_id
|
||||
})
|
||||
|
||||
var language = this.languages.find(obj => {
|
||||
return obj.id == this.company.settings_object.language_id
|
||||
})
|
||||
|
||||
|
||||
if(this.settings_language_id)
|
||||
language = this.settings_language_id
|
||||
|
||||
if(this.settings_currency_id)
|
||||
currency = this.settings_currency_id
|
||||
|
||||
return new NumberFormat(1000, currency, currency_symbol, language).format()
|
||||
},
|
||||
currencySettingChange() {
|
||||
this.currency_code_example = this.updateCurrencyExample(false)
|
||||
this.currency_symbol_example = this.updateCurrencyExample(true)
|
||||
|
||||
console.dir(this.currency_symbol_example)
|
||||
console.dir(this.currency_code_example)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
|
||||
#example-content {
|
||||
}
|
||||
|
||||
.client_form {
|
||||
border-bottom: 0px;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-color: #167090;
|
||||
}
|
||||
|
||||
.menu-li {
|
||||
list-style: none;
|
||||
padding-left:5px;
|
||||
width:200px;
|
||||
line-height:1.4;
|
||||
margin-top:10px;
|
||||
|
||||
}
|
||||
|
||||
a.scrollactive-item.is-active {
|
||||
color: #027093;
|
||||
font-family: helvetica;
|
||||
text-decoration: none;
|
||||
border-left-style: solid;
|
||||
border-left-color: #027093;
|
||||
padding-left:10px;
|
||||
|
||||
}
|
||||
|
||||
a.scrollactive-item.is-active:hover {
|
||||
text-decoration: none;
|
||||
|
||||
color: #027093;
|
||||
padding-left:10px;
|
||||
|
||||
}
|
||||
|
||||
a.scrollactive-item.is-active:active {
|
||||
color: #027093;
|
||||
padding-left:10px;
|
||||
|
||||
}
|
||||
|
||||
|
||||
.menu-list a {
|
||||
color: #939393;
|
||||
|
||||
font-family: helvetica;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.menu-list a:hover {
|
||||
text-decoration: none;
|
||||
|
||||
color: #027093;
|
||||
padding-left:5px;
|
||||
|
||||
}
|
||||
|
||||
.menu-list a:active {
|
||||
color: #027093;
|
||||
text-decoration: none;
|
||||
padding-left:5px;
|
||||
|
||||
}
|
||||
|
||||
|
||||
</style>
|
@ -1,181 +0,0 @@
|
||||
<template>
|
||||
|
||||
<div class="container-fluid">
|
||||
|
||||
<div class="row">
|
||||
<div class="col" style="padding: 0px;">
|
||||
|
||||
<div class="float-right">
|
||||
|
||||
<div class="btn-group ml-2">
|
||||
<button type="button" class="btn btn-lg btn-secondary" :disabled="editClientIsDisabled" v-for="link in this.meta.edit_client_route" @click="goToUrl(link.url)">{{ trans('texts.edit_client') }}</button>
|
||||
<button type="button" class="btn btn-lg btn-secondary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" :disabled="editClientIsDisabled">
|
||||
<span class="sr-only">Toggle Dropdown</span>
|
||||
</button>
|
||||
<div class="dropdown-menu" x-placement="top-start" style="position: absolute; transform: translate3d(189px, -2px, 0px); top: 0px; left: 0px; will-change: transform;">
|
||||
<a class="dropdown-item" href="#" @click="itemAction('archive', client, rowIndex)" v-if="client.deleted_at == null">{{ trans('texts.archive') }}</a>
|
||||
<a class="dropdown-item" href="#" @click="itemAction('restore', client, rowIndex)" v-if="client.is_deleted == 1 || client.deleted_at != null">{{ trans('texts.restore') }}</a>
|
||||
<a class="dropdown-item" href="#" @click="itemAction('delete', client, rowIndex)" v-if="client.is_deleted == 0">{{ trans('texts.delete') }}</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" @click="itemAction('purge', client, rowIndex)">{{ trans('texts.purge_client') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="btn-group ml-2">
|
||||
<button type="button" class="btn btn-lg btn-primary" :disabled="viewStatementIsDisabled" v-for="link in this.meta.view_statement_route" @click="goToUrl(link.url)">{{ trans('texts.view_statement') }}</button>
|
||||
<button type="button" class="btn btn-lg btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" :disabled="viewStatementIsDisabled">
|
||||
<span class="sr-only">Toggle Dropdown</span>
|
||||
</button>
|
||||
<div class="dropdown-menu" x-placement="top-start" style="position: absolute; transform: translate3d(189px, -2px, 0px); top: 0px; left: 0px; will-change: transform;">
|
||||
<a class="dropdown-item" v-for="link in this.meta.view_statement_actions" :href="link.url">{{ link.name }}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
|
||||
<div class="col-sm">
|
||||
<h3> {{ trans('texts.details') }} </h3>
|
||||
<p v-if="client.id_number && client.id_number.length >= 1"><b>{{ trans('texts.id_number') }}:</b> {{ client.id_number }}</p>
|
||||
<p v-if="client.vat_number && client.vat_number.length >= 1"><b>{{ trans('texts.vat_number') }}:</b> {{ client.vat_number }}</p>
|
||||
<p v-if="client.custom_value1 && client.custom_value1.length >= 1"><b>{{ company.custom_client_label1 }}:</b> {{ client.custom_value1 }}</p>
|
||||
<p v-if="client.custom_value2 && client.custom_value2.length >= 1"><b>{{ company.custom_client_label2 }}:</b> {{ client.custom_value2 }}</p>
|
||||
<p v-if="client.custom_value3 && client.custom_value3.length >= 1"><b>{{ company.custom_client_label3 }}:</b> {{ client.custom_value3 }}</p>
|
||||
<p v-if="client.custom_value4 && client.custom_value4.length >= 1"><b>{{ company.custom_client_label4 }}:</b> {{ client.custom_value4 }}</p>
|
||||
</div>
|
||||
|
||||
<div class="col-sm">
|
||||
<ul>
|
||||
<li><h3> {{ trans('texts.address') }} </h3></li>
|
||||
<li><b> {{ trans('texts.billing_address') }}</b></li>
|
||||
<li v-if="client.address1 && client.address1.length >=1">{{ client.address1 }} <br></li>
|
||||
<li v-if="client.address2 && client.address2.length >=1">{{ client.address2 }} <br></li>
|
||||
<li v-if="client.city && client.city.length >=1">{{ client.city }} <br></li>
|
||||
<li v-if="client.state && client.state.length >=1" >{{ client.state}} {{client.postal_code}}<br></li>
|
||||
<li v-if="client.country && client.country.name.length >=1">{{ client.country.name }}<br></li>
|
||||
</ul>
|
||||
|
||||
<ul v-if="client.shipping_address1 && client.shipping_address1.length >=1">
|
||||
<li><b> {{ trans('texts.shipping_address') }}</b></li>
|
||||
<li v-if="client.shipping_address1 && client.shipping_address1.length >=1">{{ client.shipping_address1 }} <br></li>
|
||||
<li v-if="client.shipping_address2 && client.shipping_address2.length >=1">{{ client.shipping_address2 }} <br></li>
|
||||
<li v-if="client.shipping_city && client.shipping_city.length >=1">{{ client.shipping_city }} <br></li>
|
||||
<li v-if="client.shipping_state && client.shipping_state.length >=1" >{{ client.shipping_state}} {{client.shipping_postal_code}}<br></li>
|
||||
<li v-if="client.shipping_country && client.shipping_country.name.length >=1">{{ client.shipping_country.name }}<br></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="col-sm">
|
||||
<h3> {{ trans('texts.contacts') }} </h3>
|
||||
|
||||
<ul v-for="contact in client.contacts">
|
||||
<li v-if="contact.first_name">{{ contact.first_name }} {{ contact.last_name }}</li>
|
||||
<li v-if="contact.email">{{ contact.email }}</li>
|
||||
<li v-if="contact.phone">{{ contact.phone }}</li>
|
||||
<li v-if="company.custom_client_contact_label1 && company.custom_client_contact_label1.length >= 1"><b>{{ company.custom_client_contact_label1 }}:</b> {{ contact.custom_value1 }}</li>
|
||||
<li v-if="company.custom_client_contact_label2 && company.custom_client_contact_label2.length >= 1"><b>{{ company.custom_client_contact_label2 }}:</b> {{ contact.custom_value2 }}</li>
|
||||
<li v-if="company.custom_client_contact_label3 && company.custom_client_contact_label3.length >= 1"><b>{{ company.custom_client_contact_label3 }}:</b> {{ contact.custom_value3 }}</li>
|
||||
<li v-if="company.custom_client_contact_label4 && company.custom_client_contact_label4.length >= 1"><b>{{ company.custom_client_contact_label4 }}:</b> {{ contact.custom_value4 }}</li>
|
||||
</ul>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col-sm">
|
||||
<h3> {{ trans('texts.standing') }} </h3>
|
||||
<p><b>{{ trans('texts.paid_to_date') }} {{client.paid_to_date}}</b></p>
|
||||
<p><b>{{ trans('texts.balance') }} {{client.balance }}</b></p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div v-if="this.meta.google_maps_api_key">
|
||||
|
||||
<iframe
|
||||
width="100%"
|
||||
height="200px"
|
||||
frameborder="0" style="border:0"
|
||||
:src="mapUrl" allowfullscreen>
|
||||
</iframe>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
export default {
|
||||
props: ['client', 'company', 'meta'],
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
goToUrl(url) {
|
||||
location.href=url
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
mapUrl: {
|
||||
get: function() {
|
||||
return `https://www.google.com/maps/embed/v1/place?key=${this.meta.google_maps_api_key}&q=${this.clientAddress}`
|
||||
}
|
||||
},
|
||||
clientAddress: {
|
||||
get: function() {
|
||||
|
||||
var addressArray = []
|
||||
|
||||
if(this.client.address1)
|
||||
addressArray.push(this.client.address1.split(' ').join('+'))
|
||||
|
||||
if(this.client.address2)
|
||||
addressArray.push(this.client.address2.split(' ').join('+'))
|
||||
|
||||
if(this.client.city)
|
||||
addressArray.push(this.client.city.split(' ').join('+'))
|
||||
|
||||
if(this.client.state)
|
||||
addressArray.push(this.client.state.split(' ').join('+'))
|
||||
|
||||
if(this.client.postal_code)
|
||||
addressArray.push(this.client.postal_code.split(' ').join('+'))
|
||||
|
||||
if(this.client.country.name)
|
||||
addressArray.push(this.client.country.name.split(' ').join('+'))
|
||||
|
||||
return encodeURIComponent(addressArray.join(","))
|
||||
}
|
||||
},
|
||||
viewStatementIsDisabled() :any
|
||||
{
|
||||
return ! this.meta.view_statement_permission
|
||||
},
|
||||
editClientIsDisabled() :any
|
||||
{
|
||||
return ! this.meta.edit_client_permission
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.card { margin-top:50px; }
|
||||
|
||||
li { list-style: none }
|
||||
</style>
|
@ -1,58 +0,0 @@
|
||||
<template>
|
||||
<div class="card-body">
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.address1') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" name="address1" :placeholder="trans('texts.address1')" v-model="data.address1" class="form-control" id="address1">
|
||||
<div v-if="errors && errors.address1" class="text-danger">{{ errors.address1[0] }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.address2') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" name="address2" :placeholder="trans('texts.address2')" v-model="data.address2" class="form-control" id="address2">
|
||||
<div v-if="errors && errors.address2" class="text-danger">{{ errors.address2[0] }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.city') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" name="city" :placeholder="trans('texts.city')" v-model="data.city" class="form-control" id="city">
|
||||
<div v-if="errors && errors.city" class="text-danger">{{ errors.city[0] }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.state') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" name="state" :placeholder="trans('texts.state')" v-model="data.state" class="form-control" id="state">
|
||||
<div v-if="errors && errors.state" class="text-danger">{{ errors.state[0] }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.postal_code') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" name="postal_code" :placeholder="trans('texts.postal_code')" v-model="data.postal_code" class="form-control" id="postal_code">
|
||||
<div v-if="errors && errors.postal_code" class="text-danger">{{ errors.postal_code[0] }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">{{ trans('texts.country') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" name="country" :placeholder="trans('texts.country')" v-model="data.country" class="form-control" id="country">
|
||||
<div v-if="errors && errors.country" class="text-danger">{{ errors.country[0] }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: ['data', 'errors'],
|
||||
default: () => {}
|
||||
}
|
||||
</script>
|
@ -1,117 +0,0 @@
|
||||
<template>
|
||||
|
||||
<div class="d-flex justify-content-start">
|
||||
|
||||
<div class="p-2">
|
||||
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-primary btn-lg dropdown-toggle" type="button" :disabled="getBulkCount() == 0" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{{ trans('texts.action') }} <span v-if="getBulkCount() > 0">({{ getBulkCount() }})</span></button>
|
||||
<div class="dropdown-menu" x-placement="bottom-start" style="position: absolute; will-change: transform; top: 0px; left: 0px; transform: translate3d(0px, 44px, 0px);">
|
||||
<a class="dropdown-item" @click="archive" href="#">{{ trans('texts.archive') }}</a>
|
||||
<a class="dropdown-item" @click="restore" href="#">{{ trans('texts.restore') }}</a>
|
||||
<a class="dropdown-item" @click="del" href="#">{{ trans('texts.delete') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="p-2">
|
||||
<vuetable-multi-select :select_options="listaction.multi_select"></vuetable-multi-select>
|
||||
</div>
|
||||
|
||||
<div class="mr-auto p-2">
|
||||
<div class="input-group mb-3">
|
||||
|
||||
<select class="custom-select" id="per_page" v-model="per_page" @change="updatePerPage()">
|
||||
<option value="10">10</option>
|
||||
<option value="25">25</option>
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
</select>
|
||||
|
||||
<div class="input-group-append">
|
||||
<label class="input-group-text" for="per_page">{{trans('texts.rows')}}</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ml-auto p-2">
|
||||
<vuetable-query-filter></vuetable-query-filter>
|
||||
</div>
|
||||
|
||||
<div class="p-2">
|
||||
<button class="btn btn-primary btn-lg " @click="goToUrl(listaction.create_entity.url)" :disabled="isDisabled">{{ trans('texts.new_client') }}</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
export default {
|
||||
props: {
|
||||
listaction: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
per_page_prop: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
|
||||
per_page: this.per_page_prop
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
archive () {
|
||||
|
||||
this.$events.fire('bulk-action', 'archive')
|
||||
|
||||
},
|
||||
del () {
|
||||
|
||||
this.$events.fire('bulk-action', 'delete')
|
||||
|
||||
},
|
||||
restore() {
|
||||
|
||||
this.$events.fire('bulk-action', 'restore')
|
||||
|
||||
},
|
||||
getBulkCount() {
|
||||
|
||||
return this.$store.getters['client_list/getBulkCount']
|
||||
|
||||
},
|
||||
goToUrl: function (url) {
|
||||
|
||||
location.href=url
|
||||
|
||||
},
|
||||
updatePerPage() {
|
||||
|
||||
this.$events.fire('perpage_action', this.per_page)
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isDisabled() :any
|
||||
{
|
||||
return !this.listaction.create_entity.create_permission;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
select.custom-select {
|
||||
height: 42px;
|
||||
}
|
||||
</style>
|
@ -1,23 +0,0 @@
|
||||
export default {
|
||||
table: {
|
||||
tableClass: 'table table-striped table-hover',
|
||||
loadingClass: 'loading',
|
||||
ascendingIcon: 'fa fa-angle-double-up',
|
||||
descendingIcon: 'fa fa-angle-double-down',
|
||||
handleIcon: 'glyphicon glyphicon-menu-hamburger',
|
||||
},
|
||||
pagination: {
|
||||
infoClass: 'pull-left',
|
||||
wrapperClass: 'vuetable-pagination pull-right',
|
||||
activeClass: 'btn-primary',
|
||||
disabledClass: 'disabled',
|
||||
pageClass: 'btn btn-border',
|
||||
linkClass: 'btn btn-border',
|
||||
icons: {
|
||||
first: '',
|
||||
prev: '',
|
||||
next: '',
|
||||
last: '',
|
||||
},
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
<template>
|
||||
|
||||
<div class="input-group">
|
||||
|
||||
<input type="text" v-model="filterText" class="form-control" @keyup.enter="doFilter" placeholder="search">
|
||||
<button class="btn btn-primary" style="margin-left:15px;" @click="doFilter">Go</button>
|
||||
<!--<button class="btn btn-light" @click="resetFilter">Reset</button>-->
|
||||
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
import Vue from 'vue'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
|
||||
filterText: ''
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
doFilter () {
|
||||
|
||||
this.$store.commit('client_list/setFilterText', this.filterText)
|
||||
this.$events.fire('filter-set','')
|
||||
|
||||
},
|
||||
resetFilter () {
|
||||
|
||||
this.$store.commit('client_list/setFilterText', '')
|
||||
this.$events.fire('filter-set','')
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
.form-inline > * {
|
||||
margin:5px 10px;
|
||||
}
|
||||
.form-control {
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
</style>
|
@ -1,54 +0,0 @@
|
||||
<template>
|
||||
<div style="width:300px;">
|
||||
<multiselect v-model="value"
|
||||
:options="options"
|
||||
:multiple="true"
|
||||
:placeholder="trans('texts.status')"
|
||||
:preselect-first="true"
|
||||
label="name"
|
||||
track-by="name"
|
||||
@input="onChange"
|
||||
></multiselect>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
import Multiselect from 'vue-multiselect'
|
||||
|
||||
export default {
|
||||
components: { Multiselect },
|
||||
props:['select_options'],
|
||||
data () {
|
||||
return {
|
||||
value : [],
|
||||
options: this.select_options
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
this.$events.fire('multi-select', '')
|
||||
|
||||
},
|
||||
methods: {
|
||||
onChange (value) {
|
||||
|
||||
this.$store.commit('client_list/setStatusArray', value)
|
||||
this.$events.fire('multi-select', '')
|
||||
|
||||
if (value.indexOf('Reset me!') !== -1) this.value = []
|
||||
|
||||
},
|
||||
onSelect (option) {
|
||||
|
||||
if (option === 'Disable me!') this.isDisabled = true
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style src="vue-multiselect/dist/vue-multiselect.min.css"></style>
|
||||
|
||||
<style>
|
||||
</style>
|
@ -1,37 +0,0 @@
|
||||
<template>
|
||||
<ul class="pagination">
|
||||
<li :class="{'disabled': isOnFirstPage}">
|
||||
<a href="" @click.prevent="loadPage('prev')">
|
||||
<span>«</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<template v-if="notEnoughPages">
|
||||
<li v-for="n in totalPage" :class="{'active': isCurrentPage(n)}">
|
||||
<a @click.prevent="loadPage(n)" v-html="n"></a>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<li v-for="n in windowSize" :class="{'active': isCurrentPage(windowStart+n-1)}">
|
||||
<a @click.prevent="loadPage(windowStart+n-1)" v-html="windowStart+n-1"></a>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
<li :class="{'disabled': isOnLastPage}">
|
||||
<a href="" @click.prevent="loadPage('next')">
|
||||
<span>»</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import VuetablePaginationMixin from 'vuetable-2/src/components/VuetablePaginationMixin'
|
||||
|
||||
export default {
|
||||
mixins: [VuetablePaginationMixin]
|
||||
}
|
||||
|
||||
</script>
|
@ -1,37 +0,0 @@
|
||||
export default class ClientContact {
|
||||
|
||||
id: number
|
||||
client_id: number
|
||||
user_id: number
|
||||
company_id: number
|
||||
first_name: string
|
||||
last_name: string
|
||||
phone: string
|
||||
custom_value1: string
|
||||
custom_value2: string
|
||||
email: string
|
||||
email_verified_at: string
|
||||
confirmation_code: string
|
||||
is_primary: boolean
|
||||
confirmed: boolean
|
||||
failed_logins: number
|
||||
oauth_user_id: string
|
||||
oauth_provider_id: string
|
||||
google_2fa_secret: string
|
||||
accepted_terms_version: string
|
||||
avatar: string
|
||||
avatar_width: string
|
||||
avatar_height: string
|
||||
avatar_size: string
|
||||
db: string
|
||||
password: string
|
||||
remember_token: string
|
||||
deleted_at: string
|
||||
created_at: string
|
||||
updated_at: string
|
||||
|
||||
public constructor(init?:Partial<ClientContact>) {
|
||||
(<any>Object).assign(this, init);
|
||||
}
|
||||
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
export default class Client {
|
||||
|
||||
id: number
|
||||
name: string
|
||||
user_id: number
|
||||
company_id: number
|
||||
website: string
|
||||
private_notes: string
|
||||
balance: number
|
||||
paid_to_date: number
|
||||
last_login: string
|
||||
industry_id: number
|
||||
size_id: number
|
||||
currency_id: number
|
||||
address1: string
|
||||
address2: string
|
||||
city: string
|
||||
state: string
|
||||
postal_code: string
|
||||
country_id: number
|
||||
latitude: number
|
||||
longitude: number
|
||||
shipping_latitude: number
|
||||
shipping_longitude: number
|
||||
custom_value1: string
|
||||
custom_value2: string
|
||||
shipping_address1: string
|
||||
shipping_address2: string
|
||||
shipping_city: string
|
||||
shipping_state: string
|
||||
shipping_postal_code: string
|
||||
shipping_country_id: number
|
||||
is_deleted: boolean
|
||||
payment_terms: string
|
||||
vat_number: string
|
||||
id_number: string
|
||||
created_at: string
|
||||
updated_at: string
|
||||
|
||||
public constructor(init?:Partial<Client>) {
|
||||
(<any>Object).assign(this, init);
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
export default class ClientSettings {
|
||||
|
||||
timezone_id:number
|
||||
language_id:number
|
||||
currency_id:number
|
||||
default_task_rate:number
|
||||
send_reminders:boolean
|
||||
show_tasks_in_portal:boolean
|
||||
custom_message_dashboard:string
|
||||
custom_message_unpaid_invoice:string
|
||||
custom_message_paid_invoice:string
|
||||
custom_message_unapproved_quote:string
|
||||
show_currency_symbol:boolean
|
||||
show_currency_code:boolean
|
||||
industry_id:number
|
||||
size_id:number
|
||||
|
||||
constructor(init?:Partial<ClientSettings>) {
|
||||
(<any>Object).assign(this, init);
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
|
||||
import Vue from 'vue';
|
||||
import VueSelect from 'vue-select';
|
||||
|
||||
Vue.component('v-select', VueSelect.VueSelect)
|
||||
|
||||
new Vue({
|
||||
el: '#localization',
|
||||
data: {
|
||||
options: ['jim','bob','frank'],
|
||||
selected: 'frank',
|
||||
}
|
||||
})
|
4
resources/js/src/shims-vue.d.ts
vendored
4
resources/js/src/shims-vue.d.ts
vendored
@ -1,4 +0,0 @@
|
||||
declare module '*.vue' {
|
||||
import Vue from 'vue'
|
||||
export default Vue
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
import client_list from './modules/client_list'
|
||||
|
||||
Vue.use(Vuex)
|
||||
|
||||
const debug = process.env.NODE_ENV !== 'production'
|
||||
|
||||
const store = new Vuex.Store({
|
||||
modules: {
|
||||
client_list
|
||||
},
|
||||
strict: debug,
|
||||
})
|
||||
|
||||
export default store
|
@ -1,70 +0,0 @@
|
||||
/**
|
||||
* State managment for the Client List View
|
||||
*/
|
||||
|
||||
const state = {
|
||||
statuses: [{value: 'active'}],
|
||||
filter_text: '',
|
||||
bulk_count : 0
|
||||
}
|
||||
|
||||
// getters
|
||||
const getters = {
|
||||
getBulkCount: state => {
|
||||
|
||||
return state.bulk_count
|
||||
|
||||
},
|
||||
getFilterText: state => {
|
||||
|
||||
return state.filter_text
|
||||
|
||||
},
|
||||
getQueryStringObject: state => {
|
||||
|
||||
var values = state.statuses.map(function (state, index, array) {
|
||||
return state.value;
|
||||
});
|
||||
|
||||
var queryObj = {
|
||||
filter: state.filter_text,
|
||||
status: [].concat.apply([], values).join(",")
|
||||
}
|
||||
|
||||
return queryObj
|
||||
}
|
||||
}
|
||||
|
||||
// actions
|
||||
const actions = {
|
||||
|
||||
}
|
||||
|
||||
// mutations
|
||||
const mutations = {
|
||||
setFilterText(state, text) {
|
||||
|
||||
state.filter_text = text
|
||||
|
||||
},
|
||||
setStatusArray(state, statuses) {
|
||||
|
||||
state.statuses = statuses
|
||||
|
||||
},
|
||||
setBulkCount(state, count) {
|
||||
|
||||
state.bulk_count = count
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
|
||||
namespaced: true,
|
||||
state,
|
||||
getters,
|
||||
actions,
|
||||
mutations
|
||||
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
export function sum(x: number, y: number): number {
|
||||
return x + y;
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
import { sum } from "./math";
|
||||
|
||||
describe("This is a simple test", () => {
|
||||
test("Check the sum of 0 + 0", () => {
|
||||
expect(sum(0,0)).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("This is a simple test", () => {
|
||||
test("Check the sum of 1 + 2", () => {
|
||||
expect(sum(1, 2)).toBe(3);
|
||||
});
|
||||
});
|
@ -1,129 +0,0 @@
|
||||
import CSettings from '../models/client-settings-model';
|
||||
|
||||
export default class ClientSettings {
|
||||
|
||||
client_settings:any
|
||||
|
||||
company_settings:any
|
||||
|
||||
settings:any
|
||||
|
||||
languages:any
|
||||
|
||||
currencies:any
|
||||
|
||||
payment_terms:any
|
||||
|
||||
industries:any
|
||||
|
||||
sizes:any
|
||||
|
||||
|
||||
/**
|
||||
* Create a new Client Settings instance.
|
||||
*/
|
||||
constructor(
|
||||
client_settings: any,
|
||||
company_settings: any,
|
||||
languages: any,
|
||||
currencies: any,
|
||||
payment_terms: any,
|
||||
industries: any,
|
||||
sizes: any
|
||||
) {
|
||||
this.client_settings = client_settings
|
||||
this.company_settings = company_settings
|
||||
this.languages = languages
|
||||
this.currencies = currencies
|
||||
this.payment_terms = payment_terms
|
||||
this.industries = industries
|
||||
this.sizes = sizes
|
||||
}
|
||||
|
||||
/**
|
||||
* Build Settings object
|
||||
*/
|
||||
build() {
|
||||
|
||||
this.settings = new CSettings(this.client_settings)
|
||||
if (this.client_settings.currency_id !== null) {
|
||||
|
||||
this.settings.currency_id = this.currencies.find(obj => {
|
||||
return obj.id == this.client_settings.currency_id
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
if(this.client_settings.show_currency_symbol == null)
|
||||
this.settings.show_currency_symbol = this.company_settings.show_currency_symbol
|
||||
|
||||
if(this.client_settings.show_currency_code == null)
|
||||
this.settings.show_currency_code = this.company_settings.show_currency_code
|
||||
|
||||
if (this.client_settings.language_id !== null) {
|
||||
|
||||
this.settings.language_id = this.languages.find(obj => {
|
||||
return obj.id == this.client_settings.language_id
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
if (this.client_settings.payment_terms !== null) {
|
||||
|
||||
this.settings.payment_terms = this.payment_terms.find(obj => {
|
||||
return obj.id == this.client_settings.payment_terms
|
||||
})
|
||||
}
|
||||
|
||||
this.settings.default_task_rate = this.client_settings.default_task_rate ? this.client_settings.default_task_rate : this.company_settings.default_task_rate
|
||||
|
||||
if(this.client_settings.send_reminders)
|
||||
this.settings.send_reminders = this.client_settings.send_reminders
|
||||
else
|
||||
this.settings.send_reminders = this.company_settings.send_reminders
|
||||
|
||||
if(this.client_settings.show_tasks_in_portal)
|
||||
this.settings.show_tasks_in_portal = this.client_settings.show_tasks_in_portal
|
||||
else
|
||||
this.settings.show_tasks_in_portal = this.company_settings.show_tasks_in_portal
|
||||
|
||||
if(this.client_settings.custom_message_dashboard && this.client_settings.custom_message_dashboard.length >=1)
|
||||
this.settings.custom_message_dashboard = this.client_settings.custom_message_dashboard
|
||||
else
|
||||
this.settings.custom_message_dashboard = this.company_settings.custom_message_dashboard
|
||||
|
||||
if(this.client_settings.custom_message_unpaid_invoice && this.client_settings.custom_message_unpaid_invoice.length >=1)
|
||||
this.settings.custom_message_unpaid_invoice = this.client_settings.custom_message_unpaid_invoice
|
||||
else
|
||||
this.settings.custom_message_unpaid_invoice = this.company_settings.custom_message_unpaid_invoice
|
||||
|
||||
if(this.client_settings.custom_message_paid_invoice && this.client_settings.custom_message_paid_invoice.length >=1)
|
||||
this.settings.custom_message_paid_invoice = this.client_settings.custom_message_paid_invoice
|
||||
else
|
||||
this.settings.custom_message_paid_invoice = this.company_settings.custom_message_paid_invoice
|
||||
|
||||
if(this.client_settings.custom_message_unapproved_quote && this.client_settings.custom_message_unapproved_quote.length >=1)
|
||||
this.settings.custom_message_unapproved_quote = this.client_settings.custom_message_unapproved_quote
|
||||
else
|
||||
this.settings.custom_message_unapproved_quote = this.company_settings.custom_message_unapproved_quote
|
||||
|
||||
if (this.client_settings.industry_id !== null) {
|
||||
|
||||
this.settings.industry_id = this.industries.find(obj => {
|
||||
return obj.id == this.client_settings.industry_id
|
||||
})
|
||||
}
|
||||
|
||||
if (this.client_settings.size_id !== null) {
|
||||
|
||||
this.settings.size_id = this.sizes.find(obj => {
|
||||
return obj.id == this.client_settings.size_id
|
||||
})
|
||||
}
|
||||
|
||||
return this.settings
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
export default class FormErrors {
|
||||
|
||||
errors:any;
|
||||
/**
|
||||
* Create a new Errors instance.
|
||||
*/
|
||||
constructor() {
|
||||
this.errors = {};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine if an errors exists for the given field.
|
||||
*
|
||||
* @param {string} field
|
||||
*/
|
||||
has(field:string) {
|
||||
return this.errors.hasOwnProperty(field);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine if we have any errors.
|
||||
*/
|
||||
any() {
|
||||
return Object.keys(this.errors).length > 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the error message for a field.
|
||||
*
|
||||
* @param {string} field
|
||||
*/
|
||||
get(field:string) {
|
||||
if (this.errors[field]) {
|
||||
return this.errors[field][0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Record the new errors.
|
||||
*
|
||||
* @param {object} errors
|
||||
*/
|
||||
record(errors:any) {
|
||||
this.errors = errors;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clear one or all error fields.
|
||||
*
|
||||
* @param {string|null} field
|
||||
*/
|
||||
clear(field:string) {
|
||||
if (field) {
|
||||
delete this.errors[field];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.errors = {};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//@keydown="errors.clear($event.target.name)"
|
||||
//
|
||||
//
|
||||
//
|
@ -1,175 +0,0 @@
|
||||
import axios from 'axios';
|
||||
import FormErrors from '../utils/form-errors';
|
||||
|
||||
export default class Form {
|
||||
|
||||
errors:any;
|
||||
|
||||
originalData:any;
|
||||
|
||||
/**
|
||||
* Create a new Form instance.
|
||||
*
|
||||
* @param {object} data
|
||||
*/
|
||||
constructor(data) {
|
||||
|
||||
this.originalData = data;
|
||||
|
||||
for (let field in data) {
|
||||
this[field] = data[field];
|
||||
}
|
||||
|
||||
this.errors = new FormErrors();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all relevant data for the form.
|
||||
*/
|
||||
data() {
|
||||
|
||||
let data = {};
|
||||
|
||||
for (let property in this.originalData) {
|
||||
data[property] = this[property];
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the form fields.
|
||||
*/
|
||||
reset() {
|
||||
|
||||
for (let field in this.originalData) {
|
||||
this[field] = '';
|
||||
}
|
||||
|
||||
this.errors.clear();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a POST request to the given URL.
|
||||
* .
|
||||
* @param {string} url
|
||||
*/
|
||||
post(url) {
|
||||
|
||||
return this.submit('post', url);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a PUT request to the given URL.
|
||||
* .
|
||||
* @param {string} url
|
||||
*/
|
||||
put(url:string) {
|
||||
|
||||
return this.submit('put', url);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a PATCH request to the given URL.
|
||||
* .
|
||||
* @param {string} url
|
||||
*/
|
||||
patch(url:string) {
|
||||
|
||||
return this.submit('patch', url);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a DELETE request to the given URL.
|
||||
* .
|
||||
* @param {string} url
|
||||
*/
|
||||
delete(url:string) {
|
||||
|
||||
return this.submit('delete', url);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit the form.
|
||||
*
|
||||
* @param {string} requestType
|
||||
* @param {string} url
|
||||
*/
|
||||
submit(requestType:string, url:string) {
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
axios[requestType](url, this.data())
|
||||
.then(response => {
|
||||
|
||||
this.onSuccess(response.data);
|
||||
|
||||
resolve(response.data);
|
||||
|
||||
})
|
||||
.catch(error => {
|
||||
|
||||
|
||||
if (error.response.status === 422) {
|
||||
|
||||
this.onFail(error.response.data.errors);
|
||||
|
||||
}
|
||||
else if(error.response.status === 419) {
|
||||
|
||||
//csrf token has expired, we'll need to force a page reload
|
||||
|
||||
}
|
||||
|
||||
reject(error.response.data);
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Update form data on success
|
||||
*
|
||||
* @param {object} data
|
||||
*/
|
||||
update(data)
|
||||
{
|
||||
this.originalData = data;
|
||||
|
||||
for (let field in data) {
|
||||
this[field] = data[field];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a successful form submission.
|
||||
*
|
||||
* @param {object} data
|
||||
*/
|
||||
onSuccess(data) {
|
||||
this.update(data);
|
||||
this.errors.clear();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a failed form submission.
|
||||
*
|
||||
* @param {object} errors
|
||||
*/
|
||||
onFail(errors) {
|
||||
|
||||
this.errors.record(errors);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
export default class NumberFormat {
|
||||
|
||||
amount:any
|
||||
|
||||
currency:any
|
||||
|
||||
symbol_decorator:boolean
|
||||
|
||||
language:any
|
||||
|
||||
/**
|
||||
* Create a new Number Format instance.
|
||||
*/
|
||||
constructor(amount: any, currency: any, symbol_decorator: boolean, language: any) {
|
||||
this.amount = amount
|
||||
this.currency = currency
|
||||
this.symbol_decorator = symbol_decorator
|
||||
this.language = language
|
||||
}
|
||||
|
||||
format() {
|
||||
this.amount = new Intl.NumberFormat(this.language.locale.replace("_", "-"), {style: 'decimal',currency: this.currency.code} ).format(this.amount)
|
||||
|
||||
if(this.symbol_decorator)
|
||||
this.amount = this.currency.symbol + this.amount
|
||||
else
|
||||
this.amount = this.amount + " " + this.currency.code
|
||||
|
||||
|
||||
return this.amount
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -95,24 +95,26 @@ class MigrationTest extends TestCase
|
||||
|
||||
}
|
||||
|
||||
public function testMigrationFileUpload()
|
||||
{
|
||||
$file = new UploadedFile(base_path('tests/Unit/Migration/migration.zip'), 'migration.zip');
|
||||
// public function testMigrationFileUpload()
|
||||
// {
|
||||
// $file = new UploadedFile(base_path('tests/Unit/Migration/migration.zip'), 'migration.zip');
|
||||
|
||||
$data = [
|
||||
'migration' => $file,
|
||||
'force' => true,
|
||||
];
|
||||
// $data = [
|
||||
// 'migration' => $file,
|
||||
// 'force' => true,
|
||||
// ];
|
||||
|
||||
$token = $this->company->tokens->first()->token;
|
||||
// $token = $this->company->tokens->first()->token;
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-TOKEN' => $token,
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-Requested-With' => 'XMLHttpRequest',
|
||||
'X-API-PASSWORD' => 'ALongAndBriliantPassword',
|
||||
])->post('/api/v1/migration/start', $data);
|
||||
// $response = $this->withHeaders([
|
||||
// 'X-API-TOKEN' => $token,
|
||||
// 'X-API-SECRET' => config('ninja.api_secret'),
|
||||
// 'X-Requested-With' => 'XMLHttpRequest',
|
||||
// 'X-API-PASSWORD' => 'ALongAndBriliantPassword',
|
||||
// ])->post('/api/v1/migration/start', $data);
|
||||
|
||||
// $response->assertStatus(200);
|
||||
// $this->assertTrue(file_exists(base_path('storage/migrations/migration/migration.json')));
|
||||
// }
|
||||
|
||||
$response->assertStatus(200);
|
||||
}
|
||||
}
|
||||
|
@ -35,10 +35,17 @@ class DesignTest extends TestCase
|
||||
|
||||
$this->assertNotNull($html);
|
||||
|
||||
//\Log::error($html);
|
||||
|
||||
$this->invoice = factory(\App\Models\Invoice::class)->create([
|
||||
'user_id' => $this->user->id,
|
||||
'client_id' => $this->client->id,
|
||||
'company_id' => $this->company->id,
|
||||
]);
|
||||
|
||||
$this->invoice->uses_inclusive_taxes = false;
|
||||
|
||||
$settings = $this->invoice->client->settings;
|
||||
$settings->invoice_design_id = "5";
|
||||
$settings->invoice_design_id = "6";
|
||||
|
||||
$this->client->settings = $settings;
|
||||
$this->client->save();
|
||||
@ -60,7 +67,7 @@ class DesignTest extends TestCase
|
||||
//\Log::error($html);
|
||||
|
||||
$settings = $this->invoice->client->settings;
|
||||
$settings->quote_design_id = "10";
|
||||
$settings->quote_design_id = "6";
|
||||
|
||||
$this->client->settings = $settings;
|
||||
$this->client->save();
|
||||
|
@ -91,8 +91,6 @@ trait MockAccountData
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
$this->account = factory(\App\Models\Account::class)->create();
|
||||
$this->company = factory(\App\Models\Company::class)->create([
|
||||
'account_id' => $this->account->id,
|
||||
@ -189,9 +187,16 @@ trait MockAccountData
|
||||
$this->client->group_settings_id = $gs->id;
|
||||
$this->client->save();
|
||||
|
||||
$this->invoice = InvoiceFactory::create($this->company->id,$this->user->id);//stub the company and user_id
|
||||
$this->invoice = InvoiceFactory::create($this->company->id, $this->user->id);//stub the company and user_id
|
||||
$this->invoice->client_id = $this->client->id;
|
||||
|
||||
// $this->invoice = factory(\App\Models\Invoice::class)->create([
|
||||
// 'user_id' => $this->user->id,
|
||||
// 'client_id' => $this->client->id,
|
||||
// 'company_id' => $this->company->id,
|
||||
// ]);
|
||||
|
||||
|
||||
$this->invoice->line_items = $this->buildLineItems();
|
||||
$this->invoice->uses_inclusive_taxes = false;
|
||||
|
||||
|
@ -103,13 +103,10 @@ class ImportTest extends TestCase
|
||||
$this->makeTestData();
|
||||
|
||||
$this->invoice->forceDelete();
|
||||
$this->quote->forceDelete();
|
||||
|
||||
$original_count = Invoice::count();
|
||||
|
||||
|
||||
|
||||
//$this->migration_array = json_decode(file_get_contents($migration_file), 1);
|
||||
|
||||
Import::dispatchNow($this->migration_array, $this->company, $this->user);
|
||||
|
||||
$this->assertGreaterThan($original_count, Invoice::count());
|
||||
@ -149,7 +146,7 @@ class ImportTest extends TestCase
|
||||
//$this->makeTestData();
|
||||
|
||||
$this->invoice->forceDelete();
|
||||
|
||||
$this->quote->forceDelete();
|
||||
// $migration_file = base_path() . '/tests/Unit/Migration/migration.json';
|
||||
|
||||
// $this->migration_array = json_decode(file_get_contents($migration_file), 1);
|
||||
@ -190,7 +187,7 @@ class ImportTest extends TestCase
|
||||
$original_number = Invoice::count();
|
||||
|
||||
$this->invoice->forceDelete();
|
||||
|
||||
$this->quote->forceDelete();
|
||||
// $migration_file = base_path() . '/tests/Unit/Migration/migration.json';
|
||||
|
||||
// $this->migration_array = json_decode(file_get_contents($migration_file), 1);
|
||||
@ -264,7 +261,7 @@ class ImportTest extends TestCase
|
||||
$original_count = Payment::count();
|
||||
|
||||
$this->invoice->forceDelete();
|
||||
|
||||
$this->quote->forceDelete();
|
||||
// $migration_file = base_path() . '/tests/Unit/Migration/migration.json';
|
||||
|
||||
// $this->migration_array = json_decode(file_get_contents($migration_file), 1);
|
||||
@ -295,6 +292,7 @@ class ImportTest extends TestCase
|
||||
$original_count = Credit::count();
|
||||
|
||||
$this->invoice->forceDelete();
|
||||
$this->quote->forceDelete();
|
||||
|
||||
// $migration_file = base_path() . '/tests/Unit/Migration/migration.json';
|
||||
|
||||
@ -329,6 +327,7 @@ class ImportTest extends TestCase
|
||||
public function testValidityOfImportedData()
|
||||
{
|
||||
$this->invoice->forceDelete();
|
||||
$this->quote->forceDelete();
|
||||
|
||||
// $migration_file = base_path() . '/tests/Unit/Migration/migration.json';
|
||||
|
||||
@ -424,7 +423,7 @@ class ImportTest extends TestCase
|
||||
}*/
|
||||
|
||||
foreach ($this->migration_array['documents'] as $key => $document) {
|
||||
$record = Document::whereHash('5a81aa656c8aaf77dca259b7defdda1dc5ae7901')
|
||||
$record = Document::whereHash($document['hash'])
|
||||
->first();
|
||||
|
||||
if (!$record) {
|
||||
@ -432,12 +431,14 @@ class ImportTest extends TestCase
|
||||
}
|
||||
}
|
||||
|
||||
\Log::error($differences);
|
||||
$this->assertCount(0, $differences);
|
||||
}
|
||||
|
||||
public function testClientContactsImport()
|
||||
{
|
||||
$this->invoice->forceDelete();
|
||||
$this->quote->forceDelete();
|
||||
|
||||
$original = ClientContact::count();
|
||||
|
||||
@ -453,6 +454,7 @@ class ImportTest extends TestCase
|
||||
public function testDocumentsImport()
|
||||
{
|
||||
$this->invoice->forceDelete();
|
||||
$this->quote->forceDelete();
|
||||
|
||||
$original = Document::count();
|
||||
|
||||
@ -461,6 +463,8 @@ class ImportTest extends TestCase
|
||||
$this->assertGreaterThan($original, Document::count());
|
||||
|
||||
$document = Document::first();
|
||||
|
||||
\Log::error($document);
|
||||
|
||||
$this->assertNotNull(Invoice::find($document->documentable_id)->documents);
|
||||
$this->assertNotNull($document->documentable);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,62 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
/* Basic Options */
|
||||
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
|
||||
"module": "commonjs", /* Specify module code generation: 'none', -> 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
|
||||
// "lib": [], /* Specify library files to be included in the compilation. */
|
||||
// "allowJs": true, /* Allow javascript files to be compiled. */
|
||||
// "checkJs": true, /* Report errors in .js files. */
|
||||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
|
||||
// "declaration": true, /* Generates corresponding '.d.ts' file. */
|
||||
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
|
||||
"sourceMap": false, /* Generates corresponding '.map' file. */
|
||||
// "outFile": "./", /* Concatenate and emit output to single file. */
|
||||
// "outDir": "./", /* Redirect output structure to the directory. */
|
||||
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
|
||||
// "composite": true, /* Enable project compilation */
|
||||
// "removeComments": true, /* Do not emit comments to output. */
|
||||
// "noEmit": true, /* Do not emit outputs. */
|
||||
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
|
||||
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
||||
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
|
||||
|
||||
/* Strict Type-Checking Options */
|
||||
"strict": false, /* Enable all strict type-checking options. */
|
||||
"noImplicitAny": false, /* Raise error on expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* Enable strict null checks. */
|
||||
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
|
||||
/* Additional Checks */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
|
||||
|
||||
/* Module Resolution Options */
|
||||
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
|
||||
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
|
||||
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
|
||||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
||||
// "typeRoots": [], /* List of folders to include type definitions from. */
|
||||
// "types": [], /* Type declaration files to be included in compilation. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
||||
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
|
||||
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
|
||||
|
||||
/* Source Map Options */
|
||||
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
|
||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
|
||||
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
|
||||
|
||||
/* Experimental Options */
|
||||
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
|
||||
},
|
||||
"include": [
|
||||
"resources/js/**/*"
|
||||
]
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user