mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Implement list view per_page rows with refresh (#2610)
This commit is contained in:
parent
0c1fc0d904
commit
d454f8e0da
@ -7,7 +7,7 @@ use App\Models\Client;
|
||||
class DefaultSettings
|
||||
{
|
||||
|
||||
public static $per_page = 20;
|
||||
public static $per_page = 25;
|
||||
|
||||
public static function userSettings() : \stdClass
|
||||
{
|
||||
|
@ -70,21 +70,6 @@ class ClientDatatable extends EntityDatatable
|
||||
private function buildActionColumn($data)
|
||||
{
|
||||
|
||||
//if(auth()->user()->isAdmin())
|
||||
//todo permissions are only mocked here, when user permissions have been implemented this needs to be refactored.
|
||||
|
||||
$permissions = [
|
||||
'view_client',
|
||||
'edit_client',
|
||||
'create_task',
|
||||
'create_invoice',
|
||||
'create_payment',
|
||||
'create_credit',
|
||||
'create_expense'
|
||||
];
|
||||
|
||||
$permissions = auth()->user()->permissions();
|
||||
|
||||
$requested_actions = [
|
||||
'view_client_client_id',
|
||||
'edit_client_client_id',
|
||||
@ -95,9 +80,7 @@ class ClientDatatable extends EntityDatatable
|
||||
'create_expense_client_id'
|
||||
];
|
||||
|
||||
$is_admin = false;
|
||||
|
||||
$actions = $this->filterActions($requested_actions, $permissions, $is_admin);
|
||||
$actions = $this->filterActions($requested_actions, auth()->user()->permissions(), auth()->user()->isAdmin());
|
||||
|
||||
$data->map(function ($row) use ($actions) {
|
||||
|
||||
@ -139,7 +122,7 @@ class ClientDatatable extends EntityDatatable
|
||||
$visible = auth()->user()->getColumnVisibility(Client::class);
|
||||
|
||||
return collect([
|
||||
'per_page' => 20,
|
||||
'per_page' => 25,
|
||||
'sort_order' => [
|
||||
[
|
||||
'field' => 'name',
|
||||
|
@ -29,53 +29,49 @@ class RouteServiceProvider extends ServiceProvider
|
||||
parent::boot();
|
||||
|
||||
Route::bind('client', function ($value) {
|
||||
$client = \App\Models\Client::where('id', $this->decodePrimaryKey($value))->first() ?? abort(404);
|
||||
$client = \App\Models\Client::withTrashed()->where('id', $this->decodePrimaryKey($value))->first() ?? abort(404);
|
||||
$client->load('contacts', 'primary_contact');
|
||||
return $client;
|
||||
});
|
||||
|
||||
Route::bind('invoice', function ($value) {
|
||||
return \App\Models\Invoice::where('id', $this->decodePrimaryKey($value))->first() ?? abort(404);
|
||||
return \App\Models\Invoice::withTrashed()->where('id', $this->decodePrimaryKey($value))->first() ?? abort(404);
|
||||
});
|
||||
|
||||
Route::bind('payment', function ($value) {
|
||||
return \App\Models\Payment::where('id', $this->decodePrimaryKey($value))->first() ?? abort(404);
|
||||
return \App\Models\Payment::withTrashed()->where('id', $this->decodePrimaryKey($value))->first() ?? abort(404);
|
||||
});
|
||||
|
||||
Route::bind('product', function ($value) {
|
||||
return \App\Models\Product::where('id', $this->decodePrimaryKey($value))->first() ?? abort(404);
|
||||
return \App\Models\Product::withTrashed()->where('id', $this->decodePrimaryKey($value))->first() ?? abort(404);
|
||||
});
|
||||
|
||||
Route::bind('company', function ($value) {
|
||||
return \App\Models\Company::where('id', $this->decodePrimaryKey($value))->first() ?? abort(404);
|
||||
return \App\Models\Company::withTrashed()->where('id', $this->decodePrimaryKey($value))->first() ?? abort(404);
|
||||
});
|
||||
|
||||
Route::bind('account', function ($value) {
|
||||
return \App\Models\Account::where('id', $this->decodePrimaryKey($value))->first() ?? abort(404);
|
||||
return \App\Models\Account::withTrashed()->where('id', $this->decodePrimaryKey($value))->first() ?? abort(404);
|
||||
});
|
||||
|
||||
Route::bind('client_contact', function ($value) {
|
||||
return \App\Models\ClientContact::where('id', $this->decodePrimaryKey($value))->first() ?? abort(404);
|
||||
});
|
||||
|
||||
Route::bind('client_location', function ($value) {
|
||||
return \App\Models\ClientLocation::where('id', $this->decodePrimaryKey($value))->first() ?? abort(404);
|
||||
return \App\Models\ClientContact::withTrashed()->where('id', $this->decodePrimaryKey($value))->first() ?? abort(404);
|
||||
});
|
||||
|
||||
Route::bind('expense', function ($value) {
|
||||
return \App\Models\Expense::where('id', $this->decodePrimaryKey($value))->first() ?? abort(404);
|
||||
return \App\Models\Expense::withTrashed()->where('id', $this->decodePrimaryKey($value))->first() ?? abort(404);
|
||||
});
|
||||
|
||||
Route::bind('invitation', function ($value) {
|
||||
return \App\Models\Invitation::where('id', $this->decodePrimaryKey($value))->first() ?? abort(404);
|
||||
return \App\Models\Invitation::withTrashed()->where('id', $this->decodePrimaryKey($value))->first() ?? abort(404);
|
||||
});
|
||||
|
||||
Route::bind('task', function ($value) {
|
||||
return \App\Models\Task::where('id', $this->decodePrimaryKey($value))->first() ?? abort(404);
|
||||
return \App\Models\Task::withTrashed()->where('id', $this->decodePrimaryKey($value))->first() ?? abort(404);
|
||||
});
|
||||
|
||||
Route::bind('tax_rate', function ($value) {
|
||||
return \App\Models\TaxRate::where('id', $this->decodePrimaryKey($value))->first() ?? abort(404);
|
||||
return \App\Models\TaxRate::withTrashed()->where('id', $this->decodePrimaryKey($value))->first() ?? abort(404);
|
||||
});
|
||||
|
||||
Route::bind('proposal', function ($value) {
|
||||
|
93
public/js/client_list.js
vendored
93
public/js/client_list.js
vendored
@ -4318,7 +4318,7 @@ exports = module.exports = __webpack_require__("./node_modules/css-loader/lib/cs
|
||||
|
||||
|
||||
// module
|
||||
exports.push([module.i, "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", ""]);
|
||||
exports.push([module.i, "\nselect.custom-select {\n height: 42px;\n}\n", ""]);
|
||||
|
||||
// exports
|
||||
|
||||
@ -6415,6 +6415,7 @@ exports.default = {
|
||||
this.$events.$on('bulk-action', function (eventData) { return _this.bulkAction(eventData); });
|
||||
this.$events.$on('multi-select', function (eventData) { return _this.multiSelect(eventData); });
|
||||
this.$events.$on('single-action', function (eventData) { return _this.singleAction(eventData); });
|
||||
this.$events.$on('perpage_action', function (eventData) { return _this.onPerPageUpdate(eventData); });
|
||||
},
|
||||
methods: {
|
||||
onPaginationData: function (paginationData) {
|
||||
@ -6429,6 +6430,11 @@ exports.default = {
|
||||
this.moreParams = this.$store.getters['client_list/getQueryStringObject'];
|
||||
vue_1.default.nextTick(function () { return _this.$refs.vuetable.refresh(); });
|
||||
},
|
||||
onPerPageUpdate: function (per_page) {
|
||||
var _this = this;
|
||||
this.perPage = Number(per_page);
|
||||
vue_1.default.nextTick(function () { return _this.$refs.vuetable.refresh(); });
|
||||
},
|
||||
bulkAction: function (action) {
|
||||
var dataObj = {
|
||||
'action': action,
|
||||
@ -6437,7 +6443,6 @@ exports.default = {
|
||||
this.postBulkAction(dataObj);
|
||||
},
|
||||
singleAction: function (dataObj) {
|
||||
console.dir(dataObj);
|
||||
this.postBulkAction(dataObj);
|
||||
},
|
||||
postBulkAction: function (dataObj) {
|
||||
@ -6475,7 +6480,21 @@ exports.default = {
|
||||
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.default = {
|
||||
props: ['listaction'],
|
||||
props: {
|
||||
listaction: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
per_page_prop: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
per_page: this.per_page_prop
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
archive: function () {
|
||||
this.$events.fire('bulk-action', 'archive');
|
||||
@ -6488,6 +6507,9 @@ exports.default = {
|
||||
},
|
||||
goToUrl: function (url) {
|
||||
location.href = url;
|
||||
},
|
||||
updatePerPage: function () {
|
||||
this.$events.fire('perpage_action', this.per_page);
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -8052,7 +8074,7 @@ var render = function() {
|
||||
_vm._v(" "),
|
||||
_c(
|
||||
"div",
|
||||
{ staticClass: "mr-auto p-2" },
|
||||
{ staticClass: "p-2" },
|
||||
[
|
||||
_c("vuetable-multi-select", {
|
||||
attrs: { select_options: _vm.listaction.multi_select }
|
||||
@ -8061,6 +8083,63 @@ var render = function() {
|
||||
1
|
||||
),
|
||||
_vm._v(" "),
|
||||
_c("div", { staticClass: "mr-auto p-2" }, [
|
||||
_c("div", { staticClass: "input-group mb-3" }, [
|
||||
_c(
|
||||
"select",
|
||||
{
|
||||
directives: [
|
||||
{
|
||||
name: "model",
|
||||
rawName: "v-model",
|
||||
value: _vm.per_page,
|
||||
expression: "per_page"
|
||||
}
|
||||
],
|
||||
staticClass: "custom-select",
|
||||
attrs: { id: "per_page" },
|
||||
on: {
|
||||
change: [
|
||||
function($event) {
|
||||
var $$selectedVal = Array.prototype.filter
|
||||
.call($event.target.options, function(o) {
|
||||
return o.selected
|
||||
})
|
||||
.map(function(o) {
|
||||
var val = "_value" in o ? o._value : o.value
|
||||
return val
|
||||
})
|
||||
_vm.per_page = $event.target.multiple
|
||||
? $$selectedVal
|
||||
: $$selectedVal[0]
|
||||
},
|
||||
function($event) {
|
||||
_vm.updatePerPage()
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
[
|
||||
_c("option", { attrs: { value: "10" } }, [_vm._v("10")]),
|
||||
_vm._v(" "),
|
||||
_c("option", { attrs: { value: "25" } }, [_vm._v("25")]),
|
||||
_vm._v(" "),
|
||||
_c("option", { attrs: { value: "50" } }, [_vm._v("50")]),
|
||||
_vm._v(" "),
|
||||
_c("option", { attrs: { value: "100" } }, [_vm._v("100")])
|
||||
]
|
||||
),
|
||||
_vm._v(" "),
|
||||
_c("div", { staticClass: "input-group-append" }, [
|
||||
_c(
|
||||
"label",
|
||||
{ staticClass: "input-group-text", attrs: { for: "per_page" } },
|
||||
[_vm._v(_vm._s(_vm.trans("texts.rows")))]
|
||||
)
|
||||
])
|
||||
])
|
||||
]),
|
||||
_vm._v(" "),
|
||||
_c("div", { staticClass: "ml-auto p-2" }, [_c("vuetable-query-filter")], 1),
|
||||
_vm._v(" "),
|
||||
_c("div", { staticClass: "p-2" }, [
|
||||
@ -8400,7 +8479,11 @@ var render = function() {
|
||||
_vm._v(" "),
|
||||
_c(
|
||||
"button",
|
||||
{ staticClass: "btn btn-primary", on: { click: _vm.doFilter } },
|
||||
{
|
||||
staticClass: "btn btn-primary",
|
||||
staticStyle: { "margin-left": "15px" },
|
||||
on: { click: _vm.doFilter }
|
||||
},
|
||||
[_vm._v("Go")]
|
||||
)
|
||||
])
|
||||
|
93
public/js/client_list.min.js
vendored
93
public/js/client_list.min.js
vendored
@ -4318,7 +4318,7 @@ exports = module.exports = __webpack_require__("./node_modules/css-loader/lib/cs
|
||||
|
||||
|
||||
// module
|
||||
exports.push([module.i, "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", ""]);
|
||||
exports.push([module.i, "\nselect.custom-select {\n height: 42px;\n}\n", ""]);
|
||||
|
||||
// exports
|
||||
|
||||
@ -6415,6 +6415,7 @@ exports.default = {
|
||||
this.$events.$on('bulk-action', function (eventData) { return _this.bulkAction(eventData); });
|
||||
this.$events.$on('multi-select', function (eventData) { return _this.multiSelect(eventData); });
|
||||
this.$events.$on('single-action', function (eventData) { return _this.singleAction(eventData); });
|
||||
this.$events.$on('perpage_action', function (eventData) { return _this.onPerPageUpdate(eventData); });
|
||||
},
|
||||
methods: {
|
||||
onPaginationData: function (paginationData) {
|
||||
@ -6429,6 +6430,11 @@ exports.default = {
|
||||
this.moreParams = this.$store.getters['client_list/getQueryStringObject'];
|
||||
vue_1.default.nextTick(function () { return _this.$refs.vuetable.refresh(); });
|
||||
},
|
||||
onPerPageUpdate: function (per_page) {
|
||||
var _this = this;
|
||||
this.perPage = Number(per_page);
|
||||
vue_1.default.nextTick(function () { return _this.$refs.vuetable.refresh(); });
|
||||
},
|
||||
bulkAction: function (action) {
|
||||
var dataObj = {
|
||||
'action': action,
|
||||
@ -6437,7 +6443,6 @@ exports.default = {
|
||||
this.postBulkAction(dataObj);
|
||||
},
|
||||
singleAction: function (dataObj) {
|
||||
console.dir(dataObj);
|
||||
this.postBulkAction(dataObj);
|
||||
},
|
||||
postBulkAction: function (dataObj) {
|
||||
@ -6475,7 +6480,21 @@ exports.default = {
|
||||
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.default = {
|
||||
props: ['listaction'],
|
||||
props: {
|
||||
listaction: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
per_page_prop: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
per_page: this.per_page_prop
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
archive: function () {
|
||||
this.$events.fire('bulk-action', 'archive');
|
||||
@ -6488,6 +6507,9 @@ exports.default = {
|
||||
},
|
||||
goToUrl: function (url) {
|
||||
location.href = url;
|
||||
},
|
||||
updatePerPage: function () {
|
||||
this.$events.fire('perpage_action', this.per_page);
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -8052,7 +8074,7 @@ var render = function() {
|
||||
_vm._v(" "),
|
||||
_c(
|
||||
"div",
|
||||
{ staticClass: "mr-auto p-2" },
|
||||
{ staticClass: "p-2" },
|
||||
[
|
||||
_c("vuetable-multi-select", {
|
||||
attrs: { select_options: _vm.listaction.multi_select }
|
||||
@ -8061,6 +8083,63 @@ var render = function() {
|
||||
1
|
||||
),
|
||||
_vm._v(" "),
|
||||
_c("div", { staticClass: "mr-auto p-2" }, [
|
||||
_c("div", { staticClass: "input-group mb-3" }, [
|
||||
_c(
|
||||
"select",
|
||||
{
|
||||
directives: [
|
||||
{
|
||||
name: "model",
|
||||
rawName: "v-model",
|
||||
value: _vm.per_page,
|
||||
expression: "per_page"
|
||||
}
|
||||
],
|
||||
staticClass: "custom-select",
|
||||
attrs: { id: "per_page" },
|
||||
on: {
|
||||
change: [
|
||||
function($event) {
|
||||
var $$selectedVal = Array.prototype.filter
|
||||
.call($event.target.options, function(o) {
|
||||
return o.selected
|
||||
})
|
||||
.map(function(o) {
|
||||
var val = "_value" in o ? o._value : o.value
|
||||
return val
|
||||
})
|
||||
_vm.per_page = $event.target.multiple
|
||||
? $$selectedVal
|
||||
: $$selectedVal[0]
|
||||
},
|
||||
function($event) {
|
||||
_vm.updatePerPage()
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
[
|
||||
_c("option", { attrs: { value: "10" } }, [_vm._v("10")]),
|
||||
_vm._v(" "),
|
||||
_c("option", { attrs: { value: "25" } }, [_vm._v("25")]),
|
||||
_vm._v(" "),
|
||||
_c("option", { attrs: { value: "50" } }, [_vm._v("50")]),
|
||||
_vm._v(" "),
|
||||
_c("option", { attrs: { value: "100" } }, [_vm._v("100")])
|
||||
]
|
||||
),
|
||||
_vm._v(" "),
|
||||
_c("div", { staticClass: "input-group-append" }, [
|
||||
_c(
|
||||
"label",
|
||||
{ staticClass: "input-group-text", attrs: { for: "per_page" } },
|
||||
[_vm._v(_vm._s(_vm.trans("texts.rows")))]
|
||||
)
|
||||
])
|
||||
])
|
||||
]),
|
||||
_vm._v(" "),
|
||||
_c("div", { staticClass: "ml-auto p-2" }, [_c("vuetable-query-filter")], 1),
|
||||
_vm._v(" "),
|
||||
_c("div", { staticClass: "p-2" }, [
|
||||
@ -8400,7 +8479,11 @@ var render = function() {
|
||||
_vm._v(" "),
|
||||
_c(
|
||||
"button",
|
||||
{ staticClass: "btn btn-primary", on: { click: _vm.doFilter } },
|
||||
{
|
||||
staticClass: "btn btn-primary",
|
||||
staticStyle: { "margin-left": "15px" },
|
||||
on: { click: _vm.doFilter }
|
||||
},
|
||||
[_vm._v("Go")]
|
||||
)
|
||||
])
|
||||
|
@ -65,6 +65,7 @@ export default {
|
||||
this.$events.$on('bulk-action', eventData => this.bulkAction(eventData))
|
||||
this.$events.$on('multi-select', eventData => this.multiSelect(eventData))
|
||||
this.$events.$on('single-action', eventData => this.singleAction(eventData))
|
||||
this.$events.$on('perpage_action', eventData => this.onPerPageUpdate(eventData))
|
||||
|
||||
},
|
||||
methods: {
|
||||
@ -86,19 +87,24 @@ export default {
|
||||
Vue.nextTick( () => this.$refs.vuetable.refresh())
|
||||
|
||||
},
|
||||
onPerPageUpdate(per_page){
|
||||
|
||||
this.perPage = Number(per_page)
|
||||
Vue.nextTick( () => this.$refs.vuetable.refresh())
|
||||
|
||||
},
|
||||
bulkAction (action){
|
||||
|
||||
var dataObj = {
|
||||
'action' : action,
|
||||
'ids' : this.$refs.vuetable.selectedTo
|
||||
}
|
||||
|
||||
this.postBulkAction(dataObj)
|
||||
|
||||
},
|
||||
singleAction(dataObj) {
|
||||
|
||||
console.dir(dataObj)
|
||||
|
||||
this.postBulkAction(dataObj)
|
||||
|
||||
},
|
||||
|
@ -17,10 +17,27 @@
|
||||
|
||||
</div>
|
||||
|
||||
<div class="mr-auto p-2">
|
||||
<div class="p-2">
|
||||
<vuetable-multi-select :select_options="listaction.multi_select"></vuetable-multi-select>
|
||||
</div>
|
||||
|
||||
<div class="mr-auto p-2">
|
||||
<div class="input-group mb-3">
|
||||
|
||||
<select class="custom-select" id="per_page" v-model="per_page" @change="updatePerPage()">
|
||||
<option value="10">10</option>
|
||||
<option value="25">25</option>
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
</select>
|
||||
|
||||
<div class="input-group-append">
|
||||
<label class="input-group-text" for="per_page">{{trans('texts.rows')}}</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ml-auto p-2">
|
||||
<vuetable-query-filter></vuetable-query-filter>
|
||||
</div>
|
||||
@ -36,19 +53,48 @@
|
||||
<script lang="ts">
|
||||
|
||||
export default {
|
||||
props:['listaction'],
|
||||
props: {
|
||||
listaction: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
per_page_prop: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
|
||||
per_page: this.per_page_prop
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
archive () {
|
||||
|
||||
this.$events.fire('bulk-action', 'archive')
|
||||
|
||||
},
|
||||
del () {
|
||||
|
||||
this.$events.fire('bulk-action', 'delete')
|
||||
|
||||
},
|
||||
getBulkCount() {
|
||||
|
||||
return this.$store.getters['client_list/getBulkCount']
|
||||
|
||||
},
|
||||
goToUrl: function (url) {
|
||||
|
||||
location.href=url
|
||||
|
||||
},
|
||||
updatePerPage() {
|
||||
|
||||
this.$events.fire('perpage_action', this.per_page)
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -62,5 +108,7 @@
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
select.custom-select {
|
||||
height: 42px;
|
||||
}
|
||||
</style>
|
@ -3,7 +3,7 @@
|
||||
<div class="input-group">
|
||||
|
||||
<input type="text" v-model="filterText" class="form-control" @keyup.enter="doFilter" placeholder="search">
|
||||
<button class="btn btn-primary" @click="doFilter">Go</button>
|
||||
<button class="btn btn-primary" style="margin-left:15px;" @click="doFilter">Go</button>
|
||||
<!--<button class="btn btn-light" @click="resetFilter">Reset</button>-->
|
||||
|
||||
</div>
|
||||
|
@ -13,7 +13,7 @@
|
||||
<div class="container-fluid" id="client_list">
|
||||
<vue-toastr ref="toastr"></vue-toastr>
|
||||
|
||||
<list-actions :listaction="{{ $listaction }}"></list-actions>
|
||||
<list-actions :listaction="{{ $listaction }}" :per_page_prop="{{ $datatable['per_page'] }}"></list-actions>
|
||||
|
||||
<div style="background: #fff;">
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user