Merge branch 'master' of https://github.com/brkcvn/akaunting into new-plans
This commit is contained in:
		| @@ -150,7 +150,7 @@ abstract class Report | |||||||
|  |  | ||||||
|     public function applySearchStringFilter($event) |     public function applySearchStringFilter($event) | ||||||
|     { |     { | ||||||
|         $input = request('search'); |         $input = request('search', ''); | ||||||
|  |  | ||||||
|         // Remove year as it's handled based on financial start |         // Remove year as it's handled based on financial start | ||||||
|         $search_year = 'year:' . $this->getSearchStringValue('year', '', $input); |         $search_year = 'year:' . $this->getSearchStringValue('year', '', $input); | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ abstract class Widget | |||||||
|     public $default_name = ''; |     public $default_name = ''; | ||||||
|  |  | ||||||
|     public $default_settings = [ |     public $default_settings = [ | ||||||
|         'width' => 'w-full lg:w-2/4 px-12 my-8', |         'width' => 'w-full lg:w-2/4 lg:px-12 my-8', | ||||||
|     ]; |     ]; | ||||||
|  |  | ||||||
|     public $description = ''; |     public $description = ''; | ||||||
|   | |||||||
| @@ -48,6 +48,20 @@ class Handler extends ExceptionHandler | |||||||
|         'password_confirmation', |         'password_confirmation', | ||||||
|     ]; |     ]; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Register the exception handling callbacks for the application. | ||||||
|  |      * | ||||||
|  |      * @return void | ||||||
|  |      */ | ||||||
|  |     public function register() | ||||||
|  |     { | ||||||
|  |         $this->reportable(function (Throwable $e) { | ||||||
|  |             if (config('logging.default') == 'bugsnag') { | ||||||
|  |                 call_user_func(config('bugsnag.before_send'), $e); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Report or log an exception. |      * Report or log an exception. | ||||||
|      * |      * | ||||||
|   | |||||||
							
								
								
									
										29
									
								
								app/Exceptions/Trackers/Bugsnag.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								app/Exceptions/Trackers/Bugsnag.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace App\Exceptions\Trackers; | ||||||
|  |  | ||||||
|  | use Throwable; | ||||||
|  |  | ||||||
|  | class Bugsnag | ||||||
|  | { | ||||||
|  |     public static function beforeSend(Throwable $e): void | ||||||
|  |     { | ||||||
|  |         app('bugsnag')->setAppVersion(version('short')); | ||||||
|  |  | ||||||
|  |         app('bugsnag')->registerCallback(function ($report) { | ||||||
|  |             $report->setMetaData([ | ||||||
|  |                 'akaunting' => [ | ||||||
|  |                     'company_id' => (string) company_id(), | ||||||
|  |                     'locale' => (string) app()->getLocale(), | ||||||
|  |                     'timezone' => (string) config('app.timezone'), | ||||||
|  |                     'route_name' => (string) static::getRouteName(), | ||||||
|  |                 ] | ||||||
|  |             ]); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public static function getRouteName(): ?string | ||||||
|  |     { | ||||||
|  |         return request()->route()?->getName(); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										76
									
								
								app/Exceptions/Trackers/Sentry.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								app/Exceptions/Trackers/Sentry.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace App\Exceptions\Trackers; | ||||||
|  |  | ||||||
|  | use Illuminate\Support\Str; | ||||||
|  | use Sentry\Event; | ||||||
|  | use Sentry\EventHint; | ||||||
|  | use Sentry\Tracing\SamplingContext; | ||||||
|  |  | ||||||
|  | class Sentry | ||||||
|  | { | ||||||
|  |     public static function beforeSend(Event $event, ?EventHint $hint): ?Event | ||||||
|  |     { | ||||||
|  |         $event->setRelease(version('short')); | ||||||
|  |  | ||||||
|  |         $event->setTags([ | ||||||
|  |             'company_id' => (string) company_id(), | ||||||
|  |             'locale' => (string) app()->getLocale(), | ||||||
|  |             'timezone' => (string) config('app.timezone'), | ||||||
|  |             'app_type' => (string) static::getAppType(), | ||||||
|  |             'route_name' => (string) static::getRouteName(), | ||||||
|  |         ]); | ||||||
|  |  | ||||||
|  |         return $event; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public static function tracesSampler(SamplingContext $context): float | ||||||
|  |     { | ||||||
|  |         if (static::shouldFilterAgent()) { | ||||||
|  |             return 0.0; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return config('sentry.traces_sample_rate'); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public static function shouldFilterAgent(): bool | ||||||
|  |     { | ||||||
|  |         $user_agent = request()->userAgent(); | ||||||
|  |  | ||||||
|  |         $filter_agents = explode(',', env('SENTRY_TRACES_FILTER_AGENTS')); | ||||||
|  |  | ||||||
|  |         foreach ($filter_agents as $filter_agent) { | ||||||
|  |             if (! Str::contains($user_agent, $filter_agent)) { | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public static function getAppType(): string | ||||||
|  |     { | ||||||
|  |         $hostname = gethostname(); | ||||||
|  |  | ||||||
|  |         if (Str::contains($hostname, '-queue-')) { | ||||||
|  |             $app_type = 'queue'; | ||||||
|  |         } elseif (Str::contains($hostname, '-cron-')) { | ||||||
|  |             $app_type = 'cron'; | ||||||
|  |         } elseif (request()->isApi()) { | ||||||
|  |             $app_type = 'api'; | ||||||
|  |         } elseif (app()->runningInConsole()) { | ||||||
|  |             $app_type = 'console'; | ||||||
|  |         } else { | ||||||
|  |             $app_type = 'ui'; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return $app_type; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public static function getRouteName(): ?string | ||||||
|  |     { | ||||||
|  |         return request()->route()?->getName(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -195,7 +195,7 @@ class Categories extends Controller | |||||||
|  |  | ||||||
|             flash($message)->success(); |             flash($message)->success(); | ||||||
|         } else { |         } else { | ||||||
|             $response['redirect'] = route('categories.edit', $category_id); |             $response['redirect'] = route('categories.edit', $category->id); | ||||||
|  |  | ||||||
|             $message = $response['message']; |             $message = $response['message']; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,16 +8,24 @@ use App\Interfaces\Job\HasSource; | |||||||
| use App\Interfaces\Job\ShouldCreate; | use App\Interfaces\Job\ShouldCreate; | ||||||
| use App\Models\Banking\Reconciliation; | use App\Models\Banking\Reconciliation; | ||||||
| use App\Models\Banking\Transaction; | use App\Models\Banking\Transaction; | ||||||
|  | use App\Utilities\Date; | ||||||
|  |  | ||||||
| class CreateReconciliation extends Job implements HasOwner, HasSource, ShouldCreate | class CreateReconciliation extends Job implements HasOwner, HasSource, ShouldCreate | ||||||
| { | { | ||||||
|     public function handle(): Reconciliation |     public function handle(): Reconciliation | ||||||
|     { |     { | ||||||
|         \DB::transaction(function () { |         \DB::transaction(function () { | ||||||
|  |             $started_at = Date::parse($this->request->get('started_at'))->startOfDay(); | ||||||
|  |             $ended_at = Date::parse($this->request->get('ended_at'))->endOfDay(); | ||||||
|  |  | ||||||
|             $reconcile = (int) $this->request->get('reconcile'); |             $reconcile = (int) $this->request->get('reconcile'); | ||||||
|             $transactions = $this->request->get('transactions'); |             $transactions = $this->request->get('transactions'); | ||||||
|  |  | ||||||
|             $this->request->merge(['reconciled' => $reconcile]); |             $this->request->merge([ | ||||||
|  |                 'started_at' => $started_at, | ||||||
|  |                 'ended_at' => $ended_at, | ||||||
|  |                 'reconciled' => $reconcile, | ||||||
|  |             ]); | ||||||
|  |  | ||||||
|             $this->model = Reconciliation::create($this->request->all()); |             $this->model = Reconciliation::create($this->request->all()); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ class Reconciliation extends Model | |||||||
|      * |      * | ||||||
|      * @var array |      * @var array | ||||||
|      */ |      */ | ||||||
|     protected $fillable = ['company_id', 'account_id', 'started_at', 'ended_at', 'closing_balance', 'reconciled', 'created_from', 'created_by']; |     protected $fillable = ['company_id', 'account_id', 'started_at', 'ended_at', 'closing_balance', 'transactions', 'reconciled', 'created_from', 'created_by']; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * The attributes that should be cast. |      * The attributes that should be cast. | ||||||
|   | |||||||
| @@ -565,7 +565,7 @@ class Transaction extends Model | |||||||
|                             'permission' => 'read-banking-transactions', |                             'permission' => 'read-banking-transactions', | ||||||
|                             'attributes' => [ |                             'attributes' => [ | ||||||
|                                 'id' => 'index-line-actions-send-email-' . $this->type . '-'  . $this->id, |                                 'id' => 'index-line-actions-send-email-' . $this->type . '-'  . $this->id, | ||||||
|                                 '@click' => 'onEmail("' . route('modals.transactions.emails.create', $this->id) . '")', |                                 '@click' => 'onSendEmail("' . route('modals.transactions.emails.create', $this->id) . '")', | ||||||
|                             ], |                             ], | ||||||
|                         ]; |                         ]; | ||||||
|                     } |                     } | ||||||
|   | |||||||
| @@ -488,6 +488,20 @@ class Document extends Model | |||||||
|             return $actions; |             return $actions; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         if (app('mobile-detect')->isMobile()) { | ||||||
|  |             try { | ||||||
|  |                 $actions[] = [ | ||||||
|  |                     'title' => trans('general.show'), | ||||||
|  |                     'icon' => 'visibility', | ||||||
|  |                     'url' => route($prefix . '.show', $this->id), | ||||||
|  |                     'permission' => 'read-' . $group . '-' . $permission_prefix, | ||||||
|  |                     'attributes' => [ | ||||||
|  |                         'id' => 'index-more-actions-show-' . $this->id, | ||||||
|  |                     ], | ||||||
|  |                 ]; | ||||||
|  |             } catch (\Exception $e) {} | ||||||
|  |         } | ||||||
|  |  | ||||||
|         try { |         try { | ||||||
|             if (! $this->reconciled) { |             if (! $this->reconciled) { | ||||||
|                 $actions[] = [ |                 $actions[] = [ | ||||||
| @@ -524,7 +538,7 @@ class Document extends Model | |||||||
|                     'permission' => 'read-' . $group . '-' . $permission_prefix, |                     'permission' => 'read-' . $group . '-' . $permission_prefix, | ||||||
|                     'attributes' => [ |                     'attributes' => [ | ||||||
|                         'id' => 'index-line-actions-payment-' . $this->type . '-' . $this->id, |                         'id' => 'index-line-actions-payment-' . $this->type . '-' . $this->id, | ||||||
|                         '@click' => 'onPayment("' . $this->id . '")', |                         '@click' => 'onAddPayment("' . route('modals.documents.document.transactions.create', $this->id) . '")', | ||||||
|                     ], |                     ], | ||||||
|                 ]; |                 ]; | ||||||
|             } catch (\Exception $e) {} |             } catch (\Exception $e) {} | ||||||
| @@ -601,7 +615,7 @@ class Document extends Model | |||||||
|                             'permission' => 'read-' . $group . '-' . $permission_prefix, |                             'permission' => 'read-' . $group . '-' . $permission_prefix, | ||||||
|                             'attributes' => [ |                             'attributes' => [ | ||||||
|                                 'id' => 'index-line-actions-send-email-' . $this->type . '-'  . $this->id, |                                 'id' => 'index-line-actions-send-email-' . $this->type . '-'  . $this->id, | ||||||
|                                 '@click' => 'onEmail("' . route('modals.'. $prefix . '.emails.create', $this->id) . '")', |                                 '@click' => 'onSendEmail("' . route('modals.'. $prefix . '.emails.create', $this->id) . '")', | ||||||
|                             ], |                             ], | ||||||
|                         ]; |                         ]; | ||||||
|                     } |                     } | ||||||
|   | |||||||
| @@ -106,6 +106,11 @@ trait Charts | |||||||
|         $percent_position = $position ?: setting('localisation.percent_position'); |         $percent_position = $position ?: setting('localisation.percent_position'); | ||||||
|  |  | ||||||
|         switch ($type) { |         switch ($type) { | ||||||
|  |             case 'integer': | ||||||
|  |                 $label = new Raw("function(value) { | ||||||
|  |                     return value | ||||||
|  |                 }"); | ||||||
|  |                 break; | ||||||
|             case 'percent': |             case 'percent': | ||||||
|                 $label = new Raw("function(value) { |                 $label = new Raw("function(value) { | ||||||
|                     " . ($percent_position == 'right' ? "return value + '%';" : "return '%' + value;") . " |                     " . ($percent_position == 'right' ? "return value + '%';" : "return '%' + value;") . " | ||||||
|   | |||||||
| @@ -8,16 +8,12 @@ trait SearchString | |||||||
|      * Get the value of a name in search string |      * Get the value of a name in search string | ||||||
|      * Example: search=type:customer year:2020 account_id:20 |      * Example: search=type:customer year:2020 account_id:20 | ||||||
|      * Example: issued_at>=2021-02-01 issued_at<=2021-02-10 account_id:49 |      * Example: issued_at>=2021-02-01 issued_at<=2021-02-10 account_id:49 | ||||||
|      * |  | ||||||
|      * @return string|array |  | ||||||
|      */ |      */ | ||||||
|     public function getSearchStringValue($name, $default = '', $input = null) |     public function getSearchStringValue(string $name, string $default = '', string $input = ''): string|array | ||||||
|     { |     { | ||||||
|         $value = $default; |         $value = $default; | ||||||
|  |  | ||||||
|         if (is_null($input)) { |         $input = $input ?: request('search', ''); | ||||||
|             $input = request('search'); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         // $manager = $this->getSearchStringManager(); |         // $manager = $this->getSearchStringManager(); | ||||||
|         // $parsed = $manager->parse($input); |         // $parsed = $manager->parse($input); | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ class CashFlow extends Widget | |||||||
|     public $default_name = 'widgets.cash_flow'; |     public $default_name = 'widgets.cash_flow'; | ||||||
|  |  | ||||||
|     public $default_settings = [ |     public $default_settings = [ | ||||||
|         'width' => 'w-full my-8 px-12', |         'width' => 'w-full my-8 lg:px-12', | ||||||
|     ]; |     ]; | ||||||
|  |  | ||||||
|     public $description = 'widgets.description.cash_flow'; |     public $description = 'widgets.description.cash_flow'; | ||||||
|   | |||||||
| @@ -44,6 +44,7 @@ | |||||||
|         "barryvdh/laravel-dompdf": "^2.0", |         "barryvdh/laravel-dompdf": "^2.0", | ||||||
|         "barryvdh/laravel-ide-helper": "^2.9", |         "barryvdh/laravel-ide-helper": "^2.9", | ||||||
|         "bkwld/cloner": "^3.10", |         "bkwld/cloner": "^3.10", | ||||||
|  |         "bugsnag/bugsnag-laravel": "^2.24", | ||||||
|         "doctrine/dbal": "^3.1", |         "doctrine/dbal": "^3.1", | ||||||
|         "fruitcake/laravel-cors": "^2.0", |         "fruitcake/laravel-cors": "^2.0", | ||||||
|         "genealabs/laravel-model-caching": "0.12.*", |         "genealabs/laravel-model-caching": "0.12.*", | ||||||
| @@ -67,6 +68,7 @@ | |||||||
|         "plank/laravel-mediable": "^5.4", |         "plank/laravel-mediable": "^5.4", | ||||||
|         "riverskies/laravel-mobile-detect": "^1.3", |         "riverskies/laravel-mobile-detect": "^1.3", | ||||||
|         "santigarcor/laratrust": "^7.0", |         "santigarcor/laratrust": "^7.0", | ||||||
|  |         "sentry/sentry-laravel": "^3.0", | ||||||
|         "simple-icons/simple-icons": "^6.0", |         "simple-icons/simple-icons": "^6.0", | ||||||
|         "simshaun/recurr": "^5.0", |         "simshaun/recurr": "^5.0", | ||||||
|         "staudenmeir/belongs-to-through": "^2.12", |         "staudenmeir/belongs-to-through": "^2.12", | ||||||
|   | |||||||
							
								
								
									
										1083
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1083
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -180,6 +180,7 @@ return [ | |||||||
|         /* |         /* | ||||||
|          * Package Service Providers... |          * Package Service Providers... | ||||||
|          */ |          */ | ||||||
|  |         Bugsnag\BugsnagLaravel\BugsnagServiceProvider::class, | ||||||
|         Laravel\Tinker\TinkerServiceProvider::class, |         Laravel\Tinker\TinkerServiceProvider::class, | ||||||
|  |  | ||||||
|         /* |         /* | ||||||
|   | |||||||
							
								
								
									
										364
									
								
								config/bugsnag.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										364
									
								
								config/bugsnag.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,364 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | return [ | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | API Key | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | | ||||||
|  |     | You can find your API key on your Bugsnag dashboard. | ||||||
|  |     | | ||||||
|  |     | This api key points the Bugsnag notifier to the project in your account | ||||||
|  |     | which should receive your application's uncaught exceptions. | ||||||
|  |     | | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     'api_key' => env('BUGSNAG_API_KEY', ''), | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | App Type | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | | ||||||
|  |     | Set the type of application executing the current code. | ||||||
|  |     | | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     'app_type' => env('BUGSNAG_APP_TYPE'), | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | App Version | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | | ||||||
|  |     | Set the version of application executing the current code. | ||||||
|  |     | | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     'app_version' => env('BUGSNAG_APP_VERSION'), | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | Batch Sending | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | | ||||||
|  |     | Set to true to send the errors through to Bugsnag when the PHP process | ||||||
|  |     | shuts down, in order to prevent your app waiting on HTTP requests. | ||||||
|  |     | | ||||||
|  |     | Setting this to false will send an HTTP request straight away for each | ||||||
|  |     | error. | ||||||
|  |     | | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     'batch_sending' => env('BUGSNAG_BATCH_SENDING', true), | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | Endpoint | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | | ||||||
|  |     | Set what server the Bugsnag notifier should send errors to. By default | ||||||
|  |     | this is set to 'https://notify.bugsnag.com', but for Bugsnag Enterprise | ||||||
|  |     | this should be the URL to your Bugsnag instance. | ||||||
|  |     | | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     'endpoint' => env('BUGSNAG_ENDPOINT'), | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | Filters | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | | ||||||
|  |     | Use this if you want to ensure you don't send sensitive data such as | ||||||
|  |     | passwords, and credit card numbers to our servers. Any keys which | ||||||
|  |     | contain these strings will be filtered. | ||||||
|  |     | | ||||||
|  |     | This option has been deprecated in favour of 'redacted_keys' | ||||||
|  |     | | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     'filters' => empty(env('BUGSNAG_FILTERS')) ? null : explode(',', str_replace(' ', '', env('BUGSNAG_FILTERS'))), | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | Hostname | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | | ||||||
|  |     | You can set the hostname of your server to something specific for you to | ||||||
|  |     | identify it by if needed. | ||||||
|  |     | | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     'hostname' => env('BUGSNAG_HOSTNAME', env('APP_URL')), | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | Proxy | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | | ||||||
|  |     | This is where you can set the proxy settings you'd like us to use when | ||||||
|  |     | communicating with Bugsnag when reporting errors. | ||||||
|  |     | | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     'proxy' => array_filter([ | ||||||
|  |         'http' => env('HTTP_PROXY'), | ||||||
|  |         'https' => env('HTTPS_PROXY'), | ||||||
|  |         'no' => empty(env('NO_PROXY')) ? null : explode(',', str_replace(' ', '', env('NO_PROXY'))), | ||||||
|  |     ]), | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | Project Root | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | | ||||||
|  |     | Bugsnag marks stacktrace lines as in-project if they come from files | ||||||
|  |     | inside your “project root”. You can set this here. | ||||||
|  |     | | ||||||
|  |     | If this is not set, we will automatically try to detect it. | ||||||
|  |     | | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     'project_root' => env('BUGSNAG_PROJECT_ROOT'), | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | Project Root Regex | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | | ||||||
|  |     | Bugsnag marks stacktrace lines as in-project if they come from files | ||||||
|  |     | inside your “project root”. You can set this here. | ||||||
|  |     | | ||||||
|  |     | This option allows you to set it as a regular expression and will take | ||||||
|  |     | precedence over "project_root" if both are defined. | ||||||
|  |     | | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     'project_root_regex' => env('BUGSNAG_PROJECT_ROOT_REGEX'), | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | Strip Path | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | | ||||||
|  |     | The strip path is a path to be trimmed from the start of any filepaths in | ||||||
|  |     | your stacktraces. | ||||||
|  |     | | ||||||
|  |     | If this is not set, we will automatically try to detect it. | ||||||
|  |     | | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     'strip_path' => env('BUGSNAG_STRIP_PATH'), | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | Strip Path Regex | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | | ||||||
|  |     | The strip path is a path to be trimmed from the start of any filepaths in | ||||||
|  |     | your stacktraces. | ||||||
|  |     | | ||||||
|  |     | This option allows you to set it as a regular expression and will take | ||||||
|  |     | precedence over "strip_path" if both are defined. | ||||||
|  |     | | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     'strip_path_regex' => env('BUGSNAG_STRIP_PATH_REGEX'), | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | Query | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | | ||||||
|  |     | Enable this if you'd like us to automatically record all queries executed | ||||||
|  |     | as breadcrumbs. | ||||||
|  |     | | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     'query' => env('BUGSNAG_QUERY', true), | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | Bindings | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | | ||||||
|  |     | Enable this if you'd like us to include the query bindings in our query | ||||||
|  |     | breadcrumbs. | ||||||
|  |     | | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     'bindings' => env('BUGSNAG_QUERY_BINDINGS', false), | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | Release Stage | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | | ||||||
|  |     | Set the release stage to use when sending notifications to Bugsnag. | ||||||
|  |     | | ||||||
|  |     | Leaving this unset will default to using the application environment. | ||||||
|  |     | | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     'release_stage' => env('BUGSNAG_RELEASE_STAGE'), | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | Notify Release Stages | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | | ||||||
|  |     | Set which release stages should send notifications to Bugsnag. | ||||||
|  |     | | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     'notify_release_stages' => empty(env('BUGSNAG_NOTIFY_RELEASE_STAGES')) ? null : explode(',', str_replace(' ', '', env('BUGSNAG_NOTIFY_RELEASE_STAGES'))), | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | Send Code | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | | ||||||
|  |     | Bugsnag automatically sends a small snippet of the code that crashed to | ||||||
|  |     | help you diagnose even faster from within your dashboard. If you don’t | ||||||
|  |     | want to send this snippet, then set this to false. | ||||||
|  |     | | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     'send_code' => env('BUGSNAG_SEND_CODE', true), | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | Callbacks | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | | ||||||
|  |     | Enable this if you'd like us to enable our default set of notification | ||||||
|  |     | callbacks. These add things like the cookie information and session | ||||||
|  |     | details to the error to be sent to Bugsnag. | ||||||
|  |     | | ||||||
|  |     | If you'd like to add your own callbacks, you can call the | ||||||
|  |     | Bugsnag::registerCallback method from the boot method of your app | ||||||
|  |     | service provider. | ||||||
|  |     | | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     'callbacks' => env('BUGSNAG_CALLBACKS', true), | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | User | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | | ||||||
|  |     | Enable this if you'd like us to set the current user logged in via | ||||||
|  |     | Laravel's authentication system. | ||||||
|  |     | | ||||||
|  |     | If you'd like to add your own user resolver, you can do this by using | ||||||
|  |     | callbacks via Bugsnag::registerCallback. | ||||||
|  |     | | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     'user' => env('BUGSNAG_USER', true), | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | Logger Notify Level | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | | ||||||
|  |     | This sets the level at which a logged message will trigger a notification | ||||||
|  |     | to Bugsnag.  By default this level will be 'notice'. | ||||||
|  |     | | ||||||
|  |     | Must be one of the Psr\Log\LogLevel levels from the Psr specification. | ||||||
|  |     | | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     'logger_notify_level' => env('BUGSNAG_LOGGER_LEVEL'), | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | Auto Capture Sessions | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | | ||||||
|  |     | Enable this to start tracking sessions and deliver them to Bugsnag. | ||||||
|  |     | | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     'auto_capture_sessions' => env('BUGSNAG_CAPTURE_SESSIONS', false), | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | Sessions Endpoint | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | | ||||||
|  |     | Sets a url to send tracked sessions to. | ||||||
|  |     | | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     'session_endpoint' => env('BUGSNAG_SESSION_ENDPOINT'), | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | Builds Endpoint | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | | ||||||
|  |     | Sets a url to send build reports to. | ||||||
|  |     | | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     'build_endpoint' => env('BUGSNAG_BUILD_ENDPOINT'), | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | Discard Classes | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | | ||||||
|  |     | An array of classes that should not be sent to Bugsnag. | ||||||
|  |     | | ||||||
|  |     | This can contain both fully qualified class names and regular expressions. | ||||||
|  |     | | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     'discard_classes' => empty(env('BUGSNAG_DISCARD_CLASSES')) ? null : explode(',', env('BUGSNAG_DISCARD_CLASSES')), | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | Redacted Keys | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | | ||||||
|  |     | An array of metadata keys that should be redacted. | ||||||
|  |     | | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     'redacted_keys' => empty(env('BUGSNAG_REDACTED_KEYS')) ? null : explode(',', env('BUGSNAG_REDACTED_KEYS')), | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | Feature flags | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | | ||||||
|  |     | An array of feature flags to add to all reports. | ||||||
|  |     | | ||||||
|  |     | Each element in the array must have a "name" key and can optionally have a | ||||||
|  |     | "variant" key, for example: | ||||||
|  |     | | ||||||
|  |     | [ | ||||||
|  |     |     ['name' => 'example without a variant'], | ||||||
|  |     |     ['name' => 'example with a variant', 'variant' => 'example of a variant'], | ||||||
|  |     | ] | ||||||
|  |     | | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     'feature_flags' => [], | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | Before send | ||||||
|  |     |-------------------------------------------------------------------------- | ||||||
|  |     | | ||||||
|  |     | An array of callback class and method. | ||||||
|  |     | | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     'before_send' => [env('BUGSNAG_BEFORE_SEND_CLASS', 'App\\Exceptions\\Trackers\\Bugsnag'), 'beforeSend'], | ||||||
|  |  | ||||||
|  | ]; | ||||||
| @@ -128,6 +128,16 @@ return [ | |||||||
|             'path' => storage_path('logs/laravel.log'), |             'path' => storage_path('logs/laravel.log'), | ||||||
|         ], |         ], | ||||||
|  |  | ||||||
|  |         'bugsnag' => [ | ||||||
|  |             'driver' => 'bugsnag', | ||||||
|  |             'level' => env('LOG_LEVEL', 'debug'), | ||||||
|  |         ], | ||||||
|  |  | ||||||
|  |         'sentry' => [ | ||||||
|  |             'driver' => 'sentry', | ||||||
|  |             'level' => env('LOG_LEVEL', 'debug'), | ||||||
|  |         ], | ||||||
|  |  | ||||||
|     ], |     ], | ||||||
|  |  | ||||||
| ]; | ]; | ||||||
|   | |||||||
							
								
								
									
										59
									
								
								config/sentry.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								config/sentry.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | return [ | ||||||
|  |  | ||||||
|  |     'dsn' => env('SENTRY_LARAVEL_DSN', env('SENTRY_DSN')), | ||||||
|  |  | ||||||
|  |     // capture release as git sha | ||||||
|  |     // 'release' => trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')) | ||||||
|  |  | ||||||
|  |     // When left empty or `null` the Laravel environment will be used | ||||||
|  |     'environment' => env('SENTRY_ENVIRONMENT'), | ||||||
|  |  | ||||||
|  |     'breadcrumbs' => [ | ||||||
|  |         // Capture Laravel logs in breadcrumbs | ||||||
|  |         'logs' => true, | ||||||
|  |  | ||||||
|  |         // Capture SQL queries in breadcrumbs | ||||||
|  |         'sql_queries' => true, | ||||||
|  |  | ||||||
|  |         // Capture bindings on SQL queries logged in breadcrumbs | ||||||
|  |         'sql_bindings' => true, | ||||||
|  |  | ||||||
|  |         // Capture queue job information in breadcrumbs | ||||||
|  |         'queue_info' => true, | ||||||
|  |  | ||||||
|  |         // Capture command information in breadcrumbs | ||||||
|  |         'command_info' => true, | ||||||
|  |     ], | ||||||
|  |  | ||||||
|  |     'tracing' => [ | ||||||
|  |         // Trace queue jobs as their own transactions | ||||||
|  |         'queue_job_transactions' => env('SENTRY_TRACE_QUEUE_ENABLED', false), | ||||||
|  |  | ||||||
|  |         // Capture queue jobs as spans when executed on the sync driver | ||||||
|  |         'queue_jobs' => true, | ||||||
|  |  | ||||||
|  |         // Capture SQL queries as spans | ||||||
|  |         'sql_queries' => true, | ||||||
|  |  | ||||||
|  |         // Try to find out where the SQL query originated from and add it to the query spans | ||||||
|  |         'sql_origin' => true, | ||||||
|  |  | ||||||
|  |         // Capture views as spans | ||||||
|  |         'views' => true, | ||||||
|  |  | ||||||
|  |         // Indicates if the tracing integrations supplied by Sentry should be loaded | ||||||
|  |         'default_integrations' => true, | ||||||
|  |     ], | ||||||
|  |  | ||||||
|  |     // @see: https://docs.sentry.io/platforms/php/configuration/options/#send-default-pii | ||||||
|  |     'send_default_pii' => env('SENTRY_SEND_DEFAULT_PII', true), | ||||||
|  |  | ||||||
|  |     'traces_sample_rate' => (float)(env('SENTRY_TRACES_SAMPLE_RATE', 0.0)), | ||||||
|  |  | ||||||
|  |     'before_send' => [env('SENTRY_BEFORE_SEND_CLASS', 'App\\Exceptions\\Trackers\\Sentry'), 'beforeSend'], | ||||||
|  |  | ||||||
|  |     'traces_sampler' => [env('SENTRY_TRACES_SAMPLER_CLASS', 'App\\Exceptions\\Trackers\\Sentry'), 'tracesSampler'], | ||||||
|  |  | ||||||
|  | ]; | ||||||
							
								
								
									
										54
									
								
								public/css/app.css
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										54
									
								
								public/css/app.css
									
									
									
									
										vendored
									
									
								
							| @@ -51260,6 +51260,12 @@ body{ | |||||||
|           transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); |           transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | [dir="rtl"] .rtl\:-scale-x-100{ | ||||||
|  |   --tw-scale-x: -1; | ||||||
|  |   -webkit-transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); | ||||||
|  |           transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| [dir="rtl"] .rtl\:space-x-reverse > :not([hidden]) ~ :not([hidden]){ | [dir="rtl"] .rtl\:space-x-reverse > :not([hidden]) ~ :not([hidden]){ | ||||||
|   --tw-space-x-reverse: 1; |   --tw-space-x-reverse: 1; | ||||||
| } | } | ||||||
| @@ -51788,9 +51794,15 @@ body{ | |||||||
|     margin-bottom: 3rem; |     margin-bottom: 3rem; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | <<<<<<< HEAD | ||||||
|   .lg\:my-16{ |   .lg\:my-16{ | ||||||
|     margin-top: 4rem; |     margin-top: 4rem; | ||||||
|     margin-bottom: 4rem; |     margin-bottom: 4rem; | ||||||
|  | ======= | ||||||
|  |   .lg\:-mx-12{ | ||||||
|  |     margin-left: -3rem; | ||||||
|  |     margin-right: -3rem; | ||||||
|  | >>>>>>> d1b81891f887f0ababe1c40221defa5b69162795 | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   .lg\:my-0{ |   .lg\:my-0{ | ||||||
| @@ -51864,6 +51876,10 @@ body{ | |||||||
|     height: 16rem; |     height: 16rem; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   .lg\:h-auto{ | ||||||
|  |     height: auto; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   .lg\:h-48{ |   .lg\:h-48{ | ||||||
|     height: 12rem; |     height: 12rem; | ||||||
|   } |   } | ||||||
| @@ -51880,16 +51896,17 @@ body{ | |||||||
|     height: 3rem; |     height: 3rem; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   .lg\:h-auto{ |  | ||||||
|     height: auto; |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   .lg\:w-9{ |   .lg\:w-9{ | ||||||
|     width: 2.25rem; |     width: 2.25rem; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | <<<<<<< HEAD | ||||||
|   .lg\:w-18{ |   .lg\:w-18{ | ||||||
|     width: 4.5rem; |     width: 4.5rem; | ||||||
|  | ======= | ||||||
|  |   .lg\:w-96{ | ||||||
|  |     width: 24rem; | ||||||
|  | >>>>>>> d1b81891f887f0ababe1c40221defa5b69162795 | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   .lg\:w-1\/2{ |   .lg\:w-1\/2{ | ||||||
| @@ -51972,10 +51989,6 @@ body{ | |||||||
|     width: 1rem; |     width: 1rem; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   .lg\:w-96{ |  | ||||||
|     width: 24rem; |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   .lg\:w-2\/4{ |   .lg\:w-2\/4{ | ||||||
|     width: 50%; |     width: 50%; | ||||||
|   } |   } | ||||||
| @@ -52099,6 +52112,26 @@ body{ | |||||||
|     border-right-width: 1px; |     border-right-width: 1px; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   .lg\:px-3{ | ||||||
|  |     padding-left: 0.75rem; | ||||||
|  |     padding-right: 0.75rem; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .lg\:px-4{ | ||||||
|  |     padding-left: 1rem; | ||||||
|  |     padding-right: 1rem; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .lg\:px-6{ | ||||||
|  |     padding-left: 1.5rem; | ||||||
|  |     padding-right: 1.5rem; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .lg\:px-12{ | ||||||
|  |     padding-left: 3rem; | ||||||
|  |     padding-right: 3rem; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   .lg\:px-24{ |   .lg\:px-24{ | ||||||
|     padding-left: 6rem; |     padding-left: 6rem; | ||||||
|     padding-right: 6rem; |     padding-right: 6rem; | ||||||
| @@ -52109,11 +52142,6 @@ body{ | |||||||
|     padding-bottom: 0px; |     padding-bottom: 0px; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   .lg\:px-12{ |  | ||||||
|     padding-left: 3rem; |  | ||||||
|     padding-right: 3rem; |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   .lg\:pl-24{ |   .lg\:pl-24{ | ||||||
|     padding-left: 6rem; |     padding-left: 6rem; | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -189,9 +189,11 @@ export default { | |||||||
|             let el = this.$refs.dropdownMenu; |             let el = this.$refs.dropdownMenu; | ||||||
|             let target = event.target; |             let target = event.target; | ||||||
|  |  | ||||||
|  |             if (typeof el != "undefined") { | ||||||
|                 if (el !== target && ! el.contains(target)) { |                 if (el !== target && ! el.contains(target)) { | ||||||
|                     this.isOpen = false; |                     this.isOpen = false; | ||||||
|                 } |                 } | ||||||
|  |             } | ||||||
|         }, |         }, | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|   | |||||||
| @@ -53,12 +53,10 @@ | |||||||
|                     </div> |                     </div> | ||||||
|                 </div> |                 </div> | ||||||
|             </div>   |             </div>   | ||||||
|  |  | ||||||
|             <div v-else class="document-contact-with-contact-bill-to"> |             <div v-else class="document-contact-with-contact-bill-to"> | ||||||
|                 <div> |                 <div> | ||||||
|                     <span class="text-sm">{{ contactInfoText }}</span> |                     <span class="text-sm">{{ contactInfoText }}</span> | ||||||
|                 </div>   |                 </div>   | ||||||
|  |  | ||||||
|                 <div class="overflow-x-visible mt-0"> |                 <div class="overflow-x-visible mt-0"> | ||||||
|                     <table class="table table-borderless p-0"> |                     <table class="table table-borderless p-0"> | ||||||
|                         <tbody> |                         <tbody> | ||||||
| @@ -95,8 +93,8 @@ | |||||||
|                         </tbody> |                         </tbody> | ||||||
|                     </table> |                     </table> | ||||||
|                 </div> |                 </div> | ||||||
|  |             </div>   | ||||||
|                 <div class="absolute flex flex-col mt-2"> |             <div :class="show.contact_selected ? 'flex' : 'hidden'" class="absolute flex-col mt-2"> | ||||||
|                 <button type="button" class="p-0 text-xs text-purple ltr:text-left rtl:text-right" @click="onContactEdit"> |                 <button type="button" class="p-0 text-xs text-purple ltr:text-left rtl:text-right" @click="onContactEdit"> | ||||||
|                     <span class="bg-no-repeat bg-0-2 bg-0-full hover:bg-full-2 bg-gradient-to-b from-transparent to-purple transition-backgroundSize"> |                     <span class="bg-no-repeat bg-0-2 bg-0-full hover:bg-full-2 bg-gradient-to-b from-transparent to-purple transition-backgroundSize"> | ||||||
|                         {{ editContactText.replace(':contact_name', contact.name).replace(':field', contact.name) }} |                         {{ editContactText.replace(':contact_name', contact.name).replace(':field', contact.name) }} | ||||||
| @@ -108,8 +106,6 @@ | |||||||
|                     </span> |                     </span> | ||||||
|                 </button> |                 </button> | ||||||
|             </div>   |             </div>   | ||||||
|             </div> |  | ||||||
|  |  | ||||||
|             <component v-bind:is="add_new_html" @submit="onSubmit" @cancel="onCancel"></component> |             <component v-bind:is="add_new_html" @submit="onSubmit" @cancel="onCancel"></component> | ||||||
|         </div> |         </div> | ||||||
|     </div> |     </div> | ||||||
|   | |||||||
| @@ -304,7 +304,7 @@ export default { | |||||||
|         onInput(evt) { |         onInput(evt) { | ||||||
|             this.search = evt.target.value; |             this.search = evt.target.value; | ||||||
|              |              | ||||||
|             let option_url = this.selected_options[this.filter_index].url; |             let option_url = this.selected_options.length > 0 ? this.selected_options[this.filter_index].url : ''; | ||||||
|  |  | ||||||
|             if (this.search) { |             if (this.search) { | ||||||
|                 if (option_url.indexOf('?') === -1) { |                 if (option_url.indexOf('?') === -1) { | ||||||
| @@ -581,7 +581,7 @@ export default { | |||||||
|  |  | ||||||
|         onFilterDelete(index) { |         onFilterDelete(index) { | ||||||
|             this.show_icon = true; |             this.show_icon = true; | ||||||
|             this.show_close_icon = false; |  | ||||||
|             this.filter_list.push(this.selected_options[index]); |             this.filter_list.push(this.selected_options[index]); | ||||||
|  |  | ||||||
|             if (this.filter_last_step == 'options') { |             if (this.filter_last_step == 'options') { | ||||||
| @@ -598,8 +598,10 @@ export default { | |||||||
|              |              | ||||||
|             if (this.filter_index == 0) { |             if (this.filter_index == 0) { | ||||||
|                 this.onChangeSearchAndFilterText(this.defaultPlaceholder, true); |                 this.onChangeSearchAndFilterText(this.defaultPlaceholder, true); | ||||||
|  |                 this.show_close_icon = false; | ||||||
|             } else { |             } else { | ||||||
|                 this.show_icon = false; |                 this.show_icon = false; | ||||||
|  |                 this.show_close_icon = true; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             this.filter_last_step = 'options'; |             this.filter_last_step = 'options'; | ||||||
| @@ -790,6 +792,10 @@ export default { | |||||||
|         if (this.filter_index > 0) { |         if (this.filter_index > 0) { | ||||||
|             this.onChangeSearchAndFilterText(this.enterPlaceholder, false); |             this.onChangeSearchAndFilterText(this.enterPlaceholder, false); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         if (this.selected_values.length > 0) { | ||||||
|  |             this.show_close_icon = true; | ||||||
|  |         } | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     computed: { |     computed: { | ||||||
|   | |||||||
| @@ -875,7 +875,7 @@ export default { | |||||||
|                 if (this.multiple) { |                 if (this.multiple) { | ||||||
|                     this.selected = []; |                     this.selected = []; | ||||||
|                 } else { |                 } else { | ||||||
|                     this.selected = null; |                     this.selected = ''; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 return; |                 return; | ||||||
| @@ -892,7 +892,7 @@ export default { | |||||||
|                 }, this); |                 }, this); | ||||||
|             } else { |             } else { | ||||||
|                 if (! options.find((option) => option == this.selected)) { |                 if (! options.find((option) => option == this.selected)) { | ||||||
|                     this.selected = null; |                     this.selected = ''; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -1094,7 +1094,7 @@ export default { | |||||||
|             if (this.multiple) { |             if (this.multiple) { | ||||||
|                 this.selected = []; |                 this.selected = []; | ||||||
|             } else { |             } else { | ||||||
|                 this.selected = null; |                 this.selected = ''; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             return; |             return; | ||||||
| @@ -1111,7 +1111,7 @@ export default { | |||||||
|             }, this); |             }, this); | ||||||
|         } else { |         } else { | ||||||
|             if (! options.find((option) => option == this.selected)) { |             if (! options.find((option) => option == this.selected)) { | ||||||
|                 this.selected = null; |                 this.selected = ''; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
|   | |||||||
							
								
								
									
										393
									
								
								resources/assets/js/mixins/global.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										393
									
								
								resources/assets/js/mixins/global.js
									
									
									
									
										vendored
									
									
								
							| @@ -229,6 +229,9 @@ export default { | |||||||
|         // Bulk Action modal cancel |         // Bulk Action modal cancel | ||||||
|         onCancelBulkAction() { |         onCancelBulkAction() { | ||||||
|             this.bulk_action.modal = false; |             this.bulk_action.modal = false; | ||||||
|  |  | ||||||
|  |             let documentClasses = document.body.classList; | ||||||
|  |             documentClasses.remove('overflow-y-hidden', 'overflow-overlay', '-ml-4'); | ||||||
|         }, |         }, | ||||||
|  |  | ||||||
|         // Bulk Action Clear selected items |         // Bulk Action Clear selected items | ||||||
| @@ -583,6 +586,396 @@ export default { | |||||||
|             this.onChangeCurrency(currency_code); |             this.onChangeCurrency(currency_code); | ||||||
|         }, |         }, | ||||||
|  |  | ||||||
|  |         async onAddPayment(url) { | ||||||
|  |             let payment = { | ||||||
|  |                 modal: false, | ||||||
|  |                 url: url, | ||||||
|  |                 title: '', | ||||||
|  |                 html: '', | ||||||
|  |                 buttons:{} | ||||||
|  |             }; | ||||||
|  |  | ||||||
|  |             let payment_promise = Promise.resolve(window.axios.get(payment.url)); | ||||||
|  |  | ||||||
|  |             payment_promise.then(response => { | ||||||
|  |                 payment.modal = true; | ||||||
|  |                 payment.title = response.data.data.title; | ||||||
|  |                 payment.html = response.data.html; | ||||||
|  |                 payment.buttons = response.data.data.buttons; | ||||||
|  |  | ||||||
|  |                 this.component = Vue.component('add-new-component', (resolve, reject) => { | ||||||
|  |                     resolve({ | ||||||
|  |                         template: '<div id="dynamic-payment-component"><akaunting-modal-add-new modal-dialog-class="max-w-md" modal-position-top :show="payment.modal" @submit="onSubmit" @cancel="onCancel" :buttons="payment.buttons" :title="payment.title" :is_component=true :message="payment.html"></akaunting-modal-add-new></div>', | ||||||
|  |  | ||||||
|  |                         components: { | ||||||
|  |                             AkauntingDropzoneFileUpload, | ||||||
|  |                             AkauntingContactCard, | ||||||
|  |                             AkauntingCompanyEdit, | ||||||
|  |                             AkauntingEditItemColumns, | ||||||
|  |                             AkauntingItemButton, | ||||||
|  |                             AkauntingDocumentButton, | ||||||
|  |                             AkauntingSearch, | ||||||
|  |                             AkauntingRadioGroup, | ||||||
|  |                             AkauntingSelect, | ||||||
|  |                             AkauntingSelectRemote, | ||||||
|  |                             AkauntingMoney, | ||||||
|  |                             AkauntingModal, | ||||||
|  |                             AkauntingModalAddNew, | ||||||
|  |                             AkauntingDate, | ||||||
|  |                             AkauntingRecurring, | ||||||
|  |                             AkauntingHtmlEditor, | ||||||
|  |                             AkauntingCountdown, | ||||||
|  |                             AkauntingCurrencyConversion, | ||||||
|  |                             AkauntingConnectTransactions, | ||||||
|  |                             AkauntingSwitch, | ||||||
|  |                             AkauntingSlider, | ||||||
|  |                             AkauntingColor, | ||||||
|  |                             CardForm, | ||||||
|  |                             [Select.name]: Select, | ||||||
|  |                             [Option.name]: Option, | ||||||
|  |                             [Steps.name]: Steps, | ||||||
|  |                             [Step.name]: Step, | ||||||
|  |                             [Button.name]: Button, | ||||||
|  |                             [Link.name]: Link, | ||||||
|  |                             [Tooltip.name]: Tooltip, | ||||||
|  |                             [ColorPicker.name]: ColorPicker, | ||||||
|  |                         }, | ||||||
|  |  | ||||||
|  |                         data: function () { | ||||||
|  |                             return { | ||||||
|  |                                 form:{}, | ||||||
|  |                                 payment: payment, | ||||||
|  |                             } | ||||||
|  |                         }, | ||||||
|  |  | ||||||
|  |                         methods: { | ||||||
|  |                             onSubmit(event) { | ||||||
|  |                                 this.form = event; | ||||||
|  |  | ||||||
|  |                                 this.form.response = {}; | ||||||
|  |  | ||||||
|  |                                 this.loading = true; | ||||||
|  |  | ||||||
|  |                                 let data = this.form.data(); | ||||||
|  |  | ||||||
|  |                                 FormData.prototype.appendRecursive = function(data, wrapper = null) { | ||||||
|  |                                     for(var name in data) { | ||||||
|  |                                         if (wrapper) { | ||||||
|  |                                             if ((typeof data[name] == 'object' || data[name].constructor === Array) && ((data[name] instanceof File != true ) && (data[name] instanceof Blob != true))) { | ||||||
|  |                                                 this.appendRecursive(data[name], wrapper + '[' + name + ']'); | ||||||
|  |                                             } else { | ||||||
|  |                                                 this.append(wrapper + '[' + name + ']', data[name]); | ||||||
|  |                                             } | ||||||
|  |                                         } else { | ||||||
|  |                                             if ((typeof data[name] == 'object' || data[name].constructor === Array) && ((data[name] instanceof File != true ) && (data[name] instanceof Blob != true))) { | ||||||
|  |                                                 this.appendRecursive(data[name], name); | ||||||
|  |                                             } else { | ||||||
|  |                                                 this.append(name, data[name]); | ||||||
|  |                                             } | ||||||
|  |                                         } | ||||||
|  |                                     } | ||||||
|  |                                 }; | ||||||
|  |  | ||||||
|  |                                 let form_data = new FormData(); | ||||||
|  |                                 form_data.appendRecursive(data); | ||||||
|  |  | ||||||
|  |                                 window.axios({ | ||||||
|  |                                     method: this.form.method, | ||||||
|  |                                     url: this.form.action, | ||||||
|  |                                     data: form_data, | ||||||
|  |                                     headers: { | ||||||
|  |                                         'X-CSRF-TOKEN': window.Laravel.csrfToken, | ||||||
|  |                                         'X-Requested-With': 'XMLHttpRequest', | ||||||
|  |                                         'Content-Type': 'multipart/form-data' | ||||||
|  |                                     } | ||||||
|  |                                 }) | ||||||
|  |                                 .then(response => { | ||||||
|  |                                     if (response.data.success) { | ||||||
|  |                                         if (response.data.redirect) { | ||||||
|  |                                             this.form.loading = true; | ||||||
|  |  | ||||||
|  |                                             window.location.href = response.data.redirect; | ||||||
|  |                                         } | ||||||
|  |                                     } | ||||||
|  |  | ||||||
|  |                                     if (response.data.error) { | ||||||
|  |                                         this.form.loading = false; | ||||||
|  |  | ||||||
|  |                                         this.form.response = response.data; | ||||||
|  |                                     } | ||||||
|  |                                 }) | ||||||
|  |                                 .catch(error => { | ||||||
|  |                                     this.form.loading = false; | ||||||
|  |  | ||||||
|  |                                     this.form.onFail(error); | ||||||
|  |  | ||||||
|  |                                     this.method_show_html = error.message; | ||||||
|  |                                 }); | ||||||
|  |                             }, | ||||||
|  |  | ||||||
|  |                             onCancel() { | ||||||
|  |                                 this.payment.modal = false; | ||||||
|  |                                 this.payment.html = null; | ||||||
|  |  | ||||||
|  |                                 let documentClasses = document.body.classList; | ||||||
|  |  | ||||||
|  |                                 documentClasses.remove('overflow-y-hidden', 'overflow-overlay', '-ml-4'); | ||||||
|  |                             }, | ||||||
|  |                         } | ||||||
|  |                     }) | ||||||
|  |                 }); | ||||||
|  |             }) | ||||||
|  |             .catch(error => { | ||||||
|  |             }) | ||||||
|  |             .finally(function () { | ||||||
|  |                 // always executed | ||||||
|  |             }); | ||||||
|  |         }, | ||||||
|  |  | ||||||
|  |         async onEditPayment(url) { | ||||||
|  |             let payment = { | ||||||
|  |                 modal: false, | ||||||
|  |                 url: url, | ||||||
|  |                 title: '', | ||||||
|  |                 html: '', | ||||||
|  |                 buttons:{} | ||||||
|  |             }; | ||||||
|  |  | ||||||
|  |             let payment_promise = Promise.resolve(window.axios.get(payment.url)); | ||||||
|  |  | ||||||
|  |             payment_promise.then(response => { | ||||||
|  |                 payment.modal = true; | ||||||
|  |                 payment.title = response.data.data.title; | ||||||
|  |                 payment.html = response.data.html; | ||||||
|  |                 payment.buttons = response.data.data.buttons; | ||||||
|  |  | ||||||
|  |                 this.component = Vue.component('add-new-component', (resolve, reject) => { | ||||||
|  |                     resolve({ | ||||||
|  |                         template: '<div id="dynamic-payment-component"><akaunting-modal-add-new modal-dialog-class="max-w-md" modal-position-top :show="payment.modal" @submit="onSubmit" @cancel="onCancel" :buttons="payment.buttons" :title="payment.title" :is_component=true :message="payment.html"></akaunting-modal-add-new></div>', | ||||||
|  |  | ||||||
|  |                         components: { | ||||||
|  |                             AkauntingDropzoneFileUpload, | ||||||
|  |                             AkauntingContactCard, | ||||||
|  |                             AkauntingCompanyEdit, | ||||||
|  |                             AkauntingEditItemColumns, | ||||||
|  |                             AkauntingItemButton, | ||||||
|  |                             AkauntingDocumentButton, | ||||||
|  |                             AkauntingSearch, | ||||||
|  |                             AkauntingRadioGroup, | ||||||
|  |                             AkauntingSelect, | ||||||
|  |                             AkauntingSelectRemote, | ||||||
|  |                             AkauntingMoney, | ||||||
|  |                             AkauntingModal, | ||||||
|  |                             AkauntingModalAddNew, | ||||||
|  |                             AkauntingDate, | ||||||
|  |                             AkauntingRecurring, | ||||||
|  |                             AkauntingHtmlEditor, | ||||||
|  |                             AkauntingCountdown, | ||||||
|  |                             AkauntingCurrencyConversion, | ||||||
|  |                             AkauntingConnectTransactions, | ||||||
|  |                             AkauntingSwitch, | ||||||
|  |                             AkauntingSlider, | ||||||
|  |                             AkauntingColor, | ||||||
|  |                             CardForm, | ||||||
|  |                             [Select.name]: Select, | ||||||
|  |                             [Option.name]: Option, | ||||||
|  |                             [Steps.name]: Steps, | ||||||
|  |                             [Step.name]: Step, | ||||||
|  |                             [Button.name]: Button, | ||||||
|  |                             [Link.name]: Link, | ||||||
|  |                             [Tooltip.name]: Tooltip, | ||||||
|  |                             [ColorPicker.name]: ColorPicker, | ||||||
|  |                         }, | ||||||
|  |  | ||||||
|  |                         data: function () { | ||||||
|  |                             return { | ||||||
|  |                                 form:{}, | ||||||
|  |                                 payment: payment, | ||||||
|  |                             } | ||||||
|  |                         }, | ||||||
|  |  | ||||||
|  |                         methods: { | ||||||
|  |                             onSubmit(event) { | ||||||
|  |                                 this.form = event; | ||||||
|  |  | ||||||
|  |                                 this.form.response = {}; | ||||||
|  |  | ||||||
|  |                                 this.loading = true; | ||||||
|  |  | ||||||
|  |                                 let data = this.form.data(); | ||||||
|  |  | ||||||
|  |                                 FormData.prototype.appendRecursive = function(data, wrapper = null) { | ||||||
|  |                                     for(var name in data) { | ||||||
|  |                                         if (wrapper) { | ||||||
|  |                                             if ((typeof data[name] == 'object' || data[name].constructor === Array) && ((data[name] instanceof File != true ) && (data[name] instanceof Blob != true))) { | ||||||
|  |                                                 this.appendRecursive(data[name], wrapper + '[' + name + ']'); | ||||||
|  |                                             } else { | ||||||
|  |                                                 this.append(wrapper + '[' + name + ']', data[name]); | ||||||
|  |                                             } | ||||||
|  |                                         } else { | ||||||
|  |                                             if ((typeof data[name] == 'object' || data[name].constructor === Array) && ((data[name] instanceof File != true ) && (data[name] instanceof Blob != true))) { | ||||||
|  |                                                 this.appendRecursive(data[name], name); | ||||||
|  |                                             } else { | ||||||
|  |                                                 this.append(name, data[name]); | ||||||
|  |                                             } | ||||||
|  |                                         } | ||||||
|  |                                     } | ||||||
|  |                                 }; | ||||||
|  |  | ||||||
|  |                                 let form_data = new FormData(); | ||||||
|  |                                 form_data.appendRecursive(data); | ||||||
|  |  | ||||||
|  |                                 window.axios({ | ||||||
|  |                                     method: this.form.method, | ||||||
|  |                                     url: this.form.action, | ||||||
|  |                                     data: form_data, | ||||||
|  |                                     headers: { | ||||||
|  |                                         'X-CSRF-TOKEN': window.Laravel.csrfToken, | ||||||
|  |                                         'X-Requested-With': 'XMLHttpRequest', | ||||||
|  |                                         'Content-Type': 'multipart/form-data' | ||||||
|  |                                     } | ||||||
|  |                                 }) | ||||||
|  |                                 .then(response => { | ||||||
|  |                                     if (response.data.success) { | ||||||
|  |                                         if (response.data.redirect) { | ||||||
|  |                                             this.form.loading = true; | ||||||
|  |  | ||||||
|  |                                             window.location.href = response.data.redirect; | ||||||
|  |                                         } | ||||||
|  |                                     } | ||||||
|  |  | ||||||
|  |                                     if (response.data.error) { | ||||||
|  |                                         this.form.loading = false; | ||||||
|  |  | ||||||
|  |                                         this.form.response = response.data; | ||||||
|  |                                     } | ||||||
|  |                                 }) | ||||||
|  |                                 .catch(error => { | ||||||
|  |                                     this.form.loading = false; | ||||||
|  |  | ||||||
|  |                                     this.form.onFail(error); | ||||||
|  |  | ||||||
|  |                                     this.method_show_html = error.message; | ||||||
|  |                                 }); | ||||||
|  |                             }, | ||||||
|  |  | ||||||
|  |                             onCancel() { | ||||||
|  |                                 this.payment.modal = false; | ||||||
|  |                                 this.payment.html = null; | ||||||
|  |  | ||||||
|  |                                 let documentClasses = document.body.classList; | ||||||
|  |  | ||||||
|  |                                 documentClasses.remove('overflow-y-hidden', 'overflow-overlay', '-ml-4'); | ||||||
|  |                             }, | ||||||
|  |                         } | ||||||
|  |                     }) | ||||||
|  |                 }); | ||||||
|  |             }) | ||||||
|  |             .catch(error => { | ||||||
|  |             }) | ||||||
|  |             .finally(function () { | ||||||
|  |                 // always executed | ||||||
|  |             }); | ||||||
|  |         }, | ||||||
|  |  | ||||||
|  |         async onSendEmail(url) { | ||||||
|  |             let email = { | ||||||
|  |                 modal: false, | ||||||
|  |                 url: url, | ||||||
|  |                 title: '', | ||||||
|  |                 html: '', | ||||||
|  |                 buttons:{} | ||||||
|  |             }; | ||||||
|  |  | ||||||
|  |             let email_promise = Promise.resolve(window.axios.get(email.url)); | ||||||
|  |  | ||||||
|  |             if (this.email_template) { | ||||||
|  |                 email_promise = Promise.resolve(window.axios.get(email.url, { | ||||||
|  |                     params: { | ||||||
|  |                         email_template: this.email_template | ||||||
|  |                     } | ||||||
|  |                 })); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             this.email_template = false; | ||||||
|  |  | ||||||
|  |             email_promise.then(response => { | ||||||
|  |                 email.modal = true; | ||||||
|  |                 email.title = response.data.data.title; | ||||||
|  |                 email.html = response.data.html; | ||||||
|  |                 email.buttons = response.data.data.buttons; | ||||||
|  |  | ||||||
|  |                 this.component = Vue.component('add-new-component', (resolve, reject) => { | ||||||
|  |                     resolve({ | ||||||
|  |                         template: '<div id="dynamic-email-component"><akaunting-modal-add-new modal-dialog-class="max-w-screen-md" :show="email.modal" @submit="onSubmit" @cancel="onCancel" :buttons="email.buttons" :title="email.title" :is_component=true :message="email.html"></akaunting-modal-add-new></div>', | ||||||
|  |  | ||||||
|  |                         components: { | ||||||
|  |                             AkauntingDropzoneFileUpload, | ||||||
|  |                             AkauntingContactCard, | ||||||
|  |                             AkauntingCompanyEdit, | ||||||
|  |                             AkauntingEditItemColumns, | ||||||
|  |                             AkauntingItemButton, | ||||||
|  |                             AkauntingDocumentButton, | ||||||
|  |                             AkauntingSearch, | ||||||
|  |                             AkauntingRadioGroup, | ||||||
|  |                             AkauntingSelect, | ||||||
|  |                             AkauntingSelectRemote, | ||||||
|  |                             AkauntingMoney, | ||||||
|  |                             AkauntingModal, | ||||||
|  |                             AkauntingModalAddNew, | ||||||
|  |                             AkauntingDate, | ||||||
|  |                             AkauntingRecurring, | ||||||
|  |                             AkauntingHtmlEditor, | ||||||
|  |                             AkauntingCountdown, | ||||||
|  |                             AkauntingCurrencyConversion, | ||||||
|  |                             AkauntingConnectTransactions, | ||||||
|  |                             AkauntingSwitch, | ||||||
|  |                             AkauntingSlider, | ||||||
|  |                             AkauntingColor, | ||||||
|  |                             CardForm, | ||||||
|  |                             [Select.name]: Select, | ||||||
|  |                             [Option.name]: Option, | ||||||
|  |                             [Steps.name]: Steps, | ||||||
|  |                             [Step.name]: Step, | ||||||
|  |                             [Button.name]: Button, | ||||||
|  |                             [Link.name]: Link, | ||||||
|  |                             [Tooltip.name]: Tooltip, | ||||||
|  |                             [ColorPicker.name]: ColorPicker, | ||||||
|  |                         }, | ||||||
|  |  | ||||||
|  |                         data: function () { | ||||||
|  |                             return { | ||||||
|  |                                 form:{}, | ||||||
|  |                                 email: email, | ||||||
|  |                             } | ||||||
|  |                         }, | ||||||
|  |  | ||||||
|  |                         methods: { | ||||||
|  |                             onSubmit(event) { | ||||||
|  |                                 this.$emit('submit', event); | ||||||
|  |  | ||||||
|  |                                 event.submit(); | ||||||
|  |                             }, | ||||||
|  |  | ||||||
|  |                             onCancel() { | ||||||
|  |                                 this.email.modal = false; | ||||||
|  |                                 this.email.html = null; | ||||||
|  |  | ||||||
|  |                                 let documentClasses = document.body.classList; | ||||||
|  |  | ||||||
|  |                                 documentClasses.remove('overflow-y-hidden', 'overflow-overlay', '-ml-4'); | ||||||
|  |                             }, | ||||||
|  |                         } | ||||||
|  |                     }) | ||||||
|  |                 }); | ||||||
|  |             }) | ||||||
|  |             .catch(error => { | ||||||
|  |             }) | ||||||
|  |             .finally(function () { | ||||||
|  |                 // always executed | ||||||
|  |             }); | ||||||
|  |         }, | ||||||
|  |  | ||||||
|         onShareLink(url) { |         onShareLink(url) { | ||||||
|             let share = { |             let share = { | ||||||
|                 modal: false, |                 modal: false, | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								resources/assets/js/plugins/form.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								resources/assets/js/plugins/form.js
									
									
									
									
										vendored
									
									
								
							| @@ -493,7 +493,9 @@ export default class Form { | |||||||
|  |  | ||||||
|     // Form fields check validation issue |     // Form fields check validation issue | ||||||
|     onFail(error) { |     onFail(error) { | ||||||
|  |         if (typeof this.errors != "undefined") { | ||||||
|             this.errors.record(error.response.data.errors); |             this.errors.record(error.response.data.errors); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         this.loading = false; |         this.loading = false; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -33,62 +33,6 @@ const app = new Vue({ | |||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     methods: { |     methods: { | ||||||
|         async onEmail(route) { |         // | ||||||
|             let email = { |  | ||||||
|                 modal: false, |  | ||||||
|                 route: route, |  | ||||||
|                 title: '', |  | ||||||
|                 html: '', |  | ||||||
|                 buttons:{} |  | ||||||
|             }; |  | ||||||
|  |  | ||||||
|             let email_promise = Promise.resolve(window.axios.get(email.route)); |  | ||||||
|  |  | ||||||
|             email_promise.then(response => { |  | ||||||
|                 email.modal = true; |  | ||||||
|                 email.title = response.data.data.title; |  | ||||||
|                 email.html = response.data.html; |  | ||||||
|                 email.buttons = response.data.data.buttons; |  | ||||||
|  |  | ||||||
|                 this.component = Vue.component('add-new-component', (resolve, reject) => { |  | ||||||
|                     resolve({ |  | ||||||
|                         template: '<div id="dynamic-email-component"><akaunting-modal-add-new modal-dialog-class="max-w-md" :show="email.modal" @submit="onSubmit" @cancel="onCancel" :buttons="email.buttons" :title="email.title" :is_component=true :message="email.html"></akaunting-modal-add-new></div>', |  | ||||||
|  |  | ||||||
|                         mixins: [ |  | ||||||
|                             Global |  | ||||||
|                         ], |  | ||||||
|  |  | ||||||
|                         data: function () { |  | ||||||
|                             return { |  | ||||||
|                                 form:{}, |  | ||||||
|                                 email: email, |  | ||||||
|                             } |  | ||||||
|                         }, |  | ||||||
|  |  | ||||||
|                         methods: { |  | ||||||
|                             onSubmit(event) { |  | ||||||
|                                 this.$emit('submit', event); |  | ||||||
|  |  | ||||||
|                                 event.submit(); |  | ||||||
|                             }, |  | ||||||
|  |  | ||||||
|                             onCancel() { |  | ||||||
|                                 this.email.modal = false; |  | ||||||
|                                 this.email.html = null; |  | ||||||
|  |  | ||||||
|                                 let documentClasses = document.body.classList; |  | ||||||
|  |  | ||||||
|                                 documentClasses.remove('overflow-y-hidden', 'overflow-overlay', '-ml-4'); |  | ||||||
|                             }, |  | ||||||
|                         } |  | ||||||
|                     }) |  | ||||||
|                 }); |  | ||||||
|             }) |  | ||||||
|             .catch(error => { |  | ||||||
|             }) |  | ||||||
|             .finally(function () { |  | ||||||
|                 // always executed |  | ||||||
|             }); |  | ||||||
|         }, |  | ||||||
|     }, |     }, | ||||||
| }); | }); | ||||||
|   | |||||||
							
								
								
									
										309
									
								
								resources/assets/js/views/common/documents.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										309
									
								
								resources/assets/js/views/common/documents.js
									
									
									
									
										vendored
									
									
								
							| @@ -589,315 +589,10 @@ const app = new Vue({ | |||||||
|             this.form.items[item_index][field_name] = this.items[item_index][field_name]; |             this.form.items[item_index][field_name] = this.items[item_index][field_name]; | ||||||
|         }, |         }, | ||||||
|  |  | ||||||
|         async onPayment(document_id) { |  | ||||||
|             if (typeof  document_id == 'object') { |  | ||||||
|                 document_id = document.getElementById('document_id').value; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             let payment = { |  | ||||||
|                 modal: false, |  | ||||||
|                 url: url + '/modals/documents/' + document_id + '/transactions/create', |  | ||||||
|                 title: '', |  | ||||||
|                 html: '', |  | ||||||
|                 buttons:{} |  | ||||||
|             }; |  | ||||||
|  |  | ||||||
|             let payment_promise = Promise.resolve(window.axios.get(payment.url)); |  | ||||||
|  |  | ||||||
|             payment_promise.then(response => { |  | ||||||
|                 payment.modal = true; |  | ||||||
|                 payment.title = response.data.data.title; |  | ||||||
|                 payment.html = response.data.html; |  | ||||||
|                 payment.buttons = response.data.data.buttons; |  | ||||||
|  |  | ||||||
|                 this.component = Vue.component('add-new-component', (resolve, reject) => { |  | ||||||
|                     resolve({ |  | ||||||
|                         template: '<div id="dynamic-payment-component"><akaunting-modal-add-new modal-dialog-class="max-w-md" modal-position-top :show="payment.modal" @submit="onSubmit" @cancel="onCancel" :buttons="payment.buttons" :title="payment.title" :is_component=true :message="payment.html"></akaunting-modal-add-new></div>', |  | ||||||
|  |  | ||||||
|                         mixins: [ |  | ||||||
|                             Global |  | ||||||
|                         ], |  | ||||||
|  |  | ||||||
|                         data: function () { |  | ||||||
|                             return { |  | ||||||
|                                 form:{}, |  | ||||||
|                                 payment: payment, |  | ||||||
|                             } |  | ||||||
|                         }, |  | ||||||
|  |  | ||||||
|                         methods: { |  | ||||||
|                             onSubmit(event) { |  | ||||||
|                                 this.form = event; |  | ||||||
|  |  | ||||||
|                                 this.form.response = {}; |  | ||||||
|  |  | ||||||
|                                 this.loading = true; |  | ||||||
|  |  | ||||||
|                                 let data = this.form.data(); |  | ||||||
|  |  | ||||||
|                                 FormData.prototype.appendRecursive = function(data, wrapper = null) { |  | ||||||
|                                     for(var name in data) { |  | ||||||
|                                         if (wrapper) { |  | ||||||
|                                             if ((typeof data[name] == 'object' || data[name].constructor === Array) && ((data[name] instanceof File != true ) && (data[name] instanceof Blob != true))) { |  | ||||||
|                                                 this.appendRecursive(data[name], wrapper + '[' + name + ']'); |  | ||||||
|                                             } else { |  | ||||||
|                                                 this.append(wrapper + '[' + name + ']', data[name]); |  | ||||||
|                                             } |  | ||||||
|                                         } else { |  | ||||||
|                                             if ((typeof data[name] == 'object' || data[name].constructor === Array) && ((data[name] instanceof File != true ) && (data[name] instanceof Blob != true))) { |  | ||||||
|                                                 this.appendRecursive(data[name], name); |  | ||||||
|                                             } else { |  | ||||||
|                                                 this.append(name, data[name]); |  | ||||||
|                                             } |  | ||||||
|                                         } |  | ||||||
|                                     } |  | ||||||
|                                 }; |  | ||||||
|  |  | ||||||
|                                 let form_data = new FormData(); |  | ||||||
|                                 form_data.appendRecursive(data); |  | ||||||
|  |  | ||||||
|                                 window.axios({ |  | ||||||
|                                     method: this.form.method, |  | ||||||
|                                     url: this.form.action, |  | ||||||
|                                     data: form_data, |  | ||||||
|                                     headers: { |  | ||||||
|                                         'X-CSRF-TOKEN': window.Laravel.csrfToken, |  | ||||||
|                                         'X-Requested-With': 'XMLHttpRequest', |  | ||||||
|                                         'Content-Type': 'multipart/form-data' |  | ||||||
|                                     } |  | ||||||
|                                 }) |  | ||||||
|                                 .then(response => { |  | ||||||
|                                     if (response.data.success) { |  | ||||||
|                                         if (response.data.redirect) { |  | ||||||
|                                             this.form.loading = true; |  | ||||||
|  |  | ||||||
|                                             window.location.href = response.data.redirect; |  | ||||||
|                                         } |  | ||||||
|                                     } |  | ||||||
|  |  | ||||||
|                                     if (response.data.error) { |  | ||||||
|                                         this.form.loading = false; |  | ||||||
|  |  | ||||||
|                                         this.form.response = response.data; |  | ||||||
|                                     } |  | ||||||
|                                 }) |  | ||||||
|                                 .catch(error => { |  | ||||||
|                                     this.form.loading = false; |  | ||||||
|  |  | ||||||
|                                     this.form.onFail(error); |  | ||||||
|  |  | ||||||
|                                     this.method_show_html = error.message; |  | ||||||
|                                 }); |  | ||||||
|                             }, |  | ||||||
|  |  | ||||||
|                             onCancel() { |  | ||||||
|                                 this.payment.modal = false; |  | ||||||
|                                 this.payment.html = null; |  | ||||||
|  |  | ||||||
|                                 let documentClasses = document.body.classList; |  | ||||||
|  |  | ||||||
|                                 documentClasses.remove('overflow-y-hidden', 'overflow-overlay', '-ml-4'); |  | ||||||
|                             }, |  | ||||||
|                         } |  | ||||||
|                     }) |  | ||||||
|                 }); |  | ||||||
|             }) |  | ||||||
|             .catch(error => { |  | ||||||
|             }) |  | ||||||
|             .finally(function () { |  | ||||||
|                 // always executed |  | ||||||
|             }); |  | ||||||
|         }, |  | ||||||
|  |  | ||||||
|         async onEditPayment(transaction_id) { |  | ||||||
|             let document_id = document.getElementById('document_id').value; |  | ||||||
|  |  | ||||||
|             let payment = { |  | ||||||
|                 modal: false, |  | ||||||
|                 url: url + '/modals/documents/' + document_id + '/transactions/' + transaction_id + '/edit', |  | ||||||
|                 title: '', |  | ||||||
|                 html: '', |  | ||||||
|                 buttons:{} |  | ||||||
|             }; |  | ||||||
|  |  | ||||||
|             let payment_promise = Promise.resolve(window.axios.get(payment.url)); |  | ||||||
|  |  | ||||||
|             payment_promise.then(response => { |  | ||||||
|                 payment.modal = true; |  | ||||||
|                 payment.title = response.data.data.title; |  | ||||||
|                 payment.html = response.data.html; |  | ||||||
|                 payment.buttons = response.data.data.buttons; |  | ||||||
|  |  | ||||||
|                 this.component = Vue.component('add-new-component', (resolve, reject) => { |  | ||||||
|                     resolve({ |  | ||||||
|                         template: '<div id="dynamic-payment-component"><akaunting-modal-add-new modal-dialog-class="max-w-md" modal-position-top :show="payment.modal" @submit="onSubmit" @cancel="onCancel" :buttons="payment.buttons" :title="payment.title" :is_component=true :message="payment.html"></akaunting-modal-add-new></div>', |  | ||||||
|  |  | ||||||
|                         mixins: [ |  | ||||||
|                             Global |  | ||||||
|                         ], |  | ||||||
|  |  | ||||||
|                         data: function () { |  | ||||||
|                             return { |  | ||||||
|                                 form:{}, |  | ||||||
|                                 payment: payment, |  | ||||||
|                             } |  | ||||||
|                         }, |  | ||||||
|  |  | ||||||
|                         methods: { |  | ||||||
|                             onSubmit(event) { |  | ||||||
|                                 this.form = event; |  | ||||||
|  |  | ||||||
|                                 this.form.response = {}; |  | ||||||
|  |  | ||||||
|                                 this.loading = true; |  | ||||||
|  |  | ||||||
|                                 let data = this.form.data(); |  | ||||||
|  |  | ||||||
|                                 FormData.prototype.appendRecursive = function(data, wrapper = null) { |  | ||||||
|                                     for(var name in data) { |  | ||||||
|                                         if (wrapper) { |  | ||||||
|                                             if ((typeof data[name] == 'object' || data[name].constructor === Array) && ((data[name] instanceof File != true ) && (data[name] instanceof Blob != true))) { |  | ||||||
|                                                 this.appendRecursive(data[name], wrapper + '[' + name + ']'); |  | ||||||
|                                             } else { |  | ||||||
|                                                 this.append(wrapper + '[' + name + ']', data[name]); |  | ||||||
|                                             } |  | ||||||
|                                         } else { |  | ||||||
|                                             if ((typeof data[name] == 'object' || data[name].constructor === Array) && ((data[name] instanceof File != true ) && (data[name] instanceof Blob != true))) { |  | ||||||
|                                                 this.appendRecursive(data[name], name); |  | ||||||
|                                             } else { |  | ||||||
|                                                 this.append(name, data[name]); |  | ||||||
|                                             } |  | ||||||
|                                         } |  | ||||||
|                                     } |  | ||||||
|                                 }; |  | ||||||
|  |  | ||||||
|                                 let form_data = new FormData(); |  | ||||||
|                                 form_data.appendRecursive(data); |  | ||||||
|  |  | ||||||
|                                 window.axios({ |  | ||||||
|                                     method: this.form.method, |  | ||||||
|                                     url: this.form.action, |  | ||||||
|                                     data: form_data, |  | ||||||
|                                     headers: { |  | ||||||
|                                         'X-CSRF-TOKEN': window.Laravel.csrfToken, |  | ||||||
|                                         'X-Requested-With': 'XMLHttpRequest', |  | ||||||
|                                         'Content-Type': 'multipart/form-data' |  | ||||||
|                                     } |  | ||||||
|                                 }) |  | ||||||
|                                 .then(response => { |  | ||||||
|                                     if (response.data.success) { |  | ||||||
|                                         if (response.data.redirect) { |  | ||||||
|                                             this.form.loading = true; |  | ||||||
|  |  | ||||||
|                                             window.location.href = response.data.redirect; |  | ||||||
|                                         } |  | ||||||
|                                     } |  | ||||||
|  |  | ||||||
|                                     if (response.data.error) { |  | ||||||
|                                         this.form.loading = false; |  | ||||||
|  |  | ||||||
|                                         this.form.response = response.data; |  | ||||||
|                                     } |  | ||||||
|                                 }) |  | ||||||
|                                 .catch(error => { |  | ||||||
|                                     this.form.loading = false; |  | ||||||
|  |  | ||||||
|                                     this.form.onFail(error); |  | ||||||
|  |  | ||||||
|                                     this.method_show_html = error.message; |  | ||||||
|                                 }); |  | ||||||
|                             }, |  | ||||||
|  |  | ||||||
|                             onCancel() { |  | ||||||
|                                 this.payment.modal = false; |  | ||||||
|                                 this.payment.html = null; |  | ||||||
|  |  | ||||||
|                                 let documentClasses = document.body.classList; |  | ||||||
|  |  | ||||||
|                                 documentClasses.remove('overflow-y-hidden', 'overflow-overlay', '-ml-4'); |  | ||||||
|                             }, |  | ||||||
|                         } |  | ||||||
|                     }) |  | ||||||
|                 }); |  | ||||||
|             }) |  | ||||||
|             .catch(error => { |  | ||||||
|             }) |  | ||||||
|             .finally(function () { |  | ||||||
|                 // always executed |  | ||||||
|             }); |  | ||||||
|         }, |  | ||||||
|  |  | ||||||
|         async onEmail(route) { |  | ||||||
|             let email = { |  | ||||||
|                 modal: false, |  | ||||||
|                 route: route, |  | ||||||
|                 title: '', |  | ||||||
|                 html: '', |  | ||||||
|                 buttons:{} |  | ||||||
|             }; |  | ||||||
|  |  | ||||||
|             let email_promise = Promise.resolve(window.axios.get(email.route)); |  | ||||||
|  |  | ||||||
|             if (this.email_template) { |  | ||||||
|                 email_promise = Promise.resolve(window.axios.get(email.route, { |  | ||||||
|                     params: { |  | ||||||
|                         email_template: this.email_template |  | ||||||
|                     } |  | ||||||
|                 })); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             this.email_template = false; |  | ||||||
|  |  | ||||||
|             email_promise.then(response => { |  | ||||||
|                 email.modal = true; |  | ||||||
|                 email.title = response.data.data.title; |  | ||||||
|                 email.html = response.data.html; |  | ||||||
|                 email.buttons = response.data.data.buttons; |  | ||||||
|  |  | ||||||
|                 this.component = Vue.component('add-new-component', (resolve, reject) => { |  | ||||||
|                     resolve({ |  | ||||||
|                         template: '<div id="dynamic-email-component"><akaunting-modal-add-new modal-dialog-class="max-w-md" :show="email.modal" @submit="onSubmit" @cancel="onCancel" :buttons="email.buttons" :title="email.title" :is_component=true :message="email.html"></akaunting-modal-add-new></div>', |  | ||||||
|  |  | ||||||
|                         mixins: [ |  | ||||||
|                             Global |  | ||||||
|                         ], |  | ||||||
|  |  | ||||||
|                         data: function () { |  | ||||||
|                             return { |  | ||||||
|                                 form:{}, |  | ||||||
|                                 email: email, |  | ||||||
|                             } |  | ||||||
|                         }, |  | ||||||
|  |  | ||||||
|                         methods: { |  | ||||||
|                             onSubmit(event) { |  | ||||||
|                                 this.$emit('submit', event); |  | ||||||
|                                 event.submit(); |  | ||||||
|                             }, |  | ||||||
|  |  | ||||||
|                             onCancel() { |  | ||||||
|                                 this.email.modal = false; |  | ||||||
|                                 this.email.html = null; |  | ||||||
|  |  | ||||||
|                                 let documentClasses = document.body.classList; |  | ||||||
|  |  | ||||||
|                                 documentClasses.remove('overflow-y-hidden', 'overflow-overlay', '-ml-4'); |  | ||||||
|                             }, |  | ||||||
|                         } |  | ||||||
|                     }) |  | ||||||
|                 }); |  | ||||||
|             }) |  | ||||||
|             .catch(error => { |  | ||||||
|             }) |  | ||||||
|             .finally(function () { |  | ||||||
|                 // always executed |  | ||||||
|             }); |  | ||||||
|         }, |  | ||||||
|  |  | ||||||
|         onEmailViaTemplate(route, template) { |         onEmailViaTemplate(route, template) { | ||||||
|             this.email_template = template; |             this.email_template = template; | ||||||
|  |  | ||||||
|             this.onEmail(route); |             this.onSendEmail(route); | ||||||
|         }, |         }, | ||||||
|  |  | ||||||
|         // Change currency get money |         // Change currency get money | ||||||
| @@ -1108,7 +803,7 @@ const app = new Vue({ | |||||||
|  |  | ||||||
|             let email_route = document.getElementById('senddocument_route').value; |             let email_route = document.getElementById('senddocument_route').value; | ||||||
|  |  | ||||||
|             this.onEmail(email_route); |             this.onSendEmail(email_route); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         this.page_loaded = true; |         this.page_loaded = true; | ||||||
|   | |||||||
| @@ -24,7 +24,7 @@ return [ | |||||||
|         'create_recurring'  => ':user created this recurring template on :date', |         'create_recurring'  => ':user created this recurring template on :date', | ||||||
|         'schedule'          => 'Repeat every :interval :frequency since :date', |         'schedule'          => 'Repeat every :interval :frequency since :date', | ||||||
|         'children'          => ':count transactions were created automatically', |         'children'          => ':count transactions were created automatically', | ||||||
|         'transfer_headline' => 'From :from_account to :to_account', |         'transfer_headline' => '<div> <span class="font-bold"> From: </span> :from_account </div> <div> <span class="font-bold"> to: </span> :to_account </div>', | ||||||
|         'transfer_desc'     => 'Transfer created on :date.', |         'transfer_desc'     => 'Transfer created on :date.', | ||||||
|     ], |     ], | ||||||
|  |  | ||||||
|   | |||||||
| @@ -179,7 +179,7 @@ | |||||||
|     @endsection |     @endsection | ||||||
|  |  | ||||||
|     <x-slot name="content"> |     <x-slot name="content"> | ||||||
|         <div class="dashboard flex flex-wrap -mx-12"> |         <div class="dashboard flex flex-wrap lg:-mx-12"> | ||||||
|             @foreach($widgets as $widget) |             @foreach($widgets as $widget) | ||||||
|                 @widget($widget) |                 @widget($widget) | ||||||
|             @endforeach |             @endforeach | ||||||
|   | |||||||
| @@ -3,10 +3,10 @@ | |||||||
|         <div class="overflow-y-hidden py-6"> |         <div class="overflow-y-hidden py-6"> | ||||||
|             <table id="totals" class="float-right"> |             <table id="totals" class="float-right"> | ||||||
|                 <colgroup> |                 <colgroup> | ||||||
|                     <col style="width: 47.5%;"> |                     <col class="small-col" style="width: 47.5%;"> | ||||||
|                     <col style="width: 30%;"> |                     <col class="small-col" style="width: 30%;"> | ||||||
|                     <col style="width: 18%;"> |                     <col class="small-col" style="width: 18%;"> | ||||||
|                     <col style="width: 50px;"> |                     <col class="small-col" style="width: 50px;"> | ||||||
|                 </colgroup> |                 </colgroup> | ||||||
|  |  | ||||||
|                 <tbody id="invoice-total-rows"> |                 <tbody id="invoice-total-rows"> | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| <div id="{{ $id }}" role="tooltip" class="w-96 inline-block absolute left-0 z-10 text-sm font-medium rounded-lg border border-gray-200 shadow-sm whitespace-nowrap tooltip-content transition-visible bg-lilac-900 border-none text-black p-6 cursor-auto opacity-0 invisible information-content"> | <div id="{{ $id }}" role="tooltip" class="w-full lg:w-96 inline-block absolute left-0 z-10 text-sm font-medium rounded-lg border border-gray-200 shadow-sm whitespace-nowrap tooltip-content transition-visible bg-lilac-900 border-none text-black p-6 cursor-auto opacity-0 invisible information-content"> | ||||||
|     <div class="absolute w-2 h-2 inset-y-1/2 -right-1 before:content-[' '] before:absolute before:w-2 before:h-2 before:bg-lilac-900 before:border-gray-200 before:transform before:rotate-45 before:border before:border-t-0 before:border-l-0 data-popper-arrow"></div> |     <div class="absolute w-2 h-2 inset-y-1/2 -right-1 before:content-[' '] before:absolute before:w-2 before:h-2 before:bg-lilac-900 before:border-gray-200 before:transform before:rotate-45 before:border before:border-t-0 before:border-l-0 data-popper-arrow"></div> | ||||||
|  |  | ||||||
|     <ul> |     <ul> | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ | |||||||
|             @if (! $hideAddPayment) |             @if (! $hideAddPayment) | ||||||
|                 @if (empty($document->transactions->count()) || (! empty($document->transactions->count()) && $document->paid != $document->amount)) |                 @if (empty($document->transactions->count()) || (! empty($document->transactions->count()) && $document->paid != $document->amount)) | ||||||
|                     <x-button |                     <x-button | ||||||
|                         @click="onPayment" |                         @click="onAddPayment('{{ route('modals.documents.document.transactions.create', $document->id) }}')" | ||||||
|                         id="show-slider-actions-payment-{{ $document->type }}" |                         id="show-slider-actions-payment-{{ $document->type }}" | ||||||
|                         class="px-3 py-1.5 mb-3 sm:mb-0 rounded-lg text-xs font-medium leading-6 bg-green hover:bg-green-700 text-white disabled:bg-green-100" |                         class="px-3 py-1.5 mb-3 sm:mb-0 rounded-lg text-xs font-medium leading-6 bg-green hover:bg-green-700 text-white disabled:bg-green-100" | ||||||
|                         override="class" |                         override="class" | ||||||
| @@ -80,7 +80,7 @@ | |||||||
|                         <span> - </span> |                         <span> - </span> | ||||||
|  |  | ||||||
|                         <x-button |                         <x-button | ||||||
|                             @click="onEditPayment('{{ $transaction->id }}')" |                             @click="onEditPayment('{{ route('modals.documents.document.transactions.edit', ['document' => $document->id, 'transaction' => $transaction->id]) }}')" | ||||||
|                             id="show-slider-actions-transaction-edit-{{ $document->type }}-{{ $transaction->id }}" |                             id="show-slider-actions-transaction-edit-{{ $document->type }}-{{ $transaction->id }}" | ||||||
|                             class="text-purple mt-1" |                             class="text-purple mt-1" | ||||||
|                             override="class" |                             override="class" | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ | |||||||
|             @if (! $hideAddPayment) |             @if (! $hideAddPayment) | ||||||
|                 @if(empty($document->transactions->count()) || (! empty($document->transactions->count()) && $document->paid != $document->amount)) |                 @if(empty($document->transactions->count()) || (! empty($document->transactions->count()) && $document->paid != $document->amount)) | ||||||
|                     <x-button |                     <x-button | ||||||
|                         @click="onPayment" |                         @click="onAddPayment('{{ route('modals.documents.document.transactions.create', $document->id) }}')" | ||||||
|                         id="show-slider-actions-payment-{{ $document->type }}" |                         id="show-slider-actions-payment-{{ $document->type }}" | ||||||
|                         class="px-3 py-1.5 mb-3 sm:mb-0 rounded-lg text-xs font-medium leading-6 bg-green hover:bg-green-700 text-white disabled:bg-green-100" |                         class="px-3 py-1.5 mb-3 sm:mb-0 rounded-lg text-xs font-medium leading-6 bg-green hover:bg-green-700 text-white disabled:bg-green-100" | ||||||
|                         override="class" |                         override="class" | ||||||
| @@ -63,7 +63,7 @@ | |||||||
|                         <span> - </span> |                         <span> - </span> | ||||||
|  |  | ||||||
|                         <x-button |                         <x-button | ||||||
|                             @click="onEditPayment('{{ $transaction->id }}')" |                             @click="onEditPayment('{{ route('modals.documents.document.transactions.edit', ['document' => $document->id, 'transaction' => $transaction->id]) }}')" | ||||||
|                             id="show-slider-actions-transaction-edit-{{ $document->type }}-{{ $transaction->id }}" |                             id="show-slider-actions-transaction-edit-{{ $document->type }}-{{ $transaction->id }}" | ||||||
|                             class="text-purple mt-1" |                             class="text-purple mt-1" | ||||||
|                             override="class" |                             override="class" | ||||||
|   | |||||||
| @@ -65,7 +65,7 @@ | |||||||
|  |  | ||||||
|             @if (! $hideEmail) |             @if (! $hideEmail) | ||||||
|                 @if ($document->contact_email) |                 @if ($document->contact_email) | ||||||
|                     <x-dropdown.button id="show-more-actions-send-email-{{ $document->type }}" @click="onEmail('{{ route($emailRoute, $document->id) }}')"> |                     <x-dropdown.button id="show-more-actions-send-email-{{ $document->type }}" @click="onSendEmail('{{ route($emailRoute, $document->id) }}')"> | ||||||
|                         {{ trans($textEmail) }} |                         {{ trans($textEmail) }} | ||||||
|                     </x-dropdown.button> |                     </x-dropdown.button> | ||||||
|                 @else |                 @else | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ | |||||||
|         <div class="flex flex-wrap space-x-3 rtl:space-x-reverse"> |         <div class="flex flex-wrap space-x-3 rtl:space-x-reverse"> | ||||||
|             @if (! $hideEmail) |             @if (! $hideEmail) | ||||||
|                 @if ($document->contact_email) |                 @if ($document->contact_email) | ||||||
|                     <x-button id="show-slider-actions-send-email-{{ $document->type }}" kind="secondary" @click="onEmail('{{ route($emailRoute, $document->id) }}')"> |                     <x-button id="show-slider-actions-send-email-{{ $document->type }}" kind="secondary" @click="onSendEmail('{{ route($emailRoute, $document->id) }}')"> | ||||||
|                         {{ trans($textEmail) }} |                         {{ trans($textEmail) }} | ||||||
|                     </x-button> |                     </x-button> | ||||||
|                 @else |                 @else | ||||||
|   | |||||||
| @@ -222,7 +222,7 @@ | |||||||
|         <span class="material-icons text-lg text-purple transform ltr:rotate-90 rtl:-rotate-90 pointer-events-none">expand_circle_down</span> |         <span class="material-icons text-lg text-purple transform ltr:rotate-90 rtl:-rotate-90 pointer-events-none">expand_circle_down</span> | ||||||
|     </button> |     </button> | ||||||
|  |  | ||||||
|     <span data-menu-close id="menu-cancel" class="material-icons absolute ltr:-right-2 rtl:right-12 transition-all top-8 text-lg text-purple cursor-pointer z-10 hidden pointer-events-none">cancel</span> |     <span data-menu-close id="menu-cancel" class="material-icons absolute ltr:-right-2 rtl:right-12 transition-all top-8 text-lg text-purple cursor-pointer z-10 hidden">cancel</span> | ||||||
|  |  | ||||||
|     <div class="fixed w-full h-full invisible lg:hidden js-menu-background" style="background-color: rgba(0, 0, 0, 0.5); z-index: -1;"></div> |     <div class="fixed w-full h-full invisible lg:hidden js-menu-background" style="background-color: rgba(0, 0, 0, 0.5); z-index: -1;"></div> | ||||||
| </div> | </div> | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ | |||||||
|  |  | ||||||
|         @stack('body_start') |         @stack('body_start') | ||||||
|  |  | ||||||
|         <div id="app" class="bg-no-repeat bg-cover bg-center" style="background-image: url({{ asset('public/img/auth/login-bg.png') }});"> |         <div id="app" class="h-screen lg:h-auto bg-no-repeat bg-cover bg-center" style="background-image: url({{ asset('public/img/auth/login-bg.png') }});"> | ||||||
|             <div class="relative w-full lg:max-w-7xl flex items-center m-auto"> |             <div class="relative w-full lg:max-w-7xl flex items-center m-auto"> | ||||||
|                 <x-layouts.auth.slider> |                 <x-layouts.auth.slider> | ||||||
|                     {!! $slider ?? '' !!} |                     {!! $slider ?? '' !!} | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ | |||||||
|     <body> |     <body> | ||||||
|         @stack('body_start') |         @stack('body_start') | ||||||
|  |  | ||||||
|         <div class="bg-no-repeat bg-cover bg-center" style="background-image: url({{ asset('public/img/auth/login-bg.png') }});"> |         <div class="h-screen lg:h-auto bg-no-repeat bg-cover bg-center" style="background-image: url({{ asset('public/img/auth/login-bg.png') }});"> | ||||||
|             @if (! file_exists(public_path('js/install.min.js'))) |             @if (! file_exists(public_path('js/install.min.js'))) | ||||||
|                 <div class="relative w-full lg:max-w-7xl flex flex-col lg:flex-row items-center m-auto"> |                 <div class="relative w-full lg:max-w-7xl flex flex-col lg:flex-row items-center m-auto"> | ||||||
|                     <div class="md:w-6/12 h-screen hidden lg:flex flex-col items-center justify-center"> |                     <div class="md:w-6/12 h-screen hidden lg:flex flex-col items-center justify-center"> | ||||||
|   | |||||||
| @@ -169,7 +169,7 @@ | |||||||
|         <span class="material-icons text-lg text-purple transform ltr:rotate-90 rtl:-rotate-90 pointer-events-none">expand_circle_down</span> |         <span class="material-icons text-lg text-purple transform ltr:rotate-90 rtl:-rotate-90 pointer-events-none">expand_circle_down</span> | ||||||
|     </button> |     </button> | ||||||
|  |  | ||||||
|     <span data-menu-close class="material-icons absolute ltr:-right-2 rtl:right-12 transition-all top-8 text-lg text-purple cursor-pointer z-10 hidden pointer-events-none">cancel</span> |     <span data-menu-close class="material-icons absolute ltr:-right-2 rtl:right-12 transition-all top-8 text-lg text-purple cursor-pointer z-10 hidden">cancel</span> | ||||||
|  |  | ||||||
|     <div class="fixed w-full h-full invisible lg:hidden js-menu-background" style="background-color: rgba(0, 0, 0, 0.5); z-index: -1;"></div> |     <div class="fixed w-full h-full invisible lg:hidden js-menu-background" style="background-color: rgba(0, 0, 0, 0.5); z-index: -1;"></div> | ||||||
| </div> | </div> | ||||||
|   | |||||||
| @@ -86,7 +86,7 @@ | |||||||
|         @if ($transaction->isNotTransferTransaction()) |         @if ($transaction->isNotTransferTransaction()) | ||||||
|             @if (! $hideButtonEmail) |             @if (! $hideButtonEmail) | ||||||
|                 @if (! empty($transaction->contact) && $transaction->contact->email) |                 @if (! empty($transaction->contact) && $transaction->contact->email) | ||||||
|                     <x-dropdown.button id="show-more-actions-send-email-{{ $transaction->type }}" @click="onEmail('{{ route($routeButtonEmail, $transaction->id) }}')"> |                     <x-dropdown.button id="show-more-actions-send-email-{{ $transaction->type }}" @click="onSendEmail('{{ route($routeButtonEmail, $transaction->id) }}')"> | ||||||
|                         {{ trans('invoices.send_mail') }} |                         {{ trans('invoices.send_mail') }} | ||||||
|                     </x-dropdown.button> |                     </x-dropdown.button> | ||||||
|                 @else |                 @else | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ | |||||||
|             /> |             /> | ||||||
|              |              | ||||||
|             @if ($transfer) |             @if ($transfer) | ||||||
|                 <div class="text-black-400 text-sm flex gap-x-1 mt-1"> |                 <div class="text-black-400 text-sm space-y-3 mt-1"> | ||||||
|                     {!! trans('transactions.slider.transfer_headline', ['from_account' => $from_account, 'to_account' => $to_account]) !!} |                     {!! trans('transactions.slider.transfer_headline', ['from_account' => $from_account, 'to_account' => $to_account]) !!} | ||||||
|                 </div> |                 </div> | ||||||
|             @endif |             @endif | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ | |||||||
|  |  | ||||||
|     <x-slot name="content"> |     <x-slot name="content"> | ||||||
|         <div class="flex flex-col space-y-16 py-4"> |         <div class="flex flex-col space-y-16 py-4"> | ||||||
|             <div class="flex flex-col lg:flex-row w-full space-x-16 space-y-0"> |             <div class="flex flex-col lg:flex-row w-full space-x-16 rtl:space-x-reverse space-y-0"> | ||||||
|                 <div class="w-full lg:w-7/12 flex flex-col space-x-2 banner"> |                 <div class="w-full lg:w-7/12 flex flex-col space-x-2 banner"> | ||||||
|                     @foreach ($module->files as $file) |                     @foreach ($module->files as $file) | ||||||
|                         @if ($loop->first) |                         @if ($loop->first) | ||||||
|   | |||||||
| @@ -24,7 +24,7 @@ | |||||||
|  |  | ||||||
|                         <x-form.group.select name="type" label="{{ trans_choice('general.types', 1) }}" :options="$types" :selected="config('general.types')" change="updateParentCategories" /> |                         <x-form.group.select name="type" label="{{ trans_choice('general.types', 1) }}" :options="$types" :selected="config('general.types')" change="updateParentCategories" /> | ||||||
|  |  | ||||||
|                         <x-form.group.select name="parent_id" label="{{ trans('general.parent') . ' ' . trans_choice('general.categories', 1) }}" :options="[]" not-required dynamicOptions="categoriesBasedTypes" sort-options="false" v-disabled="isParentCategoryDisabled" /> |                         <x-form.group.select name="parent_id" label="{{ trans('general.parent') . ' ' . trans_choice('general.categories', 1) }}" :options="[]" not-required dynamicOptions="categoriesBasedTypes" sort-options="false" /> | ||||||
|  |  | ||||||
|                         <x-form.input.hidden name="categories" value="{{ json_encode($categories) }}" /> |                         <x-form.input.hidden name="categories" value="{{ json_encode($categories) }}" /> | ||||||
|                     </x-slot> |                     </x-slot> | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| @if (! empty($module)) | @if (! empty($module)) | ||||||
|     {!! $module !!} |     {!! $module !!} | ||||||
| @else | @else | ||||||
|     <div class="relative w-full lg:w-1/2 my-8 px-12"> |     <div class="relative w-full lg:w-1/2 my-8 lg:px-12"> | ||||||
|         <div class="relative pb-2 my-4 lg:my-0 z-10"> |         <div class="relative pb-2 my-4 lg:my-0 z-10"> | ||||||
|             <div class="flex justify-between font-medium mb-2"> |             <div class="flex justify-between font-medium mb-2"> | ||||||
|                 <h2 class="text-black"> |                 <h2 class="text-black"> | ||||||
| @@ -17,7 +17,7 @@ | |||||||
|         </div> |         </div> | ||||||
|  |  | ||||||
|         <div class="relative flex justify-end -mt-28"> |         <div class="relative flex justify-end -mt-28"> | ||||||
|             <img src="https://assets.akaunting.com/software/admin/bank-feeds.png" alt="Bank Feeds" /> |             <img src="https://assets.akaunting.com/software/admin/bank-feeds.png" class="rtl:-scale-x-100" alt="Bank Feeds" /> | ||||||
|         </div> |         </div> | ||||||
|     </div> |     </div> | ||||||
| @endif | @endif | ||||||
|   | |||||||
| @@ -6,11 +6,17 @@ lg:mt-4 | |||||||
| lg:pl-6 | lg:pl-6 | ||||||
| lg:w-9 | lg:w-9 | ||||||
| lg:mt-11 | lg:mt-11 | ||||||
|  | lg:-mx-12 | ||||||
|  | lg:w-96 | ||||||
|  | lg:px-3 | ||||||
|  | lg:px-4 | ||||||
|  | lg:px-6 | ||||||
| lg:relative | lg:relative | ||||||
| lg:right-0 | lg:right-0 | ||||||
| lg:justify-around | lg:justify-around | ||||||
| ltr:-right-1.5 | ltr:-right-1.5 | ||||||
| rtl:-left-1.5 | rtl:-left-1.5 | ||||||
|  | rtl:-scale-x-100 | ||||||
| sm:max-w-4xl | sm:max-w-4xl | ||||||
| hover:bg-silver-700 | hover:bg-silver-700 | ||||||
| hover:bg-peach_orange-700 | hover:bg-peach_orange-700 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user