Show data Table with pagination (startRow, endRow, filter, sorting)

This commit is contained in:
Paolo Arena
2019-10-14 20:32:15 +02:00
parent 96b7b7a48b
commit 0ee08f8430
9 changed files with 265 additions and 44 deletions

View File

@@ -1,7 +1,12 @@
export const shared_consts = {
Permissions: {
Normal: 0,
Admin: 1
},
fieldsUserToChange() {
return ['username', 'email', 'name', 'surname', 'perm', 'date_reg']
return ['username', 'email', 'name', 'surname', 'perm', 'date_reg', 'verified_email']
}
}

View File

@@ -1,16 +1,17 @@
import Vue from 'vue'
import { Component, Prop } from 'vue-property-decorator'
import { UserStore } from '../../store/Modules/index'
import { GlobalStore, UserStore } from '../../store/Modules/index'
import { tools } from '../../store/Modules/tools'
import { shared_consts } from '../../common/shared_vuejs'
import { ICategory } from '../../model'
import { CTodo } from '../todos/CTodo'
import { SingleProject } from '../projects/SingleProject'
@Component({
})
@Component({})
export default class CGridTableRec extends Vue {
@Prop({ required: true }) public mytable: string
@Prop({ required: true }) public mytitle: string
@Prop({ required: true }) public mylist: any[]
@Prop({ required: true }) public mycolumns: any[]
@@ -18,21 +19,28 @@ export default class CGridTableRec extends Vue {
public $q
public $t
public loading: boolean = false
public paginationControl: {
public pagination: {
sortBy: string,
descending: boolean
rowsNumber: number
page: number,
rowsPerPage: number // specifying this determines pagination is server-side
} = { page: 1, rowsPerPage: 10 }
} = { sortBy: '', descending: false, page: 1, rowsNumber: 10, rowsPerPage: 10 }
public serverData: any [] = []
public idsel: string = ''
public colsel: string = ''
public valPrec: string = ''
public separator: 'horizontal'
public filter: string = ''
public selected: any[] = []
public selected: any
public dark: boolean = true
public returnedData
public returnedCount
get tableClass() {
if (this.dark) {
return 'bg-black'
@@ -41,11 +49,21 @@ export default class CGridTableRec extends Vue {
public selItem(item, colsel) {
console.log('item', item)
this.selected = item
this.idsel = item._id
this.colsel = colsel
console.log('this.idsel', this.idsel)
}
public undoVal() {
console.log('undoVal', 'colsel', this.colsel, 'valprec', this.valPrec, 'this.colkey', this.colkey, 'this.selected', this.selected)
console.table(this.serverData)
if (this.colsel)
this.selected[this.colsel] = this.valPrec
// this.serverData[this.colsel] = this.valPrec
}
public SaveValue(newVal, valinitial) {
console.log('SaveValue', newVal, 'selected', this.selected)
@@ -53,6 +71,7 @@ export default class CGridTableRec extends Vue {
mydata[this.colsel] = newVal
mydata[this.colkey] = this.idsel
this.valPrec = valinitial
console.log('this.idsel', this.idsel, 'this.colsel', this.colsel)
console.table(mydata)
@@ -62,6 +81,140 @@ export default class CGridTableRec extends Vue {
public created() {
this.serverData = this.mylist.slice() // [{ chiave: 'chiave1', valore: 'valore 1' }]
// this.serverData = this.mylist.slice() // [{ chiave: 'chiave1', valore: 'valore 1' }]
}
get getrows() {
return this.pagination.rowsNumber
}
public onRequest(props) {
const { page, rowsPerPage, rowsNumber, sortBy, descending } = props.pagination
const filter = props.filter
this.loading = true
// update rowsCount with appropriate value
// get all rows if "All" (0) is selected
const fetchCount = rowsPerPage === 0 ? rowsNumber : rowsPerPage
// calculate starting row of data
const startRow = (page - 1) * rowsPerPage
const endRow = startRow + fetchCount
// fetch data from "server"
this.fetchFromServer(startRow, endRow, filter, sortBy, descending).then((ris) => {
this.pagination.rowsNumber = this.getRowsNumberCount(filter)
// clear out existing data and add new
this.serverData.splice(0, this.serverData.length, ...this.returnedData)
// don't forget to update local pagination object
this.pagination.page = page
this.pagination.rowsPerPage = rowsPerPage
this.pagination.sortBy = sortBy
this.pagination.descending = descending
// ...and turn of loading indicator
this.loading = false
})
}
// emulate ajax call
// SELECT * FROM ... WHERE...LIMIT...
public async fetchFromServer(startRow, endRow, filter, sortBy, descending) {
let myobj = null
if (sortBy) {
myobj = {}
if (descending)
myobj[sortBy] = -1
else
myobj[sortBy] = 1
}
const params = {
table: this.mytable,
startRow,
endRow,
filter,
sortBy: myobj,
descending
}
console.table(params)
const data = await GlobalStore.actions.loadTable(params)
if (data) {
this.returnedData = data.rows
this.returnedCount = data.count
} else {
this.returnedData = []
this.returnedCount = 0
}
// if (!filter) {
// data = this.original.slice(startRow, startRow + count)
// }
// else {
// let found = 0
// for (let index = startRow, items = 0; index < this.original.length && items < count; ++index) {
// let row = this.original[index]
// // match filter?
// if (!row['name'].includes(filter)) {
// // get a different row, until one is found
// continue
// }
// ++found
// if (found >= startRow) {
// data.push(row)
// ++items
// }
// }
// }
// handle sortBy
// if (sortBy) {
// data.sort((a, b) => {
// let x = descending ? b : a
// let y = descending ? a : b
// if (sortBy === 'desc') {
// // string sort
// return x[sortBy] > y[sortBy] ? 1 : x[sortBy] < y[sortBy] ? -1 : 0
// }
// else {
// // numeric sort
// return parseFloat(x[sortBy]) - parseFloat(y[sortBy])
// }
// })
// }
}
// emulate 'SELECT count(*) FROM ...WHERE...'
public getRowsNumberCount(filter) {
// if (!filter) {
// return this.original.length
// }
// let count = 0
// this.original.forEach((treat) => {
// if (treat['name'].includes(filter)) {
// ++count
// }
// })
// return count
return this.returnedCount
}
public mounted() {
this.onRequest({
pagination: this.pagination,
filter: undefined
})
}
}

View File

@@ -1,17 +1,26 @@
<template>
<div class="q-pa-sm">
<!--<div class="col-2 q-table__title">{{ mytitle }}</div>-->
<!--<q-space/>-->
<!--<p style="color:red"> Rows: {{ getrows }}</p>-->
<q-table
:title="mytitle"
:data="serverData"
:columns="mycolumns"
:filter="filter"
:pagination.sync="paginationControl"
:row-key="colkey">
:pagination.sync="pagination"
:row-key="colkey"
:loading="loading"
@request="onRequest"
binary-state-sort
>
<!--<template v-slot:top="props">-->
<div class="col-2 q-table__title">{{ mytitle }}</div>
<q-space/>
<q-tr slot="body" slot-scope="props" :props="props">

View File

@@ -201,3 +201,11 @@ export interface IFunctionality {
BOOKING_EVENTS?: boolean
}
export interface IParamsQuery {
table: string
startRow: number
endRow: number
filter: string
sortBy: any
descending: number
}

View File

@@ -17,6 +17,8 @@ export interface IUserState {
surname?: string
password?: string
lang?: string
ipaddr?: string
perm?: number
repeatPassword?: string
tokens?: IToken[]
@@ -32,6 +34,7 @@ export interface IUserState {
isLogged?: boolean
isAdmin?: boolean
usersList?: IUserList[]
countusers?: number
}
export interface IUserList {

View File

@@ -20,6 +20,7 @@ import globalroutines from './../../globalroutines/index'
import { cfgrouter } from '../../router/route-config'
import { static_data } from '@src/db/static_data'
import { IParamsQuery } from '@src/model/GlobalStore'
// import { static_data } from '@src/db/static_data'
let stateConnDefault = 'online'
@@ -504,6 +505,21 @@ namespace Actions {
}
async function loadTable(context, params: IParamsQuery) {
console.log('loadTable', params)
return await Api.SendReq('/gettable', 'POST', params)
.then((res) => {
console.table(res)
return res.data
})
.catch((error) => {
console.log('error loadUsersList', error)
UserStore.mutations.setErrorCatch(error)
return null
})
}
export const actions = {
setConta: b.dispatch(setConta),
createPushSubscription: b.dispatch(createPushSubscription),
@@ -512,7 +528,8 @@ namespace Actions {
clearDataAfterLoginOnlyIfActiveConnection: b.dispatch(clearDataAfterLoginOnlyIfActiveConnection),
prova: b.dispatch(prova),
saveCfgServerKey: b.dispatch(saveCfgServerKey),
checkUpdates: b.dispatch(checkUpdates)
checkUpdates: b.dispatch(checkUpdates),
loadTable: b.dispatch(loadTable)
}
}

View File

@@ -16,6 +16,7 @@ import { db_data } from '@src/db/db_data'
import translate from './../../globalroutines/util'
import * as Types from '@src/store/Api/ApiTypes'
import { ICfgServer } from '@src/model'
import { shared_consts } from '../../common/shared_vuejs'
const bcrypt = require('bcryptjs')
@@ -36,7 +37,8 @@ const state: IUserState = {
x_auth_token: '',
isLogged: false,
isAdmin: false,
usersList: []
usersList: [],
countusers: 0
}
const b = storeBuilder.module<IUserState>('UserModule', state)
@@ -149,28 +151,27 @@ namespace Getters {
}
namespace Mutations {
function authUser(state: IUserState, data: IUserState) {
state.userId = data.userId
state.username = data.username
state.name = data.name
state.surname = data.surname
function authUser(mystate: IUserState, data: IUserState) {
mystate.userId = data.userId
mystate.username = data.username
mystate.name = data.name
mystate.surname = data.surname
mystate.perm = data.perm
mystate.isAdmin = tools.isBitActive(mystate.perm, shared_consts.Permissions.Admin)
console.log('authUser', 'state.isAdmin', mystate.isAdmin)
console.table(mystate)
console.table(data)
if (data.verified_email) {
state.verified_email = data.verified_email
mystate.verified_email = data.verified_email
}
if (data.categorySel) {
state.categorySel = data.categorySel
mystate.categorySel = data.categorySel
} // ??
resetArrToken(state.tokens)
state.tokens.push({ access: 'auth', token: state.x_auth_token, data_login: tools.getDateNow() })
// ++Todo: Settings Users Admin
if (db_data.adminUsers.includes(state.username)) {
state.isAdmin = true
} else {
state.isAdmin = false
}
resetArrToken(mystate.tokens)
mystate.tokens.push({ access: 'auth', token: mystate.x_auth_token, data_login: tools.getDateNow() })
// console.log('state.tokens', state.tokens)
}
@@ -239,15 +240,18 @@ namespace Mutations {
state.servercode = 0
state.resStatus = 0
state.isLogged = false
state.isAdmin = false
state.x_auth_token = ''
}
function setErrorCatch(state: IUserState, axerr: Types.AxiosError) {
try {
if (state.servercode !== tools.ERR_SERVERFETCH) {
state.servercode = axerr.getCode()
}
console.log('Err catch: (servercode:', axerr.getCode(), axerr.getMsgError(), ')')
} catch (e) {
console.log('Err catch:', axerr)
}
}
function getMsgError(state: IUserState, err: number) {
@@ -281,7 +285,7 @@ namespace Mutations {
clearAuthData: b.commit(clearAuthData),
setErrorCatch: b.commit(setErrorCatch),
getMsgError: b.commit(getMsgError),
setusersList: b.commit(setusersList)
setusersList: b.commit(setusersList),
}
}
@@ -325,8 +329,15 @@ namespace Actions {
return await Api.SendReq(`/users/${user.userId}`, 'PATCH', { user })
.then((res) => {
if (res)
return (res.data.code === serv_constants.RIS_CODE_OK)
else
return false
})
.catch((error) => {
return false
})
}
async function requestpwd(context, paramquery: IUserState) {
@@ -524,12 +535,15 @@ namespace Actions {
const surname = myuser.surname
const verified_email = myuser.verified_email
console.table(myuser)
Mutations.mutations.authUser({
userId,
username,
name,
surname,
verified_email
verified_email,
perm: myuser.perm
})
const now = tools.getDateNow()
@@ -540,6 +554,7 @@ namespace Actions {
localStorage.setItem(tools.localStorage.username, username)
localStorage.setItem(tools.localStorage.name, name)
localStorage.setItem(tools.localStorage.surname, surname)
localStorage.setItem(tools.localStorage.perm, String(myuser.perm) || '')
localStorage.setItem(tools.localStorage.token, state.x_auth_token)
localStorage.setItem(tools.localStorage.expirationDate, expirationDate.toString())
localStorage.setItem(tools.localStorage.isLogged, String(true))
@@ -576,6 +591,7 @@ namespace Actions {
localStorage.removeItem(tools.localStorage.username)
localStorage.removeItem(tools.localStorage.name)
localStorage.removeItem(tools.localStorage.surname)
localStorage.removeItem(tools.localStorage.perm)
localStorage.removeItem(tools.localStorage.isLogged)
// localStorage.removeItem(rescodes.localStorage.leftDrawerOpen)
localStorage.removeItem(tools.localStorage.verified_email)
@@ -647,6 +663,7 @@ namespace Actions {
const name = String(localStorage.getItem(tools.localStorage.name))
const surname = String(localStorage.getItem(tools.localStorage.surname))
const verified_email = localStorage.getItem(tools.localStorage.verified_email) === 'true'
const perm = parseInt(localStorage.getItem(tools.localStorage.perm), 10)
GlobalStore.state.wasAlreadySubOnDb = localStorage.getItem(tools.localStorage.wasAlreadySubOnDb) === 'true'
@@ -659,7 +676,8 @@ namespace Actions {
username,
name,
surname,
verified_email
verified_email,
perm
})
isLogged = true
@@ -693,6 +711,7 @@ namespace Actions {
}
*/
export const actions = {
autologin_FromLocalStorage: b.dispatch(autologin_FromLocalStorage),
logout: b.dispatch(logout),
@@ -703,6 +722,7 @@ namespace Actions {
signup: b.dispatch(signup),
vreg: b.dispatch(vreg)
}
}
const stateGetter = b.state()

View File

@@ -5,6 +5,7 @@ export const serv_constants = {
RIS_CODE_EMAIL_ALREADY_VERIFIED: -5,
RIS_CODE_EMAIL_VERIFIED: 1,
RIS_CODE_ERR_UNAUTHORIZED: -30,
RIS_CODE_LOGIN_ERR_GENERIC: -20,
RIS_CODE_LOGIN_ERR: -10,

View File

@@ -24,6 +24,7 @@ import { static_data } from '@src/db/static_data'
import { IColl, ITimeLineEntry, ITimeLineMain } from '@src/model/GlobalStore'
import { func_tools } from '@src/store/Modules/toolsext'
import { serv_constants } from '@src/store/Modules/serv_constants'
import { shared_consts } from '@src/common/shared_vuejs'
export interface INotify {
color?: string | 'primary'
@@ -69,6 +70,7 @@ export const tools = {
username: 'uname',
name: 'nm',
surname: 'sn',
perm: 'pm',
lang: 'lg'
},
@@ -2244,6 +2246,9 @@ export const tools = {
CancelUserRec(mythis, id) {
console.log('CancelUserRec', id)
tools.askConfirm(mythis.$q, translate('cal.titlebooking'), translate('cal.canceluser') + '?', translate('dialog.yes'), translate('dialog.no'), mythis, lists.MenuAction.DELETE, 0, { param1: id })
},
isBitActive(bit, whattofind) {
return ((bit & whattofind) === whattofind)
}
// getLocale() {