mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Merge pull request #6686 from beganovich/v5-statements-json-fixes
Client portal: Statements page in pure Javascript
This commit is contained in:
commit
289c4952a0
@ -1,49 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Http\Livewire;
|
||||
|
||||
use Illuminate\View\View;
|
||||
use Livewire\Component;
|
||||
|
||||
class Statement extends Component
|
||||
{
|
||||
public string $url;
|
||||
|
||||
public array $options = [
|
||||
'show_payments_table' => 0,
|
||||
'show_aging_table' => 0,
|
||||
];
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
$this->options['start_date'] = now()->startOfYear()->format('Y-m-d');
|
||||
$this->options['end_date'] = now()->format('Y-m-d');
|
||||
}
|
||||
|
||||
protected function getCurrentUrl(): string
|
||||
{
|
||||
return route('client.statement.raw', $this->options);
|
||||
}
|
||||
|
||||
public function download()
|
||||
{
|
||||
return redirect()->route('client.statement.raw', \array_merge($this->options, ['download' => 1]));
|
||||
}
|
||||
|
||||
public function render(): View
|
||||
{
|
||||
$this->url = route('client.statement.raw', $this->options);
|
||||
|
||||
return render('components.statement');
|
||||
}
|
||||
}
|
2
public/css/app.css
vendored
2
public/css/app.css
vendored
File diff suppressed because one or more lines are too long
2
public/js/clients/shared/pdf.js
vendored
2
public/js/clients/shared/pdf.js
vendored
File diff suppressed because one or more lines are too long
2
public/js/clients/statements/view.js
vendored
Normal file
2
public/js/clients/statements/view.js
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/*! For license information please see view.js.LICENSE.txt */
|
||||
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var a=t[r]={i:r,l:!1,exports:{}};return e[r].call(a.exports,a,a.exports,n),a.l=!0,a.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)n.d(r,a,function(t){return e[t]}.bind(null,a));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=26)}({26:function(e,t,n){e.exports=n("LcZE")},LcZE:function(e,t){function n(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}(new(function(){function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.url=new URL(document.querySelector("meta[name=pdf-url]").content),this.startDate="",this.endDate="",this.showPaymentsTable=!1,this.showAgingTable=!1}var t,r,a;return t=e,(r=[{key:"bindEventListeners",value:function(){var e=this;["#date-from","#date-to","#show-payments-table","#show-aging-table"].forEach((function(t){document.querySelector(t).addEventListener("change",(function(t){return e.handleValueChange(t)}))}))}},{key:"handleValueChange",value:function(e){"checkbox"===e.target.type?this[e.target.dataset.field]=e.target.checked:this[e.target.dataset.field]=e.target.value,this.updatePdf()}},{key:"composedUrl",get:function(){return this.url.search="",this.startDate.length>0&&this.url.searchParams.append("start_date",this.startDate),this.endDate.length>0&&this.url.searchParams.append("end_date",this.endDate),this.url.searchParams.append("show_payments_table",+this.showPaymentsTable),this.url.searchParams.append("show_aging_table",+this.showAgingTable),this.url.href}},{key:"updatePdf",value:function(){document.querySelector("meta[name=pdf-url]").content=this.composedUrl;var e=document.querySelector("#pdf-iframe");e&&(e.src=this.composedUrl),document.querySelector("meta[name=pdf-url]").dispatchEvent(new Event("change"))}},{key:"handle",value:function(){this.bindEventListeners()}}])&&n(t.prototype,r),a&&n(t,a),e}())).handle()}});
|
9
public/js/clients/statements/view.js.LICENSE.txt
Normal file
9
public/js/clients/statements/view.js.LICENSE.txt
Normal file
@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"/js/app.js": "/js/app.js?id=696e8203d5e8e7cf5ff5",
|
||||
"/css/app.css": "/css/app.css?id=46021f35ee55aca9ff20",
|
||||
"/css/app.css": "/css/app.css?id=08bae341ed680d6ba544",
|
||||
"/js/clients/invoices/action-selectors.js": "/js/clients/invoices/action-selectors.js?id=a09bb529b8e1826f13b4",
|
||||
"/js/clients/invoices/payment.js": "/js/clients/invoices/payment.js?id=8ce8955ba775ea5f47d1",
|
||||
"/js/clients/linkify-urls.js": "/js/clients/linkify-urls.js?id=0dc8c34010d09195d2f7",
|
||||
@ -24,7 +24,8 @@
|
||||
"/js/clients/quotes/action-selectors.js": "/js/clients/quotes/action-selectors.js?id=1b8f9325aa6e8595e7fa",
|
||||
"/js/clients/quotes/approve.js": "/js/clients/quotes/approve.js?id=85bcae0a646882e56b12",
|
||||
"/js/clients/shared/multiple-downloads.js": "/js/clients/shared/multiple-downloads.js?id=5c35d28cf0a3286e7c45",
|
||||
"/js/clients/shared/pdf.js": "/js/clients/shared/pdf.js?id=fc3055d6a099f523ea98",
|
||||
"/js/clients/shared/pdf.js": "/js/clients/shared/pdf.js?id=2a99d83305ba87bfa6cc",
|
||||
"/js/clients/statements/view.js": "/js/clients/statements/view.js?id=9efa4bfa2d5600cded6a",
|
||||
"/js/setup/setup.js": "/js/setup/setup.js?id=8d454e7090f119552a6c",
|
||||
"/css/card-js.min.css": "/css/card-js.min.css?id=62afeb675235451543ad"
|
||||
}
|
||||
|
9
resources/js/clients/shared/pdf.js
vendored
9
resources/js/clients/shared/pdf.js
vendored
@ -80,6 +80,15 @@ class PDF {
|
||||
.getElementById('zoom-out')
|
||||
.addEventListener('click', () => this.handleZoomChange());
|
||||
|
||||
document
|
||||
.querySelector('meta[name=pdf-url]')
|
||||
.addEventListener('change', () => {
|
||||
this.canvas.getContext('2d').clearRect(0, 0, this.canvas.width, this.canvas.height);
|
||||
this.url = document.querySelector("meta[name='pdf-url']").content;
|
||||
|
||||
this.handle();
|
||||
})
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
86
resources/js/clients/statements/view.js
vendored
Normal file
86
resources/js/clients/statements/view.js
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
class Statement {
|
||||
constructor() {
|
||||
this.url = new URL(
|
||||
document.querySelector('meta[name=pdf-url]').content
|
||||
);
|
||||
this.startDate = '';
|
||||
this.endDate = '';
|
||||
this.showPaymentsTable = false;
|
||||
this.showAgingTable = false;
|
||||
}
|
||||
|
||||
bindEventListeners() {
|
||||
[
|
||||
'#date-from',
|
||||
'#date-to',
|
||||
'#show-payments-table',
|
||||
'#show-aging-table',
|
||||
].forEach((selector) => {
|
||||
document
|
||||
.querySelector(selector)
|
||||
.addEventListener('change', (event) =>
|
||||
this.handleValueChange(event)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
handleValueChange(event) {
|
||||
if (event.target.type === 'checkbox') {
|
||||
this[event.target.dataset.field] = event.target.checked;
|
||||
} else {
|
||||
this[event.target.dataset.field] = event.target.value;
|
||||
}
|
||||
|
||||
this.updatePdf();
|
||||
}
|
||||
|
||||
get composedUrl() {
|
||||
this.url.search = '';
|
||||
|
||||
if (this.startDate.length > 0) {
|
||||
this.url.searchParams.append('start_date', this.startDate);
|
||||
}
|
||||
|
||||
if (this.endDate.length > 0) {
|
||||
this.url.searchParams.append('end_date', this.endDate);
|
||||
}
|
||||
|
||||
this.url.searchParams.append(
|
||||
'show_payments_table',
|
||||
+this.showPaymentsTable
|
||||
);
|
||||
this.url.searchParams.append('show_aging_table', +this.showAgingTable);
|
||||
|
||||
return this.url.href;
|
||||
}
|
||||
|
||||
updatePdf() {
|
||||
document.querySelector('meta[name=pdf-url]').content = this.composedUrl;
|
||||
|
||||
let iframe = document.querySelector('#pdf-iframe');
|
||||
|
||||
if (iframe) {
|
||||
iframe.src = this.composedUrl;
|
||||
}
|
||||
|
||||
document
|
||||
.querySelector('meta[name=pdf-url]')
|
||||
.dispatchEvent(new Event('change'));
|
||||
}
|
||||
|
||||
handle() {
|
||||
this.bindEventListeners();
|
||||
}
|
||||
}
|
||||
|
||||
new Statement().handle();
|
@ -86,7 +86,7 @@
|
||||
<canvas id="pdf-placeholder" class="shadow rounded-lg bg-white mt-4 p-4"></canvas>
|
||||
</div>
|
||||
@else
|
||||
<iframe src="{{ $url ?? $entity->pdf_file_path(null, 'url', true) }}" class="h-screen w-full border-0 mt-4"></iframe>
|
||||
<iframe id="pdf-iframe" src="{{ $url ?? $entity->pdf_file_path(null, 'url', true) }}" class="h-screen w-full border-0 mt-4"></iframe>
|
||||
@endif
|
||||
|
||||
|
||||
|
@ -1,39 +0,0 @@
|
||||
<div>
|
||||
<div class="flex flex-col md:flex-row md:justify-between">
|
||||
<div class="flex flex-col md:flex-row md:items-center">
|
||||
{{-- <label for="status" class="flex items-center mr-4">
|
||||
<span class="mr-2">{{ ctrans('texts.status') }}</span>
|
||||
<select class="input">
|
||||
<option value="all">{{ ctrans('texts.all') }}</option>
|
||||
<option value="unpaid">{{ ctrans('texts.unpaid') }}</option>
|
||||
<option value="paid">{{ ctrans('texts.paid') }}</option>
|
||||
</select>
|
||||
</label> <!-- End status dropdown --> --}}
|
||||
|
||||
<div class="flex">
|
||||
<label for="from" class="block w-full flex items-center mr-4">
|
||||
<span class="mr-2">{{ ctrans('texts.from') }}:</span>
|
||||
<input wire:model="options.start_date" type="date" class="input w-full">
|
||||
</label>
|
||||
|
||||
<label for="to" class="block w-full flex items-center mr-4">
|
||||
<span class="mr-2">{{ ctrans('texts.to') }}:</span>
|
||||
<input wire:model="options.end_date" type="date" class="input w-full">
|
||||
</label>
|
||||
</div> <!-- End date range -->
|
||||
|
||||
<label for="show_payments" class="block flex items-center mr-4 mt-4 md:mt-0">
|
||||
<input wire:model="options.show_payments_table" type="checkbox" class="form-checkbox" autocomplete="off">
|
||||
<span class="ml-2">{{ ctrans('texts.show_payments') }}</span>
|
||||
</label> <!-- End show payments checkbox -->
|
||||
|
||||
<label for="show_aging" class="block flex items-center">
|
||||
<input wire:model="options.show_aging_table" type="checkbox" class="form-checkbox" autocomplete="off">
|
||||
<span class="ml-2">{{ ctrans('texts.show_aging') }}</span>
|
||||
</label> <!-- End show aging checkbox -->
|
||||
</div>
|
||||
<button wire:click="download" class="button button-primary bg-primary mt-4 md:mt-0">{{ ctrans('texts.download') }}</button>
|
||||
</div>
|
||||
|
||||
@include('portal.ninja2020.components.pdf-viewer', ['url' => $url])
|
||||
</div>
|
@ -2,6 +2,41 @@
|
||||
|
||||
@section('meta_title', ctrans('texts.statement'))
|
||||
|
||||
@push('head')
|
||||
<meta name="pdf-url" content="{{ route('client.statement.raw') }}">
|
||||
@endpush
|
||||
|
||||
@section('body')
|
||||
@livewire('statement')
|
||||
<div class="flex flex-col md:flex-row md:justify-between">
|
||||
<div class="flex flex-col md:flex-row md:items-center">
|
||||
<div class="flex">
|
||||
<label for="from" class="block w-full flex items-center mr-4">
|
||||
<span class="mr-2">{{ ctrans('texts.from') }}:</span>
|
||||
<input id="date-from" type="date" class="input w-full" data-field="startDate" value="{{ now()->startOfYear()->format('Y-m-d') }}">
|
||||
</label>
|
||||
|
||||
<label for="to" class="block w-full flex items-center mr-4">
|
||||
<span class="mr-2">{{ ctrans('texts.to') }}:</span>
|
||||
<input id="date-to" type="date" class="input w-full" data-field="endDate" value="{{ now()->format('Y-m-d') }}">
|
||||
</label>
|
||||
</div> <!-- End date range -->
|
||||
|
||||
<label for="show_payments" class="block flex items-center mr-4 mt-4 md:mt-0">
|
||||
<input id="show-payments-table" type="checkbox" data-field="showPaymentsTable" class="form-checkbox" autocomplete="off">
|
||||
<span class="ml-2">{{ ctrans('texts.show_payments') }}</span>
|
||||
</label> <!-- End show payments checkbox -->
|
||||
|
||||
<label for="show_aging" class="block flex items-center">
|
||||
<input id="show-aging-table" type="checkbox" data-field="showAgingTable" class="form-checkbox" autocomplete="off">
|
||||
<span class="ml-2">{{ ctrans('texts.show_aging') }}</span>
|
||||
</label> <!-- End show aging checkbox -->
|
||||
</div>
|
||||
<button class="button button-primary bg-primary mt-4 md:mt-0">{{ ctrans('texts.download') }}</button>
|
||||
</div>
|
||||
|
||||
@include('portal.ninja2020.components.pdf-viewer', ['url' => route('client.statement.raw')])
|
||||
@endsection
|
||||
|
||||
@push('footer')
|
||||
<script src="{{ asset('js/clients/statements/view.js') }}"></script>
|
||||
@endpush
|
6
webpack.mix.js
vendored
6
webpack.mix.js
vendored
@ -101,7 +101,11 @@ mix.js("resources/js/app.js", "public/js")
|
||||
.js(
|
||||
"resources/js/clients/payments/square-credit-card.js",
|
||||
"public/js/clients/payments/square-credit-card.js"
|
||||
);
|
||||
)
|
||||
.js(
|
||||
"resources/js/clients/statements/view.js",
|
||||
"public/js/clients/statements/view.js",
|
||||
)
|
||||
|
||||
mix.copyDirectory('node_modules/card-js/card-js.min.css', 'public/css/card-js.min.css');
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user