Merge branch 'master' of https://gitlab.com/mohit.panjvani/crater-web into fix-view-status-action

This commit is contained in:
satyaprakash10
2019-11-14 19:57:14 +05:30
51 changed files with 447 additions and 181127 deletions

View File

@ -35,9 +35,7 @@ class EnvironmentController extends Controller
{ {
$results = $this->EnvironmentManager->saveDatabaseVariables($request); $results = $this->EnvironmentManager->saveDatabaseVariables($request);
if(array_key_exists("success", $results)) { if(array_key_exists("success", $results)) {
Artisan::call('config:clear'); Artisan::call('config:clear');
Artisan::call('migrate --seed'); Artisan::call('migrate --seed');
Artisan::call('migrate', ['--path' => 'vendor/laravel/passport/database/migrations']); Artisan::call('migrate', ['--path' => 'vendor/laravel/passport/database/migrations']);
@ -57,13 +55,30 @@ class EnvironmentController extends Controller
*/ */
public function saveMailEnvironment(MailEnvironmentRequest $request) public function saveMailEnvironment(MailEnvironmentRequest $request)
{ {
$setting = Setting::getSetting('profile_complete');
$results = $this->EnvironmentManager->saveMailVariables($request); $results = $this->EnvironmentManager->saveMailVariables($request);
Setting::setSetting('profile_complete', 4); if ($setting !== 'COMPLETED')
{
Setting::setSetting('profile_complete', 4);
}
return response()->json($results); return response()->json($results);
} }
public function getMailEnvironment()
{
$MailData = [
'mail_driver' => config('mail.driver'),
'mail_host' => config('mail.host'),
'mail_port' => config('mail.port'),
'mail_username' => config('mail.username'),
'mail_password' => config('mail.password'),
'mail_encryption' => config('mail.encryption')
];
return response()->json($MailData);
}
/** /**
* *

View File

@ -203,7 +203,7 @@ class OnboardingController extends Controller
); );
} }
Setting::setSetting('version','1.0.0'); Setting::setSetting('version', config('crater.version'));
Artisan::call('passport:install --force'); Artisan::call('passport:install --force');

View File

@ -49,12 +49,20 @@ class EnvironmentManager
'DB_PASSWORD='.$request->database_password."\n\n"; 'DB_PASSWORD='.$request->database_password."\n\n";
if (! $this->checkDatabaseConnection($request)) { if (! $this->checkDatabaseConnection($request)) {
return [ return [
'error' => 'connection_failed' 'error' => 'connection_failed'
]; ];
} else {
if(count(DB::connection()->select('SHOW TABLES'))) {
return [
'error' => 'database_should_be_empty'
];
}
} }
try { try {
file_put_contents($this->envPath, str_replace( file_put_contents($this->envPath, str_replace(
$oldDatabaseData, $oldDatabaseData,
$newDatabaseData, $newDatabaseData,
@ -101,7 +109,7 @@ class EnvironmentManager
'MAIL_USERNAME='.$request->mail_username."\n". 'MAIL_USERNAME='.$request->mail_username."\n".
'MAIL_PASSWORD='.$request->mail_password."\n". 'MAIL_PASSWORD='.$request->mail_password."\n".
'MAIL_ENCRYPTION='.$request->mail_encryption."\n\n"; 'MAIL_ENCRYPTION='.$request->mail_encryption."\n\n";
// dd($newMailData);
try { try {
file_put_contents($this->envPath, str_replace( file_put_contents($this->envPath, str_replace(

14
config/crater.php Normal file
View File

@ -0,0 +1,14 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Crater Requirements
|--------------------------------------------------------------------------
|
*/
'version' => '1.0.0',
];

View File

@ -4636,57 +4636,6 @@ input[type=button].btn-block {
display: none; display: none;
} }
.navbar-light .navbar-brand {
color: rgba(0, 0, 0, 0.9);
}
.navbar-light .navbar-brand:hover,
.navbar-light .navbar-brand:focus {
color: rgba(0, 0, 0, 0.9);
}
.navbar-light .navbar-nav .nav-link {
color: rgba(0, 0, 0, 0.5);
}
.navbar-light .navbar-nav .nav-link:hover,
.navbar-light .navbar-nav .nav-link:focus {
color: rgba(0, 0, 0, 0.7);
}
.navbar-light .navbar-nav .nav-link.disabled {
color: rgba(0, 0, 0, 0.3);
}
.navbar-light .navbar-nav .show > .nav-link,
.navbar-light .navbar-nav .active > .nav-link,
.navbar-light .navbar-nav .nav-link.show,
.navbar-light .navbar-nav .nav-link.active {
color: rgba(0, 0, 0, 0.9);
}
.navbar-light .navbar-toggler {
color: rgba(0, 0, 0, 0.5);
border-color: rgba(0, 0, 0, 0.1);
}
.navbar-light .navbar-toggler-icon {
background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
}
.navbar-light .navbar-text {
color: rgba(0, 0, 0, 0.5);
}
.navbar-light .navbar-text a {
color: rgba(0, 0, 0, 0.9);
}
.navbar-light .navbar-text a:hover,
.navbar-light .navbar-text a:focus {
color: rgba(0, 0, 0, 0.9);
}
.navbar-dark .navbar-brand { .navbar-dark .navbar-brand {
color: #fff; color: #fff;
} }
@ -11504,10 +11453,6 @@ code,
align-items: center; align-items: center;
} }
.swal-icon--custom {
height: 70px !important;
}
.site-header { .site-header {
background-color: #5851D8; background-color: #5851D8;
height: 60px; height: 60px;
@ -15112,10 +15057,6 @@ fieldset[disabled] .multiselect {
color: #FB7178; color: #FB7178;
} }
.dashboard .dashboard-table .table-component .dashboard-recent-invoice-options .dropdown-container {
margin: 10px 5px 0 -75px;
}
.dashbox { .dashbox {
background-color: #fff; background-color: #fff;
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
@ -18325,6 +18266,8 @@ fieldset[disabled] .multiselect {
.customer-create .same-address-checkbox-container { .customer-create .same-address-checkbox-container {
display: flex; display: flex;
justify-content: flex-end;
padding-left: 12px;
margin-bottom: 1.5rem; margin-bottom: 1.5rem;
align-items: center; align-items: center;
justify-content: flex-end; justify-content: flex-end;
@ -18375,6 +18318,7 @@ fieldset[disabled] .multiselect {
.customer-create .same-address-checkbox-container { .customer-create .same-address-checkbox-container {
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
padding-left: 15px;
margin-bottom: 0rem; margin-bottom: 0rem;
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,9 +1,29 @@
<template> <template>
<button :type="type" :class="btnClass" :disabled="disabled" @click="handleClick"> <button
<font-awesome-icon v-if="icon && !loading && !rightIcon" :class="iconClass" :icon="icon" class="vue-icon icon-left" /> :type="type"
<font-awesome-icon v-if="loading" :class="iconClass" icon="spinner" class="fa-spin"/> :class="btnClass"
:disabled="disabled || loading"
@click="handleClick"
>
<font-awesome-icon
v-if="icon && !loading && !rightIcon"
:class="iconClass"
:icon="icon"
class="vue-icon icon-left"
/>
<font-awesome-icon
v-if="loading"
:class="iconClass"
icon="spinner"
class="fa-spin"
/>
<slot /> <slot />
<font-awesome-icon v-if="icon && !loading && rightIcon" :class="iconClass" :icon="icon" class="vue-icon icon-right" /> <font-awesome-icon
v-if="icon && !loading && rightIcon"
:class="iconClass"
:icon="icon"
class="vue-icon icon-right"
/>
</button> </button>
</template> </template>

View File

@ -4,7 +4,7 @@
<input <input
ref="baseInput" ref="baseInput"
v-model="inputValue" v-model="inputValue"
:type="type" :type="toggleType"
:disabled="disabled" :disabled="disabled"
:readonly="readOnly" :readonly="readOnly"
:name="name" :name="name"
@ -19,6 +19,9 @@
@keydown="handleKeyDownEnter" @keydown="handleKeyDownEnter"
@blur="handleFocusOut" @blur="handleFocusOut"
> >
<div v-if="showPassword && isAlignLeftIcon" style="cursor: pointer" @click="showPass = !showPass" >
<font-awesome-icon :icon="!showPass ?'eye-slash': 'eye'" class="right-icon" />
</div>
<font-awesome-icon v-if="icon && !isAlignLeftIcon" :icon="icon" class="right-icon" /> <font-awesome-icon v-if="icon && !isAlignLeftIcon" :icon="icon" class="right-icon" />
</div> </div>
</template> </template>
@ -77,12 +80,17 @@ export default {
autocomplete: { autocomplete: {
type: String, type: String,
default: 'on' default: 'on'
},
showPassword: {
type: Boolean,
default: false
} }
}, },
data () { data () {
return { return {
inputValue: this.value, inputValue: this.value,
focus: false focus: false,
showPass: false
} }
}, },
computed: { computed: {
@ -94,6 +102,12 @@ export default {
return true return true
} }
return false return false
},
toggleType () {
if (this.showPass) {
return 'text'
}
return this.type
} }
}, },
watch: { watch: {

View File

@ -3,7 +3,7 @@
<form action="" @submit.prevent="submitCategoryData"> <form action="" @submit.prevent="submitCategoryData">
<div class="card-body"> <div class="card-body">
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{{ $t('expenses.category') }}<span class="required text-danger">*</span></label> <label class="col-sm-4 col-form-label input-label">{{ $t('expenses.category') }}<span class="required text-danger">*</span></label>
<div class="col-sm-7"> <div class="col-sm-7">
<base-input <base-input
ref="name" ref="name"

View File

@ -7,7 +7,7 @@
<tab id="basic-home" :name="$t('customers.basic_info')"> <tab id="basic-home" :name="$t('customers.basic_info')">
<div class="basic-info"> <div class="basic-info">
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{{ $t('customers.display_name') }} <span class="required">*</span></label> <label class="col-sm-4 col-form-label input-label">{{ $t('customers.display_name') }} <span class="required">*</span></label>
<div class="col-sm-7"> <div class="col-sm-7">
<base-input <base-input
ref="name" ref="name"
@ -25,7 +25,7 @@
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{{ $t('customers.primary_display_name') }}</label> <label class="col-sm-4 col-form-label input-label">{{ $t('customers.primary_display_name') }}</label>
<div class="col-sm-7"> <div class="col-sm-7">
<base-input <base-input
v-model="formData.contact_name" v-model="formData.contact_name"
@ -34,7 +34,7 @@
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{{ $t('login.email') }}</label> <label class="col-sm-4 col-form-label input-label">{{ $t('login.email') }}</label>
<div class="col-sm-7"> <div class="col-sm-7">
<base-input <base-input
:invalid="$v.formData.email.$error" :invalid="$v.formData.email.$error"
@ -49,7 +49,7 @@
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{{ $tc('settings.currencies.currency') }}</label> <label class="col-sm-4 col-form-label input-label">{{ $tc('settings.currencies.currency') }}</label>
<div class="col-sm-7"> <div class="col-sm-7">
<base-select <base-select
v-model="currency" v-model="currency"
@ -64,7 +64,7 @@
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{{ $t('customers.phone') }}</label> <label class="col-sm-4 col-form-label input-label">{{ $t('customers.phone') }}</label>
<div class="col-sm-7"> <div class="col-sm-7">
<base-input <base-input
:invalid="$v.formData.phone.$error" :invalid="$v.formData.phone.$error"
@ -79,7 +79,7 @@
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{{ $t('customers.website') }}</label> <label class="col-sm-4 col-form-label input-label">{{ $t('customers.website') }}</label>
<div class="col-sm-7"> <div class="col-sm-7">
<base-input <base-input
v-model="formData.website" v-model="formData.website"
@ -100,7 +100,7 @@
<tab id="basic-profile" :name="$t('customers.billing_address')"> <tab id="basic-profile" :name="$t('customers.billing_address')">
<div class="basic-info"> <div class="basic-info">
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{{ $t('customers.name') }}</label> <label class="col-sm-4 col-form-label input-label">{{ $t('customers.name') }}</label>
<div class="col-sm-7"> <div class="col-sm-7">
<base-input <base-input
v-model="billing.name" v-model="billing.name"
@ -110,7 +110,7 @@
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{{ $t('customers.phone') }}</label> <label class="col-sm-4 col-form-label input-label">{{ $t('customers.phone') }}</label>
<div class="col-sm-7"> <div class="col-sm-7">
<base-input <base-input
:invalid="$v.billing.phone.$error" :invalid="$v.billing.phone.$error"
@ -126,7 +126,7 @@
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{{ $t('customers.address') }}</label> <label class="col-sm-4 col-form-label input-label">{{ $t('customers.address') }}</label>
<div class="col-sm-7"> <div class="col-sm-7">
<base-text-area <base-text-area
v-model="billing.address_street_1" v-model="billing.address_street_1"
@ -155,7 +155,7 @@
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{{ $t('customers.country') }}</label> <label class="col-sm-4 col-form-label input-label">{{ $t('customers.country') }}</label>
<div class="col-sm-7"> <div class="col-sm-7">
<base-select <base-select
v-model="billingCountry" v-model="billingCountry"
@ -171,7 +171,7 @@
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{{ $t('customers.state') }}</label> <label class="col-sm-4 col-form-label input-label">{{ $t('customers.state') }}</label>
<div class="col-sm-7"> <div class="col-sm-7">
<base-select <base-select
v-model="billingState" v-model="billingState"
@ -187,7 +187,7 @@
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{{ $t('customers.city') }}</label> <label class="col-sm-4 col-form-label input-label">{{ $t('customers.city') }}</label>
<div class="col-sm-7"> <div class="col-sm-7">
<base-select <base-select
v-model="billingCity" v-model="billingCity"
@ -213,7 +213,7 @@
</div> --> </div> -->
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{{ $t('customers.zip_code') }}</label> <label class="col-sm-4 col-form-label input-label">{{ $t('customers.zip_code') }}</label>
<div class="col-sm-7"> <div class="col-sm-7">
<base-input <base-input
v-model="billing.zip" v-model="billing.zip"
@ -236,7 +236,7 @@
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{{ $t('customers.name') }}</label> <label class="col-sm-4 col-form-label input-label">{{ $t('customers.name') }}</label>
<div class="col-sm-7"> <div class="col-sm-7">
<base-input <base-input
v-model="shipping.name" v-model="shipping.name"
@ -246,7 +246,7 @@
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{{ $t('customers.phone') }}</label> <label class="col-sm-4 col-form-label input-label">{{ $t('customers.phone') }}</label>
<div class="col-sm-7"> <div class="col-sm-7">
<base-input <base-input
:invalid="$v.shipping.phone.$error" :invalid="$v.shipping.phone.$error"
@ -262,7 +262,7 @@
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{{ $t('customers.address') }}</label> <label class="col-sm-4 col-form-label input-label">{{ $t('customers.address') }}</label>
<div class="col-sm-7"> <div class="col-sm-7">
<base-text-area <base-text-area
v-model="shipping.address_street_1" v-model="shipping.address_street_1"
@ -291,7 +291,7 @@
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{{ $t('customers.country') }}</label> <label class="col-sm-4 col-form-label input-label">{{ $t('customers.country') }}</label>
<div class="col-sm-7"> <div class="col-sm-7">
<base-select <base-select
v-model="shippingCountry" v-model="shippingCountry"
@ -307,7 +307,7 @@
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{{ $t('customers.state') }}</label> <label class="col-sm-4 col-form-label input-label">{{ $t('customers.state') }}</label>
<div class="col-sm-7"> <div class="col-sm-7">
<base-select <base-select
v-model="shippingState" v-model="shippingState"
@ -323,7 +323,7 @@
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{{ $t('customers.city') }}</label> <label class="col-sm-4 col-form-label input-label">{{ $t('customers.city') }}</label>
<div class="col-sm-7"> <div class="col-sm-7">
<base-select <base-select
v-model="shippingCity" v-model="shippingCity"
@ -339,7 +339,7 @@
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{{ $t('customers.zip_code') }}</label> <label class="col-sm-4 col-form-label input-label">{{ $t('customers.zip_code') }}</label>
<div class="col-sm-7"> <div class="col-sm-7">
<base-input <base-input
v-model="shipping.zip" v-model="shipping.zip"

View File

@ -3,7 +3,7 @@
<form action="" @submit.prevent="submitItemData"> <form action="" @submit.prevent="submitItemData">
<div class="card-body"> <div class="card-body">
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label"> <label class="col-sm-4 col-form-label input-label">
{{ $t('items.name') }}<span class="required">*</span> {{ $t('items.name') }}<span class="required">*</span>
</label> </label>
<div class="col-sm-7"> <div class="col-sm-7">
@ -22,7 +22,7 @@
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{{ $t('items.price') }}<span class="required">*</span></label> <label class="col-sm-4 col-form-label input-label">{{ $t('items.price') }}<span class="required">*</span></label>
<div class="col-sm-7"> <div class="col-sm-7">
<div class="base-input"> <div class="base-input">
<money <money
@ -41,7 +41,7 @@
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{{ $t('items.unit') }}</label> <label class="col-sm-4 col-form-label input-label">{{ $t('items.unit') }}</label>
<div class="col-sm-7"> <div class="col-sm-7">
<base-select <base-select
v-model="formData.unit" v-model="formData.unit"
@ -54,7 +54,7 @@
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{{ $t('items.description') }}</label> <label class="col-sm-4 col-form-label input-label">{{ $t('items.description') }}</label>
<div class="col-sm-7"> <div class="col-sm-7">
<base-text-area <base-text-area
v-model="formData.description" v-model="formData.description"
@ -121,7 +121,8 @@ export default {
{ name: 'kg', value: 'kg' }, { name: 'kg', value: 'kg' },
{ name: 'km', value: 'km' }, { name: 'km', value: 'km' },
{ name: 'lb', value: 'lb' }, { name: 'lb', value: 'lb' },
{ name: 'mg', value: 'mg' } { name: 'mg', value: 'mg' },
{ name: 'pc', value: 'pc' }
], ],
formData: { formData: {
name: null, name: null,

View File

@ -529,7 +529,8 @@ export default {
preferences: 'Preferences', preferences: 'Preferences',
notifications: 'Notifications', notifications: 'Notifications',
tax_types: 'Tax Types', tax_types: 'Tax Types',
expense_category: 'Expense Categories' expense_category: 'Expense Categories',
update_app: 'Update App'
}, },
title: 'Settings', title: 'Settings',
setting: 'Settings | Settings', setting: 'Settings | Settings',
@ -611,8 +612,6 @@ export default {
estimate_viewed_desc: 'When your customer views the estimate sent via crater dashboard.', estimate_viewed_desc: 'When your customer views the estimate sent via crater dashboard.',
save: 'Save', save: 'Save',
email_save_message: 'Email saved successfully', email_save_message: 'Email saved successfully',
// invoice_viewed_message: 'Invoice viewed updated successfully',
// estimate_viewed_message: 'Estimate viewed updated successfully',
please_enter_email: 'Please Enter Email' please_enter_email: 'Please Enter Email'
}, },
tax_types: { tax_types: {
@ -622,7 +621,6 @@ export default {
add_new_tax: 'Add New Tax', add_new_tax: 'Add New Tax',
tax_settings: 'Tax Settings', tax_settings: 'Tax Settings',
tax_per_item: 'Tax Per Item', tax_per_item: 'Tax Per Item',
// tax_per_item_switch: 'Tax Per Item updated successfully',
tax_name: 'Tax Name', tax_name: 'Tax Name',
compound_tax: 'Compound Tax', compound_tax: 'Compound Tax',
percent: 'Percent', percent: 'Percent',
@ -660,11 +658,15 @@ export default {
preference: 'Preference | Preferences', preference: 'Preference | Preferences',
general_settings: 'Default preferences for the system.', general_settings: 'Default preferences for the system.',
updated_message: 'Preferences updated successfully', updated_message: 'Preferences updated successfully',
// set_discount_per_item_message: 'Discount set per item updated successfully',
select_language: 'select language', select_language: 'select language',
select_time_zone: 'select Time Zone', select_time_zone: 'select Time Zone',
select_date_formate: 'select Date Formate', select_date_formate: 'select Date Formate',
select_financial_year: 'select financial year' select_financial_year: 'select financial year'
},
update_app: {
title: 'Update App',
description: 'update app description',
update: 'Update'
} }
}, },
wizard: { wizard: {
@ -735,7 +737,8 @@ export default {
migrate_failed: 'Migrate Failed', migrate_failed: 'Migrate Failed',
database_variables_save_error: 'Unable to connect to the DB with Provided Values.', database_variables_save_error: 'Unable to connect to the DB with Provided Values.',
mail_variables_save_error: 'Email configuration failed.', mail_variables_save_error: 'Email configuration failed.',
connection_failed: 'Database Connection Failed' connection_failed: 'Database connection failed',
database_should_be_empty: 'Database should be empty'
}, },
success: { success: {
mail_variables_save_successfully: 'Email configured successfully', mail_variables_save_successfully: 'Email configured successfully',

View File

@ -529,7 +529,8 @@ export default {
preferences: 'Preferencias', preferences: 'Preferencias',
notifications: 'Notificaciones', notifications: 'Notificaciones',
tax_types: 'Tipos de impuestos', tax_types: 'Tipos de impuestos',
expense_category: 'Categorías de gastos' expense_category: 'Categorías de gastos',
update_app: 'Actualizar aplicación'
}, },
title: 'Configuraciones', title: 'Configuraciones',
setting: 'Configuraciones | Configuraciones', setting: 'Configuraciones | Configuraciones',
@ -556,6 +557,16 @@ export default {
action: 'Acción', action: 'Acción',
add_currency: 'Agregar moneda' add_currency: 'Agregar moneda'
}, },
mail: {
host: 'Host de correo',
port: 'Puerto de correo',
driver: 'Conductor de correo',
password: 'Contraseña de correo',
username: 'Nombre de usuario de correo',
mail_config: 'Configuración de correo',
encryption: 'Cifrado de correo',
mail_config_desc: 'Los detalles a continuación se utilizarán para actualizar el entorno de correo. También puede cambiar los detalles en cualquier momento después de iniciar sesión.'
},
pdf: { pdf: {
title: 'Configuración de PDF', title: 'Configuración de PDF',
footer_text: 'Texto de pie de página', footer_text: 'Texto de pie de página',
@ -651,6 +662,11 @@ export default {
select_time_zone: 'selecciona la zona horaria', select_time_zone: 'selecciona la zona horaria',
select_date_formate: 'seleccione formato de fecha', select_date_formate: 'seleccione formato de fecha',
select_financial_year: 'seleccione año financiero' select_financial_year: 'seleccione año financiero'
},
update_app: {
title: 'Actualizar aplicación',
description: 'actualizar la descripción de la aplicación',
update: 'Actualizar'
} }
}, },
wizard: { wizard: {
@ -749,7 +765,7 @@ export default {
numbers_only: 'Solo numeros.', numbers_only: 'Solo numeros.',
characters_only: 'Solo personajes.', characters_only: 'Solo personajes.',
password_incorrect: 'Las contraseñas deben ser idénticas', password_incorrect: 'Las contraseñas deben ser idénticas',
password_length: 'La contraseña debe tener 6 caracteres de longitud.', password_length: 'La contraseña debe tener 5 caracteres de longitud.',
qty_must_greater_than_zero: 'La cantidad debe ser mayor que cero.', qty_must_greater_than_zero: 'La cantidad debe ser mayor que cero.',
price_greater_than_zero: 'El precio debe ser mayor que cero.', price_greater_than_zero: 'El precio debe ser mayor que cero.',
payment_greater_than_zero: 'El pago debe ser mayor que cero.', payment_greater_than_zero: 'El pago debe ser mayor que cero.',

View File

@ -529,7 +529,8 @@ export default {
preferences: 'Préférences', preferences: 'Préférences',
notifications: 'Les notifications', notifications: 'Les notifications',
tax_types: 'Types de taxe', tax_types: 'Types de taxe',
expense_category: 'Catégories de dépenses' expense_category: 'Catégories de dépenses',
update_app: "Mise à jour de l'application"
}, },
title: 'Paramètres', title: 'Paramètres',
setting: 'Paramètres | Paramètres', setting: 'Paramètres | Paramètres',
@ -554,7 +555,17 @@ export default {
right: 'Droite', right: 'Droite',
left: 'La gauche', left: 'La gauche',
action: 'action', action: 'action',
add_currency: 'Ajouter une devise', add_currency: 'Ajouter une devise'
},
mail: {
host: 'Mail Host',
port: 'Port mail',
driver: 'Pilote de courrier',
password: 'Mot de passe mail',
username: "Mail Nom d'utilisateur",
mail_config: 'Configuration du courrier',
encryption: 'Chiffrement du courrier',
mail_config_desc: "Les détails ci-dessous seront utilisés pour mettre à jour l'environnement de messagerie. Aussi, vous pouvez modifier les détails à tout moment après la connexion."
}, },
pdf: { pdf: {
title: 'Paramètre PDF', title: 'Paramètre PDF',
@ -654,6 +665,11 @@ export default {
select_time_zone: 'sélectionnez le fuseau horaire', select_time_zone: 'sélectionnez le fuseau horaire',
select_date_formate: 'sélectionnez Date Formate', select_date_formate: 'sélectionnez Date Formate',
select_financial_year: 'sélectionner lexercice' select_financial_year: 'sélectionner lexercice'
},
update_app: {
title: "Mise à jour de l'application",
description: "mettre à jour la description de l'application",
update: 'Mise à jour'
} }
}, },
wizard: { wizard: {
@ -752,7 +768,7 @@ export default {
numbers_only: 'Chiffres uniquement.', numbers_only: 'Chiffres uniquement.',
characters_only: 'Caractères seulement.', characters_only: 'Caractères seulement.',
password_incorrect: 'Les mots de passe doivent être identiques', password_incorrect: 'Les mots de passe doivent être identiques',
password_length: 'Le mot de passe doit comporter 6 caractères.', password_length: 'Le mot de passe doit comporter 5 caractères.',
qty_must_greater_than_zero: 'La quantité doit être supérieure à zéro.', qty_must_greater_than_zero: 'La quantité doit être supérieure à zéro.',
price_greater_than_zero: 'Le prix doit être supérieur à zéro.', price_greater_than_zero: 'Le prix doit être supérieur à zéro.',
payment_greater_than_zero: 'Le paiement doit être supérieur à zéro.', payment_greater_than_zero: 'Le paiement doit être supérieur à zéro.',

View File

@ -72,6 +72,7 @@ import UserProfile from './views/settings/UserProfile.vue'
import TaxTypes from './views/settings/TaxTypes.vue' import TaxTypes from './views/settings/TaxTypes.vue'
import ExpenseCategory from './views/settings/ExpenseCategory.vue' import ExpenseCategory from './views/settings/ExpenseCategory.vue'
import MailConfig from './views/settings/MailConfig.vue' import MailConfig from './views/settings/MailConfig.vue'
import UpdateApp from './views/settings/UpdateApp.vue'
import Wizard from './views/wizard/Index.vue' import Wizard from './views/wizard/Index.vue'
@ -337,6 +338,11 @@ const routes = [
path: 'notifications', path: 'notifications',
name: 'notifications', name: 'notifications',
component: Notifications component: Notifications
},
{
path: 'update-app',
name: 'updateapp',
component: UpdateApp
} }
] ]
} }

View File

@ -98,7 +98,7 @@ export default {
}, },
password: { password: {
required, required,
minLength: minLength(8) minLength: minLength(5)
} }
} }
}, },

View File

@ -168,7 +168,7 @@
> >
<table-column :label="$t('dashboard.recent_invoices_card.due_on')" show="formattedDueDate" /> <table-column :label="$t('dashboard.recent_invoices_card.due_on')" show="formattedDueDate" />
<table-column :label="$t('dashboard.recent_invoices_card.customer')" show="user.name" /> <table-column :label="$t('dashboard.recent_invoices_card.customer')" show="user.name" />
<table-column :label="$t('dashboard.recent_invoices_card.amount_due')" sort-as="due_amount"> <table-column :label="$t('dashboard.recent_invoices_card.amount_due')" show="due_amount" sort-as="due_amount">
<template slot-scope="row"> <template slot-scope="row">
<span>{{ $t('dashboard.recent_invoices_card.amount_due') }}</span> <span>{{ $t('dashboard.recent_invoices_card.amount_due') }}</span>
<div v-html="$utils.formatMoney(row.due_amount, row.user.currency)"/> <div v-html="$utils.formatMoney(row.due_amount, row.user.currency)"/>
@ -242,7 +242,7 @@
> >
<table-column :label="$t('dashboard.recent_estimate_card.date')" show="formattedExpiryDate" /> <table-column :label="$t('dashboard.recent_estimate_card.date')" show="formattedExpiryDate" />
<table-column :label="$t('dashboard.recent_estimate_card.customer')" show="user.name" /> <table-column :label="$t('dashboard.recent_estimate_card.customer')" show="user.name" />
<table-column :label="$t('dashboard.recent_estimate_card.amount_due')" sort-as="total"> <table-column :label="$t('dashboard.recent_estimate_card.amount_due')" show="total" sort-as="total">
<template slot-scope="row"> <template slot-scope="row">
<span>{{ $t('dashboard.recent_estimate_card.amount_due') }}</span> <span>{{ $t('dashboard.recent_estimate_card.amount_due') }}</span>
<div v-html="$utils.formatMoney(row.total, row.user.currency)"/> <div v-html="$utils.formatMoney(row.total, row.user.currency)"/>

View File

@ -553,6 +553,8 @@ export default {
if (response.data) { if (response.data) {
this.selectCustomer(response.data.estimate.user_id) this.selectCustomer(response.data.estimate.user_id)
this.newEstimate = response.data.estimate this.newEstimate = response.data.estimate
this.newEstimate.estimate_date = moment(response.data.estimate.estimate_date, 'YYYY-MM-DD').toString()
this.newEstimate.expiry_date = moment(response.data.estimate.expiry_date, 'YYYY-MM-DD').toString()
this.discountPerItem = response.data.discount_per_item this.discountPerItem = response.data.discount_per_item
this.taxPerItem = response.data.tax_per_item this.taxPerItem = response.data.tax_per_item
this.selectedCurrency = this.defaultCurrency this.selectedCurrency = this.defaultCurrency

View File

@ -261,13 +261,13 @@
{{ $t('estimates.send_estimate') }} {{ $t('estimates.send_estimate') }}
</a> </a>
</v-dropdown-item> </v-dropdown-item>
<v-dropdown-item v-if="row.status === 'DRAFT' || row.status === 'REJECTED'"> <v-dropdown-item v-if="row.status !== 'ACCEPTED'">
<a class="dropdown-item" href="#" @click.self="onMarkAsAccepted(row.id)"> <a class="dropdown-item" href="#" @click.self="onMarkAsAccepted(row.id)">
<font-awesome-icon icon="check-circle" class="dropdown-item-icon" /> <font-awesome-icon icon="check-circle" class="dropdown-item-icon" />
{{ $t('estimates.mark_as_accepted') }} {{ $t('estimates.mark_as_accepted') }}
</a> </a>
</v-dropdown-item> </v-dropdown-item>
<v-dropdown-item v-if="row.status === 'ACCEPTED' || row.status === 'DRAFT'"> <v-dropdown-item v-if="row.status !== 'REJECTED'">
<a class="dropdown-item" href="#" @click.self="onMarkAsRejected(row.id)"> <a class="dropdown-item" href="#" @click.self="onMarkAsRejected(row.id)">
<font-awesome-icon icon="times-circle" class="dropdown-item-icon" /> <font-awesome-icon icon="times-circle" class="dropdown-item-icon" />
{{ $t('estimates.mark_as_rejected') }} {{ $t('estimates.mark_as_rejected') }}
@ -514,8 +514,8 @@ export default {
icon: '/assets/icon/envelope-solid.svg', icon: '/assets/icon/envelope-solid.svg',
buttons: true, buttons: true,
dangerMode: true dangerMode: true
}).then(async (willDelete) => { }).then(async (willConvertInToinvoice) => {
if (willDelete) { if (willConvertInToinvoice) {
let res = await this.convertToInvoice(id) let res = await this.convertToInvoice(id)
if (res.data) { if (res.data) {
window.toastr['success'](this.$t('estimates.conversion_message')) window.toastr['success'](this.$t('estimates.conversion_message'))
@ -562,8 +562,8 @@ export default {
icon: '/assets/icon/check-circle-solid.svg', icon: '/assets/icon/check-circle-solid.svg',
buttons: true, buttons: true,
dangerMode: true dangerMode: true
}).then(async (willDelete) => { }).then(async (willMarkAsSent) => {
if (willDelete) { if (willMarkAsSent) {
const data = { const data = {
id: id id: id
} }
@ -582,8 +582,8 @@ export default {
icon: '/assets/icon/paper-plane-solid.svg', icon: '/assets/icon/paper-plane-solid.svg',
buttons: true, buttons: true,
dangerMode: true dangerMode: true
}).then(async (sendEstimate) => { }).then(async (willSendEstimate) => {
if (sendEstimate) { if (willSendEstimate) {
const data = { const data = {
id: id id: id
} }

View File

@ -222,12 +222,22 @@ export default {
return true return true
}, },
async onMarkAsSent () { async onMarkAsSent () {
this.isRequestOnGoing = true swal({
let response = await this.markAsSent({id: this.estimate.id}) title: this.$t('general.are_you_sure'),
this.isRequestOnGoing = false text: this.$t('estimates.confirm_mark_as_sent'),
if (response.data) { icon: '/assets/icon/check-circle-solid.svg',
window.toastr['success'](this.$tc('estimates.mark_as_sent')) buttons: true,
} dangerMode: true
}).then(async (willMarkAsSent) => {
if (willMarkAsSent) {
this.isRequestOnGoing = true
let response = await this.markAsSent({id: this.estimate.id})
this.isRequestOnGoing = false
if (response.data) {
window.toastr['success'](this.$tc('estimates.mark_as_sent'))
}
}
})
}, },
async removeEstimate (id) { async removeEstimate (id) {
this.selectEstimate([parseInt(id)]) this.selectEstimate([parseInt(id)])
@ -235,7 +245,7 @@ export default {
swal({ swal({
title: 'Deleted', title: 'Deleted',
text: 'you will not be able to recover this estimate!', text: 'you will not be able to recover this estimate!',
icon: 'error', icon: '/assets/icon/trash-solid.svg',
buttons: true, buttons: true,
dangerMode: true dangerMode: true
}).then(async (willDelete) => { }).then(async (willDelete) => {

View File

@ -554,6 +554,8 @@ export default {
if (response.data) { if (response.data) {
this.selectCustomer(response.data.invoice.user_id) this.selectCustomer(response.data.invoice.user_id)
this.newInvoice = response.data.invoice this.newInvoice = response.data.invoice
this.newInvoice.invoice_date = moment(response.data.invoice.invoice_date, 'YYYY-MM-DD').toString()
this.newInvoice.due_date = moment(response.data.invoice.due_date, 'YYYY-MM-DD').toString()
this.discountPerItem = response.data.discount_per_item this.discountPerItem = response.data.discount_per_item
this.taxPerItem = response.data.tax_per_item this.taxPerItem = response.data.tax_per_item
this.selectedCurrency = this.defaultCurrency this.selectedCurrency = this.defaultCurrency

View File

@ -286,7 +286,7 @@ export default {
swal({ swal({
title: 'Deleted', title: 'Deleted',
text: 'you will not be able to recover this invoice!', text: 'you will not be able to recover this invoice!',
icon: 'error', icon: '/assets/icon/trash-solid.svg',
buttons: true, buttons: true,
dangerMode: true dangerMode: true
}).then(async (willDelete) => { }).then(async (willDelete) => {

View File

@ -112,7 +112,8 @@ export default {
{ name: 'kg', value: 'kg' }, { name: 'kg', value: 'kg' },
{ name: 'km', value: 'km' }, { name: 'km', value: 'km' },
{ name: 'lb', value: 'lb' }, { name: 'lb', value: 'lb' },
{ name: 'mg', value: 'mg' } { name: 'mg', value: 'mg' },
{ name: 'pc', value: 'pc' }
], ],
formData: { formData: {
name: '', name: '',

View File

@ -245,7 +245,8 @@ export default {
{ name: 'kg', value: 'kg' }, { name: 'kg', value: 'kg' },
{ name: 'km', value: 'km' }, { name: 'km', value: 'km' },
{ name: 'lb', value: 'lb' }, { name: 'lb', value: 'lb' },
{ name: 'mg', value: 'mg' } { name: 'mg', value: 'mg' },
{ name: 'pc', value: 'pc' }
], ],
isRequestOngoing: true, isRequestOngoing: true,
filtersApplied: false, filtersApplied: false,

View File

@ -196,7 +196,14 @@ export default {
return true return true
}, },
downloadReport () { downloadReport () {
this.url += '&download=true' if (!this.getReports()) {
return false
}
if (navigator.appVersion.indexOf('Mac') !== -1) {
this.url += '&download=true'
} else {
window.open(this.getReportUrl + '&download=true')
}
setTimeout(() => { setTimeout(() => {
this.url = `${this.siteURL}?from_date=${moment(this.formData.from_date).format('DD/MM/YYYY')}&to_date=${moment(this.formData.to_date).format('DD/MM/YYYY')}` this.url = `${this.siteURL}?from_date=${moment(this.formData.from_date).format('DD/MM/YYYY')}&to_date=${moment(this.formData.to_date).format('DD/MM/YYYY')}`
}, 200) }, 200)

View File

@ -200,7 +200,14 @@ export default {
return true return true
}, },
downloadReport () { downloadReport () {
this.url += '&download=true' if (!this.getReports()) {
return false
}
if (navigator.appVersion.indexOf('Mac') !== -1) {
this.url += '&download=true'
} else {
window.open(this.getReportUrl + '&download=true')
}
setTimeout(() => { setTimeout(() => {
this.url = `${this.siteURL}?from_date=${moment(this.formData.from_date).format('DD/MM/YYYY')}&to_date=${moment(this.formData.to_date).format('DD/MM/YYYY')}` this.url = `${this.siteURL}?from_date=${moment(this.formData.from_date).format('DD/MM/YYYY')}&to_date=${moment(this.formData.to_date).format('DD/MM/YYYY')}`
}, 200) }, 200)

View File

@ -238,7 +238,14 @@ export default {
return true return true
}, },
downloadReport () { downloadReport () {
this.url += '&download=true' if (!this.getReports()) {
return false
}
if (navigator.appVersion.indexOf('Mac') !== -1) {
this.url += '&download=true'
} else {
window.open(this.getReportUrl + '&download=true')
}
setTimeout(() => { setTimeout(() => {
if (this.selectedType === 'By Customer') { if (this.selectedType === 'By Customer') {
this.url = `${this.customerSiteURL}?from_date=${moment(this.formData.from_date).format('DD/MM/YYYY')}&to_date=${moment(this.formData.to_date).format('DD/MM/YYYY')}` this.url = `${this.customerSiteURL}?from_date=${moment(this.formData.from_date).format('DD/MM/YYYY')}&to_date=${moment(this.formData.to_date).format('DD/MM/YYYY')}`

View File

@ -189,14 +189,21 @@ export default {
this.$v.formData.$touch() this.$v.formData.$touch()
if (this.$v.$invalid) { if (this.$v.$invalid) {
return true return false
} }
this.url = `${this.siteURL}?from_date=${moment(this.formData.from_date).format('DD/MM/YYYY')}&to_date=${moment(this.formData.to_date).format('DD/MM/YYYY')}` this.url = `${this.siteURL}?from_date=${moment(this.formData.from_date).format('DD/MM/YYYY')}&to_date=${moment(this.formData.to_date).format('DD/MM/YYYY')}`
return true return true
}, },
downloadReport () { downloadReport () {
this.url += '&download=true' if (!this.getReports()) {
return false
}
if (navigator.appVersion.indexOf('Mac') !== -1) {
this.url += '&download=true'
} else {
window.open(this.url + '&download=true')
}
setTimeout(() => { setTimeout(() => {
this.url = `${this.siteURL}?from_date=${moment(this.formData.from_date).format('DD/MM/YYYY')}&to_date=${moment(this.formData.to_date).format('DD/MM/YYYY')}` this.url = `${this.siteURL}?from_date=${moment(this.formData.from_date).format('DD/MM/YYYY')}&to_date=${moment(this.formData.to_date).format('DD/MM/YYYY')}`
}, 200) }, 200)

View File

@ -66,8 +66,9 @@
<base-input <base-input
:invalid="$v.mailConfigData.mail_password.$error" :invalid="$v.mailConfigData.mail_password.$error"
v-model.trim="mailConfigData.mail_password" v-model.trim="mailConfigData.mail_password"
type="mail_password" type="password"
name="name" name="name"
show-password
@input="$v.mailConfigData.mail_password.$touch()" @input="$v.mailConfigData.mail_password.$touch()"
/> />
<div v-if="$v.mailConfigData.mail_password.$error"> <div v-if="$v.mailConfigData.mail_password.$error">
@ -141,12 +142,12 @@ export default {
data () { data () {
return { return {
mailConfigData: { mailConfigData: {
mail_driver: 'smtp', mail_driver: '',
mail_host: 'mailtrap.io', mail_host: '',
mail_port: 2525, mail_port: null,
mail_username: 'cc3c64516febd4', mail_username: '',
mail_password: 'e6a0176301f587', mail_password: '',
mail_encryption: 'tls' mail_encryption: ''
}, },
loading: false, loading: false,
mail_drivers: [] mail_drivers: []
@ -176,18 +177,22 @@ export default {
} }
}, },
mounted () { mounted () {
// this.getMailDrivers() this.loadData()
}, },
methods: { methods: {
async getMailDrivers () { async loadData () {
this.loading = true this.loading = true
let response = await window.axios.get('/api/admin/onboarding/environment/mail') let mailDrivers = await window.axios.get('/api/settings/environment/mail')
let mailData = await window.axios.get('/api/settings/environment/mail-env')
if (response.data) { if (mailDrivers.data) {
this.mail_drivers = response.data this.mail_drivers = mailDrivers.data
this.loading = false
} }
if (mailData.data) {
this.mailConfigData = mailData.data
}
this.loading = false
}, },
async saveEmailConfig () { async saveEmailConfig () {
this.$v.mailConfigData.$touch() this.$v.mailConfigData.$touch()
@ -196,7 +201,7 @@ export default {
} }
this.loading = true this.loading = true
try { try {
let response = await window.axios.post('/api/admin/onboarding/environment/mail', this.mailConfigData) let response = await window.axios.post('/api/settings/environment/mail', this.mailConfigData)
if (response.data.success) { if (response.data.success) {
window.toastr['success'](this.$t('wizard.success.' + response.data.success)) window.toastr['success'](this.$t('wizard.success.' + response.data.success))
} else { } else {

View File

@ -29,16 +29,9 @@
> >
<table-column <table-column
:sortable="true" :sortable="true"
:filterable="true"
:label="$t('settings.tax_types.tax_name')" :label="$t('settings.tax_types.tax_name')"
> show="name"
<template slot-scope="row"> />
<span>{{ $t('settings.tax_types.tax_name') }}</span>
<span class="tax-name mt-3">
{{ row.name }}
</span>
</template>
</table-column>
<table-column <table-column
:sortable="true" :sortable="true"
:filterable="true" :filterable="true"

View File

@ -0,0 +1,55 @@
<template>
<div class="setting-main-container">
<div class="card setting-card">
<div class="page-header">
<h3 class="page-title">{{ $t('settings.update_app.title') }}</h3>
<p class="page-sub-title">
{{ $t('settings.update_app.description') }}
</p>
<base-button size="large" icon="sync-alt" color="theme" @click="onUpdateApp">
{{ $t('settings.update_app.update') }}
</base-button>
<div v-if="isShowProgressBar" class="progress mt-4">
<div
:style="[{'width': progress+'%'}]"
class="progress-bar progress-bar-striped progress-bar-animated"
role="progressbar"
aria-valuenow="0"
aria-valuemin="0"
aria-valuemax="100"
/>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data () {
return {
isShowProgressBar: false,
progress: 10,
interval: null
}
},
watch: {
},
mounted () {
},
methods: {
onUpdateApp () {
this.isShowProgressBar = true
this.interval = setInterval(() => {
if (this.progress >= 100) {
clearInterval(this.interval)
setTimeout(() => {
this.isShowProgressBar = false
}, 1000)
}
this.progress += 10
}, 250)
}
}
}
</script>

View File

@ -106,7 +106,7 @@ export default {
email email
}, },
password: { password: {
minLength: minLength(8) minLength: minLength(5)
}, },
confirm_password: { confirm_password: {
required: requiredIf('isRequired'), required: requiredIf('isRequired'),

View File

@ -74,6 +74,12 @@ export default {
title: 'settings.menu_title.notifications', title: 'settings.menu_title.notifications',
icon: 'bell', icon: 'bell',
iconType: 'far' iconType: 'far'
},
{
link: '/admin/settings/update-app',
title: 'settings.menu_title.update_app',
icon: 'sync-alt',
iconType: 'fas'
} }
] ]
} }

View File

@ -94,17 +94,27 @@
<div class="col-md-6"> <div class="col-md-6">
<label class="form-label">{{ $t('wizard.address') }}</label> <label class="form-label">{{ $t('wizard.address') }}</label>
<base-text-area <base-text-area
:invalid="$v.companyData.address_street_1.$error"
v-model.trim="companyData.address_street_1" v-model.trim="companyData.address_street_1"
:placeholder="$t('general.street_1')" :placeholder="$t('general.street_1')"
name="billing_street1" name="billing_street1"
rows="2" rows="2"
@input="$v.companyData.address_street_1.$touch()"
/> />
<div v-if="$v.companyData.address_street_1.$error">
<span v-if="!$v.companyData.address_street_1.maxLength" class="text-danger">{{ $t('validation.description_maxlength') }}</span>
</div>
<base-text-area <base-text-area
:invalid="$v.companyData.address_street_2.$error"
v-model="companyData.address_street_2" v-model="companyData.address_street_2"
:placeholder="$t('general.street_2')" :placeholder="$t('general.street_2')"
name="billing_street2" name="billing_street2"
rows="2" rows="2"
@input="$v.companyData.address_street_2.$touch()"
/> />
<div v-if="$v.companyData.address_street_2.$error">
<span v-if="!$v.companyData.address_street_2.maxLength" class="text-danger">{{ $t('validation.description_maxlength') }}</span>
</div>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<div class="row"> <div class="row">
@ -146,7 +156,7 @@ import MultiSelect from 'vue-multiselect'
import AvatarCropper from 'vue-avatar-cropper' import AvatarCropper from 'vue-avatar-cropper'
import { validationMixin } from 'vuelidate' import { validationMixin } from 'vuelidate'
import Ls from '../../services/ls' import Ls from '../../services/ls'
const { required, minLength, email } = require('vuelidate/lib/validators') const { required, minLength, email, maxLength } = require('vuelidate/lib/validators')
export default { export default {
components: { components: {
@ -197,6 +207,12 @@ export default {
}, },
country_id: { country_id: {
required required
},
address_street_1: {
maxLength: maxLength(255)
},
address_street_2: {
maxLength: maxLength(255)
} }
} }
}, },

View File

@ -97,7 +97,6 @@
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<label class="form-label">{{ $t('wizard.database.password') }}</label> <label class="form-label">{{ $t('wizard.database.password') }}</label>
<span class="text-danger"> *</span>
<base-input <base-input
v-model.trim="databaseData.database_password" v-model.trim="databaseData.database_password"
type="password" type="password"
@ -154,7 +153,7 @@ export default {
database_name: null, database_name: null,
database_username: null, database_username: null,
database_password: null, database_password: null,
app_url: null app_url: window.location.origin
}, },
loading: false, loading: false,
connections: [ connections: [
@ -207,8 +206,8 @@ export default {
} }
this.loading = false this.loading = false
} catch (e) { } catch (e) {
console.log(e) console.log(e.response)
window.toastr['error']('Something went wrong') window.toastr['error'](e.response.data.message)
} }
} }
} }

View File

@ -61,7 +61,8 @@
<base-input <base-input
:invalid="$v.mailConfigData.mail_password.$error" :invalid="$v.mailConfigData.mail_password.$error"
v-model.trim="mailConfigData.mail_password" v-model.trim="mailConfigData.mail_password"
type="mail_password" type="password"
show-password
name="name" name="name"
@input="$v.mailConfigData.mail_password.$touch()" @input="$v.mailConfigData.mail_password.$touch()"
/> />

View File

@ -67,8 +67,8 @@ export default {
data () { data () {
return { return {
loading: false, loading: false,
tab: 'step_1', tab: 'step_3',
step: 1 step: 3
} }
}, },
created () { created () {

View File

@ -35,7 +35,7 @@
</div> </div>
</div> </div>
<base-button <base-button
v-if="requirements" v-if="hasNext"
:loading="loading" :loading="loading"
class="pull-right mt-4" class="pull-right mt-4"
icon="arrow-right" icon="arrow-right"
@ -46,7 +46,7 @@
{{ $t('wizard.continue') }} {{ $t('wizard.continue') }}
</base-button> </base-button>
<base-button <base-button
v-else v-if="!requirements"
:loading="loading" :loading="loading"
class="pull-right mt-4" class="pull-right mt-4"
color="theme" color="theme"
@ -74,6 +74,20 @@ export default {
isShow: true isShow: true
} }
}, },
computed: {
hasNext () {
if (this.requirements) {
let isRequired = true
for (const key in this.requirements) {
if (!this.requirements[key]) {
isRequired = false
}
}
return this.requirements && this.phpSupportInfo.supported && isRequired
}
return false
}
},
methods: { methods: {
listToggle () { listToggle () {
this.isShow = !this.isShow this.isShow = !this.isShow

View File

@ -108,7 +108,7 @@ export default {
}, },
password: { password: {
required, required,
minLength: minLength(8) minLength: minLength(5)
}, },
confirm_password: { confirm_password: {
required: requiredIf('isRequired'), required: requiredIf('isRequired'),

View File

@ -50,7 +50,9 @@ import {
faShare, faShare,
faEllipsisH, faEllipsisH,
faCopy, faCopy,
faPaperPlane faPaperPlane,
faEyeSlash,
faSyncAlt
} from '@fortawesome/free-solid-svg-icons' } from '@fortawesome/free-solid-svg-icons'
import { far } from '@fortawesome/free-regular-svg-icons' import { far } from '@fortawesome/free-regular-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome' import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
@ -108,10 +110,12 @@ library.add(
faFilePdf, faFilePdf,
faEnvelope, faEnvelope,
faEye, faEye,
faEyeSlash,
faShare, faShare,
faEllipsisH, faEllipsisH,
faCopy, faCopy,
faPaperPlane faPaperPlane,
faSyncAlt
) )
Vue.component('font-awesome-icon', FontAwesomeIcon) Vue.component('font-awesome-icon', FontAwesomeIcon)

View File

@ -19,3 +19,19 @@
} }
} }
@media(max-width: $x-small-breakpoint ) {
.base-modal {
.category-modal {
.input-label {
text-align: left;
}
}
}
}

View File

@ -34,3 +34,20 @@
} }
} }
@media(max-width: $x-small-breakpoint ) {
.base-modal {
.customer-modal {
.input-label {
text-align: left;
}
}
}
}

View File

@ -19,3 +19,20 @@
} }
} }
@media(max-width: $x-small-breakpoint ) {
.base-modal {
.item-modal {
.input-label {
text-align: left;
}
}
}
}

View File

@ -58,6 +58,7 @@
.content { .content {
display: flex; display: flex;
flex:1;
flex-direction: column; flex-direction: column;
label { label {
@ -445,6 +446,9 @@
.estimate-amount { .estimate-amount {
font-size: 18px; font-size: 18px;
color: #55547A; color: #55547A;
display: flex;
justify-content: center;
align-items: center;
} }
.total { .total {
@ -491,7 +495,6 @@
font-weight: 300; font-weight: 300;
font-size: 12px; font-size: 12px;
padding-top: 2px; padding-top: 2px;
padding-left: 10px;
textarea { textarea {

View File

@ -38,7 +38,7 @@
} }
.filter-date { .filter-date {
flex: 1; flex: 2;
display: flex; display: flex;
margin-right: 40px; margin-right: 40px;
align-items: center; align-items: center;
@ -60,7 +60,7 @@
margin-top: 28px; margin-top: 28px;
} }
@media(max-width: $medium-breakpoint ) { @media(max-width: $large-breakpoint ) {
.filter-container { .filter-container {
flex-direction: column; flex-direction: column;
} }

View File

@ -58,6 +58,7 @@
.content { .content {
display: flex; display: flex;
flex: 1;
flex-direction: column; flex-direction: column;
label { label {
@ -445,6 +446,9 @@
.invoice-amount { .invoice-amount {
font-size: 18px; font-size: 18px;
color: #55547A; color: #55547A;
display: flex;
justify-content: center;
align-items: center;
} }
.total { .total {

View File

@ -33,7 +33,7 @@
} }
.filter-date { .filter-date {
flex: 1; flex: 2;
display: flex; display: flex;
margin-right: 40px; margin-right: 40px;
align-items: center; align-items: center;
@ -55,7 +55,7 @@
margin-top: 28px; margin-top: 28px;
} }
@media(max-width: $medium-breakpoint ) { @media(max-width: $large-breakpoint ) {
.filter-container { .filter-container {
flex-direction: column; flex-direction: column;
} }

View File

@ -1,6 +1,6 @@
// Invoice statuses // Invoice statuses
.inv-status-due { .inv-status-overdue {
background: #FED7D7; background: #FED7D7;
font-size: 13px; font-size: 13px;
color: #9B2C2C; color: #9B2C2C;
@ -15,9 +15,9 @@
} }
.inv-status-unpaid { .inv-status-unpaid {
background: rgba(246, 208, 154, 0.4); background: #F8EDCB;
font-size: 13px; font-size: 13px;
color: #A96E1A; color: #6C432E;
padding: 5px 10px; padding: 5px 10px;
} }
@ -50,9 +50,9 @@
} }
.inv-status-partially_paid { .inv-status-partially_paid {
background: #E1E0EA; background: #C9E3EC;
font-size: 13px; font-size: 13px;
color: #312F57; color: #1E576C;
padding: 5px 10px; padding: 5px 10px;
} }

View File

@ -323,6 +323,21 @@ Route::group(['middleware' => 'api'], function () {
'uses' => 'CompanyController@updateSetting' 'uses' => 'CompanyController@updateSetting'
]); ]);
Route::get('/environment/mail', [
'as' => 'admin.environment.mail',
'uses' => 'EnvironmentController@getMailDrivers'
]);
Route::get('/environment/mail-env', [
'as' => 'admin.mail.env',
'uses' => 'EnvironmentController@getMailEnvironment'
]);
Route::post('/environment/mail', [
'as' => 'admin.environment.mail.save',
'uses' => 'EnvironmentController@saveMailEnvironment'
]);
}); });
}); });