diff --git a/src/common/shared_vuejs.ts b/src/common/shared_vuejs.ts
index 8ca0c13..49718ec 100644
--- a/src/common/shared_vuejs.ts
+++ b/src/common/shared_vuejs.ts
@@ -1,13 +1,30 @@
export const shared_consts = {
Permissions: {
- Normal: 0,
- Admin: 1,
- Manager: 2,
+ Admin: {
+ value: 1,
+ label: 'pages.Admin',
+ icon: 'fas fa-user-shield'
+ },
+ Manager: {
+ value: 2,
+ label: 'otherpages.manage.manager',
+ icon: 'fas fa-tools'
+ },
+ Teacher: {
+ value: 4,
+ label: 'event.teacher',
+ icon: 'fas fa-user-tie'
+ }
+ },
+
+ MessageOptions: {
+ Notify_ByEmail: 2,
+ Notify_ByPushNotification: 4
},
fieldsUserToChange() {
- return ['username', 'email', 'name', 'surname', 'perm', 'date_reg', 'verified_email', 'img', 'ipaddr']
+ return ['username', 'email', 'name', 'surname', 'perm', 'date_reg', 'verified_email', 'img', 'ipaddr', 'lasttimeonline']
}
}
diff --git a/src/components/CDateTime/CDateTime.scss b/src/components/CDateTime/CDateTime.scss
new file mode 100644
index 0000000..7dfc793
--- /dev/null
+++ b/src/components/CDateTime/CDateTime.scss
@@ -0,0 +1,6 @@
+.calendar_comp{
+ max-width: 170px;
+ @media (max-width: 400px) {
+ max-width: 400px;
+ }
+}
diff --git a/src/components/CDateTime/CDateTime.ts b/src/components/CDateTime/CDateTime.ts
new file mode 100644
index 0000000..1da8a3e
--- /dev/null
+++ b/src/components/CDateTime/CDateTime.ts
@@ -0,0 +1,83 @@
+import Vue from 'vue'
+import { Component, Prop, Watch } from 'vue-property-decorator'
+import { tools } from '@src/store/Modules/tools'
+import { toolsext } from '@src/store/Modules/toolsext'
+
+import { date } from 'quasar'
+import { CalendarStore } from '../../store/Modules'
+
+@Component({
+ name: 'CDateTime'
+})
+
+export default class CDateTime extends Vue {
+ public $q
+ public $t
+ @Prop() public value!: Date
+ @Prop({ required: false, default: '' }) public label: string
+ @Prop({ required: false, default: '' }) public data_class!: string
+ @Prop({ required: false, default: false }) public readonly!: boolean
+ @Prop({ required: false, default: false }) public disable!: boolean
+ @Prop({ required: false, default: '' }) public bgcolor!: string
+ @Prop({ required: false, default: false }) public dense: boolean
+
+ public mystyleicon: string = 'font-size: 1.5rem;'
+ public showDateTimeScroller: boolean = false
+ public saveit: boolean = false
+ public myvalue: Date = new Date()
+ public valueprec: Date = new Date()
+
+ get getclass() {
+ return 'calendar_comp ' + this.data_class
+ }
+
+ @Watch('showDateTimeScroller')
+ public Opening() {
+ if (this.showDateTimeScroller) {
+ this.saveit = false
+ this.valueprec = this.myvalue
+ this.$emit('show')
+ } else {
+ if (!this.saveit) {
+ if (this.myvalue !== this.valueprec) {
+ this.myvalue = this.valueprec
+ tools.showNeutralNotif(this.$q, this.$t('db.reccanceled'))
+ }
+ }
+ }
+ }
+
+ public savetoclose() {
+ this.saveit = true
+ this.showDateTimeScroller = false
+ this.$emit('savetoclose', this.myvalue, this.valueprec)
+ }
+
+ get scrollerPopupStyle280() {
+ if (this.$q.screen.lt.sm) {
+ return {
+ width: '100vw',
+ height: '100vh'
+ }
+ } else {
+ return {
+ maxHeight: '400px',
+ height: '400px',
+ width: '280px'
+ }
+ }
+ }
+
+ get locale() {
+ return CalendarStore.state.locale
+ }
+
+ public mounted() {
+ this.myvalue = this.value
+ }
+
+ public changeval(newval) {
+ // console.log('changeval', newval)
+ this.$emit('update:value', newval)
+ }
+}
diff --git a/src/components/CDateTime/CDateTime.vue b/src/components/CDateTime/CDateTime.vue
new file mode 100644
index 0000000..0238e01
--- /dev/null
+++ b/src/components/CDateTime/CDateTime.vue
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+ { savetoclose(); }"
+ />
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/CDateTime/index.ts b/src/components/CDateTime/index.ts
new file mode 100644
index 0000000..eaa621c
--- /dev/null
+++ b/src/components/CDateTime/index.ts
@@ -0,0 +1 @@
+export {default as CDateTime} from './CDateTime.vue'
diff --git a/src/components/CEventsCalendar/CEventsCalendar.scss b/src/components/CEventsCalendar/CEventsCalendar.scss
index d3f47d1..2c4c783 100644
--- a/src/components/CEventsCalendar/CEventsCalendar.scss
+++ b/src/components/CEventsCalendar/CEventsCalendar.scss
@@ -247,13 +247,6 @@ $graytext: #555;
color: white;
}
-.calendar_comp{
- max-width: 170px;
- @media (max-width: 400px) {
- max-width: 400px;
- }
-}
-
.myflex{
display: flex;
flex: 1;
diff --git a/src/components/CEventsCalendar/CEventsCalendar.ts b/src/components/CEventsCalendar/CEventsCalendar.ts
index 92f32d9..8b93d46 100644
--- a/src/components/CEventsCalendar/CEventsCalendar.ts
+++ b/src/components/CEventsCalendar/CEventsCalendar.ts
@@ -28,12 +28,15 @@ import router from '@router'
import { static_data } from '@src/db/static_data'
import translate from '@src/globalroutines/util'
import { lists } from '../../store/Modules/lists'
-import { GlobalStore } from '../../store/Modules'
-import { IMessagePage, IMessage, IIdentity } from '../../model'
+import { GlobalStore, MessageStore } from '../../store/Modules'
+import { IMessagePage, IMessage, IIdentity, MsgDefault } from '../../model'
+import MixinUsers from '../../mixins/mixin-users'
+import { CDateTime } from '../CDateTime'
@Component({
+ mixins: [MixinUsers],
name: 'CEventsCalendar',
- components: { Logo, Footer, CTitle, CImgText, QDateTimeScroller, QDateScroller, CMySelect, CMyEditor }
+ components: { Logo, Footer, CTitle, CImgText, QDateTimeScroller, QDateScroller, CMySelect, CMyEditor, CDateTime }
})
export default class CEventsCalendar extends Vue {
public $q
@@ -108,9 +111,6 @@ export default class CEventsCalendar extends Vue {
public dragging = false
public draggedEvent = null
public ignoreNextSwipe = false
- public showDateScrollerAllDay = false
- public showDateTimeScrollerStart = false
- public showDateTimeScrollerEnd = false
public resources = [
{
@@ -317,21 +317,6 @@ export default class CEventsCalendar extends Vue {
}
}
- get scrollerPopupStyle280() {
- if (this.$q.screen.lt.sm) {
- return {
- width: '100vw',
- height: '100vh'
- }
- } else {
- return {
- maxHeight: '400px',
- height: '400px',
- width: '280px'
- }
- }
- }
-
get tools() {
return tools
}
@@ -370,10 +355,6 @@ export default class CEventsCalendar extends Vue {
}
}
- get mythis() {
- return this
- }
-
public $refs: {
calendar: any
}
@@ -666,26 +647,17 @@ export default class CEventsCalendar extends Vue {
const data: IMessage = {
source: {
- page: '',
event_id: myevent._id,
infoevent: tools.gettextevent(this, myevent)
},
- idapp: process.env.APP_ID,
- origin: {
- idapp: process.env.APP_ID,
- username: UserStore.state.username
- },
dest: {
idapp: process.env.APP_ID,
username: myevent.teacher
},
- read: false,
- deleted: false,
- message: this.askInfoForm.message,
- datemsg: tools.getDateNow()
+ message: this.askInfoForm.message
}
- this.SendMsgEvent(data).then((ris) => {
+ MessageStore.actions.SendMsgEvent(data).then((ris) => {
self.contextDay = null
if (ris)
tools.showPositiveNotif(self.$q, self.$t('cal.sendmsg_sent'))
@@ -841,10 +813,6 @@ export default class CEventsCalendar extends Vue {
return await CalendarStore.actions.BookEvent(eventparam)
}
- public async SendMsgEvent(param: IMessage) {
- return await UserStore.actions.SendMsgEvent(param)
- }
-
public isAlreadyBooked(eventparam: IEvents) {
return CalendarStore.getters.findEventBooked(eventparam, true)
}
@@ -880,7 +848,7 @@ export default class CEventsCalendar extends Vue {
public createContribType(value) {
console.log('createContribType', value)
tools.createNewRecord(this, 'contribtype', { label: value }).then((myrec) => {
- console.log('myrec')
+ // console.log('myrec')
CalendarStore.state.contribtype.push(myrec)
})
}
@@ -901,10 +869,6 @@ export default class CEventsCalendar extends Vue {
return myprice
}
- public getTeacherName(teacherusername) {
- return CalendarStore.getters.getTeacherName(teacherusername)
- }
-
public getWhereIcon(where) {
const whererec = CalendarStore.getters.getWhereRec(where)
return (whererec) ? whererec.whereicon : ''
@@ -915,11 +879,6 @@ export default class CEventsCalendar extends Vue {
return (whererec) ? whererec.placename : ''
}
- public getTeacherImg(teacherusername) {
- const teacher = CalendarStore.getters.getTeacher(teacherusername)
- return (teacher) ? teacher.img : ''
- }
-
public badgeClasses(eventparam, type) {
const cssColor = tools.isCssColor(eventparam.bgcolor)
const isHeader = type === 'header'
diff --git a/src/components/CEventsCalendar/CEventsCalendar.vue b/src/components/CEventsCalendar/CEventsCalendar.vue
index 84e40f4..abd4000 100644
--- a/src/components/CEventsCalendar/CEventsCalendar.vue
+++ b/src/components/CEventsCalendar/CEventsCalendar.vue
@@ -39,17 +39,17 @@
-
+
- {{getTeacherName(myevent.teacher)}}
+ {{getUserByUsername(myevent.teacher)}}
-
-
+
-
+
- {{getTeacherName(myevent.teacher2)}}
+ {{getUserByUsername(myevent.teacher2)}}
@@ -75,7 +75,7 @@
{{$t('cal.when')}}:
-
+
@@ -121,58 +121,16 @@
-
-
-
-
-
- { showDateTimeScrollerStart = false }"
- />
-
-
-
-
-
-
-
-
-
-
- { showDateTimeScrollerEnd = false }"
- />
-
-
-
-
-
+
+
+
+
@@ -294,7 +252,7 @@
{{$t('cal.when')}}:
-
+
@@ -334,7 +292,7 @@
+ @click="tools.CancelBookingEvent(mythis(), myevent, bookEventForm._id, true)">
{{$t('cal.when')}}:
-
+
@@ -560,7 +518,7 @@
-
+
@@ -600,16 +558,16 @@
-
+
- {{getTeacherName(event.teacher)}}
+ {{getUserByUsername(event.teacher)}}
-
-
+
+
-
+
- {{getTeacherName(event.teacher2)}}
+ {{getUserByUsername(event.teacher2)}}
diff --git a/src/components/CGridTableRec/CGridTableRec.scss b/src/components/CGridTableRec/CGridTableRec.scss
index 614fcef..4129ee2 100644
--- a/src/components/CGridTableRec/CGridTableRec.scss
+++ b/src/components/CGridTableRec/CGridTableRec.scss
@@ -1,3 +1,8 @@
.colmodif {
cursor: pointer;
}
+
+.coldate {
+ max-width: 250px;
+ min-width: 200px;
+}
diff --git a/src/components/CGridTableRec/CGridTableRec.ts b/src/components/CGridTableRec/CGridTableRec.ts
index d44f9a4..a6bf10d 100644
--- a/src/components/CGridTableRec/CGridTableRec.ts
+++ b/src/components/CGridTableRec/CGridTableRec.ts
@@ -9,8 +9,15 @@ import { ICategory, IColGridTable, ITableRec } from '../../model'
import { CTodo } from '../todos/CTodo'
import { SingleProject } from '../projects/SingleProject'
import { lists } from '../../store/Modules/lists'
+import { IParamsQuery } from '../../model/GlobalStore'
+import { fieldsTable } from '../../store/Modules/fieldsTable'
+import { CDateTime } from '../CDateTime'
+import { CMyToggleList } from '../CMyToggleList'
+import { CMyChipList } from '../CMyChipList'
-@Component({})
+@Component({
+ components: { CDateTime, CMyToggleList, CMyChipList }
+})
export default class CGridTableRec extends Vue {
@Prop({ required: false }) public prop_mytable: string
@Prop({ required: true }) public prop_mytitle: string
@@ -24,6 +31,7 @@ export default class CGridTableRec extends Vue {
public mytitle: string
public mycolumns: any[]
public colkey: string
+ public search: string = ''
public tablesel: string = ''
@@ -42,12 +50,12 @@ export default class CGridTableRec extends Vue {
public spinner_visible: boolean = false
public idsel: string = ''
- public colsel: string = ''
+ public colsel: IColGridTable = {name: ''}
public valPrec: string = ''
public separator: 'horizontal'
public filter: string = ''
- public selected: any
+ public rowsel: any
public dark: boolean = true
public funcActivated = []
@@ -70,25 +78,24 @@ export default class CGridTableRec extends Vue {
}
}
- public selItem(item, colsel) {
+ public selItem(item, col: IColGridTable) {
// console.log('item', item)
- this.selected = item
+ this.rowsel = item
this.idsel = item._id
- this.colsel = colsel
- // console.log('this.idsel', this.idsel)
+ this.colsel = col
}
public undoVal() {
- console.log('undoVal', 'colsel', this.colsel, 'valprec', this.valPrec, 'this.colkey', this.colkey, 'this.selected', this.selected)
+ console.log('undoVal', 'colsel', this.colsel, 'valprec', this.valPrec, 'this.colkey', this.colkey, 'this.selected', this.rowsel)
console.table(this.serverData)
if (this.colsel)
- this.selected[this.colsel] = this.valPrec
+ this.rowsel[this.colsel.field] = this.valPrec
// this.serverData[this.colsel] = this.valPrec
}
public SaveValue(newVal, valinitial) {
- // console.log('SaveValue', newVal, 'selected', this.selected)
+ console.log('SaveValue', newVal, 'rowsel', this.rowsel)
const mydata = {
id: this.idsel,
@@ -96,7 +103,7 @@ export default class CGridTableRec extends Vue {
fieldsvalue: {}
}
- mydata.fieldsvalue[this.colsel] = newVal
+ mydata.fieldsvalue[this.colsel.field] = newVal
this.valPrec = valinitial
@@ -135,7 +142,7 @@ export default class CGridTableRec extends Vue {
public onRequest(props) {
const { page, rowsPerPage, rowsNumber, sortBy, descending } = props.pagination
- const filter = props.filter
+ const filter = this.filter
if (!this.mytable)
return
@@ -146,7 +153,7 @@ export default class CGridTableRec extends Vue {
// update rowsCount with appropriate value
- // get all rows if "All" (0) is selected
+ // get all rows if "All" (0) is rowsel
const fetchCount = rowsPerPage === 0 ? rowsNumber : rowsPerPage
// calculate starting row of data
@@ -193,7 +200,7 @@ export default class CGridTableRec extends Vue {
myobj[sortBy] = 1
}
- const params = {
+ const params: IParamsQuery = {
table: this.mytable,
startRow,
endRow,
@@ -269,7 +276,10 @@ export default class CGridTableRec extends Vue {
}
public getclassCol(col) {
- return (col.disable || !this.canEdit) ? '' : 'colmodif'
+ let mycl = (col.disable || !this.canEdit) ? '' : 'colmodif'
+ mycl += (col.fieldtype === tools.FieldType.date) ? ' coldate flex flex-container' : ''
+
+ return mycl
}
public async createNewRecord() {
@@ -279,6 +289,11 @@ export default class CGridTableRec extends Vue {
table: this.mytable,
data: {}
}
+
+ // const mykey = fieldsTable.getKeyByTable(this.mytable)
+
+ // mydata.data[mykey] = ''
+
const data = await GlobalStore.actions.saveTable(mydata)
this.serverData.push(data)
@@ -307,9 +322,13 @@ export default class CGridTableRec extends Vue {
}
public refresh() {
+ if (this.search !== '')
+ this.filter = this.search
+ else
+ this.filter = ''
+
this.onRequest({
- pagination: this.pagination,
- filter: undefined
+ pagination: this.pagination
})
}
@@ -319,6 +338,7 @@ export default class CGridTableRec extends Vue {
}
}
+
public ActionAfterYes(action, item, data) {
if (action === lists.MenuAction.DELETE_RECTABLE) {
if (this.serverData.length > 0)
@@ -342,15 +362,20 @@ export default class CGridTableRec extends Vue {
}
}
- public visuValByType(col, val) {
- if (col.fieldtype === 'date') {
+ public visuValByType(col: IColGridTable, val) {
+ if (col.fieldtype === tools.FieldType.date) {
if (val === undefined) {
return '[]'
} else {
return tools.getstrDateTime(val)
}
- } else if (col.fieldtype === 'boolean') {
+ } else if (col.fieldtype === tools.FieldType.boolean) {
return (val) ? this.$t('dialog.yes') : this.$t('dialog.no')
+ } else if (col.fieldtype === tools.FieldType.binary) {
+ if (val === undefined)
+ return '[---]'
+ else
+ return fieldsTable.getArrStrByValueBinary(this, col, val)
} else {
if (val === undefined)
return '[]'
@@ -395,4 +420,18 @@ export default class CGridTableRec extends Vue {
this.updatedcol()
this.refresh()
}
+
+ get tools() {
+ return tools
+ }
+
+ get db_fieldsTable() {
+ return fieldsTable
+ }
+
+ public doSearch() {
+
+ this.refresh()
+ }
+
}
diff --git a/src/components/CGridTableRec/CGridTableRec.vue b/src/components/CGridTableRec/CGridTableRec.vue
index 5dbaaa4..7c0a924 100644
--- a/src/components/CGridTableRec/CGridTableRec.vue
+++ b/src/components/CGridTableRec/CGridTableRec.vue
@@ -35,11 +35,16 @@
+
+
+
+
+
-
-
@@ -77,54 +82,33 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ visuValByType(col, props.row[col.name]) }}
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
{{ visuValByType(col, props.row[col.name]) }}
+ @save="SaveValue" @show="selItem(props.row, col)">
@@ -133,12 +117,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ visuValByType(col, props.row[col.name]) }}
+ @save="SaveValue" @show="selItem(props.row, col)">
diff --git a/src/components/CMyChipList/CMyChipList.scss b/src/components/CMyChipList/CMyChipList.scss
new file mode 100644
index 0000000..2e84f39
--- /dev/null
+++ b/src/components/CMyChipList/CMyChipList.scss
@@ -0,0 +1,5 @@
+.clchip{
+ display: flex;
+ //flex: 1;
+ //flex-direction: column;
+}
diff --git a/src/components/CMyChipList/CMyChipList.ts b/src/components/CMyChipList/CMyChipList.ts
new file mode 100644
index 0000000..91f57ad
--- /dev/null
+++ b/src/components/CMyChipList/CMyChipList.ts
@@ -0,0 +1,57 @@
+import Vue from 'vue'
+import { Component, Prop, Watch } from 'vue-property-decorator'
+
+import { tools } from '../../store/Modules/tools'
+import { toolsext } from '@src/store/Modules/toolsext'
+
+@Component({
+ name: 'CMyChipList'
+})
+
+export default class CMyChipList extends Vue {
+ public $t
+ @Prop({ required: true }) public options: []
+ @Prop({ required: true }) public value
+ @Prop({ required: true, default: '' }) public optlab
+ @Prop({ required: true, default: '' }) public optval
+ @Prop({ required: false, default: '' }) public myclass
+ @Prop({ required: false, default: '' }) public opticon
+ @Prop({ required: false, default: '' }) public optcolor
+
+ public myvalue = ''
+ public myarrvalues = []
+
+ get tools() {
+ return tools
+ }
+
+ public mounted() {
+ this.myarrvalues = []
+
+ console.table(this.options)
+ this.options.forEach((rec, index) => {
+ if (tools.isBitActive(this.value, rec[this.optval])) {
+ const mydata = {
+ label: this.$t(rec[this.optlab]),
+ value: rec[this.optval],
+ valbool: tools.isBitActive(this.value, rec[this.optval]),
+ icon: '',
+ color: tools.getColorByIndexBest(index)
+ }
+
+ if (this.opticon)
+ mydata.icon = rec[this.opticon]
+ if (this.optcolor)
+ mydata.color = rec[this.optcolor]
+
+ this.myarrvalues.push(mydata)
+ }
+ })
+
+ if (this.myarrvalues.length === 0)
+ this.myarrvalues.push({ label: this.$t('otherpages.manage.nessuno'), color: 'gray' })
+
+ console.log('arrvalues=', this.myarrvalues)
+
+ }
+}
diff --git a/src/components/CMyChipList/CMyChipList.vue b/src/components/CMyChipList/CMyChipList.vue
new file mode 100644
index 0000000..5e65090
--- /dev/null
+++ b/src/components/CMyChipList/CMyChipList.vue
@@ -0,0 +1,19 @@
+
+
+
+
+ {{rec.label}}
+
+
+
+
+
+
+
+
diff --git a/src/components/CMyChipList/index.ts b/src/components/CMyChipList/index.ts
new file mode 100644
index 0000000..df961e8
--- /dev/null
+++ b/src/components/CMyChipList/index.ts
@@ -0,0 +1 @@
+export {default as CMyChipList} from './CMyChipList.vue'
diff --git a/src/components/CMySelect/CMySelect.ts b/src/components/CMySelect/CMySelect.ts
index 1edd9ae..e11cbdc 100644
--- a/src/components/CMySelect/CMySelect.ts
+++ b/src/components/CMySelect/CMySelect.ts
@@ -31,7 +31,7 @@ export default class CMySelect extends Vue {
}
public changeval(newval) {
- console.log('changeval', newval)
+ // console.log('changeval', newval)
// const newvallab = newval[`${this.optval}`]
// this.myvalue = newvallab
this.$emit('update:value', newval)
@@ -39,7 +39,7 @@ export default class CMySelect extends Vue {
public mounted() {
const rec = this.options.find((myrec) => myrec[`${this.optval}`] === this.value)
- console.log('rec', rec)
+ // console.log('rec', rec)
if (!this.useinput) {
this.myvalue = this.value
} else {
@@ -49,7 +49,7 @@ export default class CMySelect extends Vue {
else
this.myvalue = rec[`${this.optlab}`]
- console.log('this.myvalue', this.myvalue, 'this.optval', this.optval, 'rec', rec[`${this.optval}`])
+ // console.log('this.myvalue', this.myvalue, 'this.optval', this.optval, 'rec', rec[`${this.optval}`])
}
}
}
diff --git a/src/components/CMyToggleList/CMyToggleList.scss b/src/components/CMyToggleList/CMyToggleList.scss
new file mode 100644
index 0000000..21fe223
--- /dev/null
+++ b/src/components/CMyToggleList/CMyToggleList.scss
@@ -0,0 +1,5 @@
+.cltoggle{
+ display: flex;
+ flex: 1;
+ flex-direction: column;
+}
diff --git a/src/components/CMyToggleList/CMyToggleList.ts b/src/components/CMyToggleList/CMyToggleList.ts
new file mode 100644
index 0000000..fed5bbf
--- /dev/null
+++ b/src/components/CMyToggleList/CMyToggleList.ts
@@ -0,0 +1,50 @@
+import Vue from 'vue'
+import { Component, Prop, Watch } from 'vue-property-decorator'
+
+import { tools } from '../../store/Modules/tools'
+import { toolsext } from '@src/store/Modules/toolsext'
+
+@Component({
+ name: 'CMyToggleList'
+})
+
+export default class CMyToggleList extends Vue {
+ public $t
+ @Prop({ required: true }) public options: []
+ @Prop({ required: true }) public value
+ @Prop({ required: true, default: '' }) public label
+ @Prop({ required: false, default: '' }) public myclass
+ @Prop({ required: true, default: '' }) public optlab
+ @Prop({ required: true, default: '' }) public optval
+
+ public myvalue = ''
+ public myarrvalues = []
+
+ get tools() {
+ return tools
+ }
+
+ public changeval(newval) {
+ // Update value
+ const totale = this.myarrvalues.filter((rec) => rec.valbool).reduce((sum, rec) => sum + rec.value, 0)
+ this.myvalue = totale
+
+ // Refresh value
+ this.$emit('update:value', this.myvalue)
+ }
+
+ public mounted() {
+ this.myarrvalues = []
+
+ console.table(this.options)
+ this.options.forEach((rec) => {
+ const mydata = {
+ label: this.$t(rec[this.optlab]),
+ value: rec[this.optval],
+ valbool: tools.isBitActive(this.value, rec[this.optval])
+ }
+ this.myarrvalues.push(mydata)
+ })
+
+ }
+}
diff --git a/src/components/CMyToggleList/CMyToggleList.vue b/src/components/CMyToggleList/CMyToggleList.vue
new file mode 100644
index 0000000..f926eae
--- /dev/null
+++ b/src/components/CMyToggleList/CMyToggleList.vue
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
diff --git a/src/components/CMyToggleList/index.ts b/src/components/CMyToggleList/index.ts
new file mode 100644
index 0000000..3add23e
--- /dev/null
+++ b/src/components/CMyToggleList/index.ts
@@ -0,0 +1 @@
+export {default as CMyToggleList} from './CMyToggleList.vue'
diff --git a/src/components/index.ts b/src/components/index.ts
index 7fe6b03..f52577b 100644
--- a/src/components/index.ts
+++ b/src/components/index.ts
@@ -7,6 +7,8 @@ export * from './CBook'
export * from './CMyPage'
export * from './CTitle'
export * from './CMySelect'
+export * from './CMyToggleList'
+export * from './CMyChipList'
export * from './CMyEditor'
export * from './CImgText'
export * from './CImgTitle'
@@ -15,6 +17,7 @@ export * from './CSignIn'
export * from './CSignUp'
export * from './CEventsCalendar'
export * from './CDate'
+export * from './CDateTime'
export * from './BannerCookies'
export * from './PagePolicy'
export * from './FormNewsletter'
diff --git a/src/components/projects/SingleProject/SingleProject.vue b/src/components/projects/SingleProject/SingleProject.vue
index 6dae3ff..654e83e 100644
--- a/src/components/projects/SingleProject/SingleProject.vue
+++ b/src/components/projects/SingleProject/SingleProject.vue
@@ -9,6 +9,7 @@
v-model.trim="precDescr"
autogrow
borderless
+ debounce="1000"
:label="getlabeltext"
dense
@focus="getFocus($event)"
diff --git a/src/components/todos/CTodo/CTodo.vue b/src/components/todos/CTodo/CTodo.vue
index 6f9c3db..eddfee8 100644
--- a/src/components/todos/CTodo/CTodo.vue
+++ b/src/components/todos/CTodo/CTodo.vue
@@ -54,6 +54,7 @@
@@ -116,9 +117,12 @@
+ v-on:keyup.enter="dbInsert(false)">
+
+
diff --git a/src/components/todos/SingleTodo/SingleTodo.vue b/src/components/todos/SingleTodo/SingleTodo.vue
index 69ccb5d..404abb2 100644
--- a/src/components/todos/SingleTodo/SingleTodo.vue
+++ b/src/components/todos/SingleTodo/SingleTodo.vue
@@ -13,6 +13,7 @@
- {{getNumMsgUnread}}
+ {{getNumMsgUnread}}
{{$t('msgs.messages')}}
@@ -19,14 +19,14 @@
-
+
- {{getUserByUsername(msg.dest.username)}}
+ {{getUsernameChatByMsg(msg)}}
- {{msg.message}}
+ {{getMsgText(msg, false)}}
diff --git a/src/mixins/mixin-users.ts b/src/mixins/mixin-users.ts
index 04d2921..bc76c28 100644
--- a/src/mixins/mixin-users.ts
+++ b/src/mixins/mixin-users.ts
@@ -5,6 +5,7 @@ import { GlobalStore, UserStore, MessageStore } from '../store/Modules'
import Component from 'vue-class-component'
import { func_tools } from '../store/Modules/toolsext'
import { tools } from '../store/Modules/tools'
+import { IMessage } from '@src/model'
// You can declare a mixin as the same style as components.
@Component
@@ -12,43 +13,71 @@ export default class MixinUsers extends Vue {
public mythis() {
return this
}
+
get func_tools() {
return func_tools
}
+
get tools() {
return tools
}
+
public getUserByUsername(username) {
return UserStore.getters.getNameSurnameByUsername(username)
}
+
public getImgByUsername(username) {
return `statics/` + UserStore.getters.getImgByUsername(username)
}
+
public getMyUsername() {
return UserStore.state.my.username
}
+
+ public getUsernameChatByMsg(msg: IMessage) {
+ if (msg) {
+ if (msg.dest.username !== this.getMyUsername())
+ return msg.dest.username
+ else
+ return msg.origin.username
+ } else {
+ return ''
+ }
+ }
+
+ public getImgByMsg(msg: IMessage) {
+ return `statics/` + UserStore.getters.getImgByUsername(this.getUsernameChatByMsg(msg))
+ }
+
get getMyImg() {
return 'statics/' + UserStore.getters.getImgByUsername(UserStore.state.my.username)
}
+
get MenuCollapse() {
return GlobalStore.state.menuCollapse
// return true
}
+
get Username() {
return UserStore.state.my.username
}
+
get myName() {
return UserStore.state.my.name
}
+
get mySurname() {
return UserStore.state.my.surname
}
+
get Verificato() {
return UserStore.state.my.verified_email
}
+
get Email() {
return UserStore.state.my.email
}
+
get getNumMsg() {
return MessageStore.getters.getlasts_messages().length
}
@@ -58,4 +87,17 @@ export default class MixinUsers extends Vue {
return MessageStore.getters.getnumMsgUnread()
}
+ public getMsgText(msg: IMessage, inarray: boolean) {
+ let add = ''
+ if (msg.origin.username === this.getMyUsername())
+ add = 'Tu: '
+
+ const ris = add + msg.message
+ if (inarray)
+ return [ris]
+ else
+ return ris
+ }
+
+
}
diff --git a/src/model/Calendar.ts b/src/model/Calendar.ts
index 872f42f..103e567 100644
--- a/src/model/Calendar.ts
+++ b/src/model/Calendar.ts
@@ -43,9 +43,6 @@ export interface IBookedEvent {
export interface IOperators {
username: string
- name: string
- surname: string
- email: string
cell: string
webpage?: string
img: string
diff --git a/src/model/GlobalStore.ts b/src/model/GlobalStore.ts
index 49e5a99..130d40c 100644
--- a/src/model/GlobalStore.ts
+++ b/src/model/GlobalStore.ts
@@ -228,7 +228,9 @@ export interface IColGridTable {
action?: any
askaction?: string
foredit?: boolean
- fieldtype?: string
+ fieldtype?: number
+ jointable?: string
+ resultjoin?: string[]
visuonlyEditVal?: boolean
}
@@ -237,6 +239,8 @@ export interface ITableRec {
value: string
columns: IColGridTable[]
colkey: string
+ collabel: string
+ colicon?: string
}
export interface IDataPass {
diff --git a/src/model/MessageStore.ts b/src/model/MessageStore.ts
new file mode 100644
index 0000000..2a3e27c
--- /dev/null
+++ b/src/model/MessageStore.ts
@@ -0,0 +1,82 @@
+import { EState } from './Calendar'
+
+import { shared_consts } from '@src/common/shared_vuejs'
+
+export interface IMessagePage {
+ show: boolean
+ msg: IMessage
+ state: EState
+}
+
+export interface ISource {
+ page?: string
+ event_id?: string
+ infoevent?: string
+}
+
+export interface IIdentity {
+ idapp?: string
+ username?: string
+}
+
+export const enum StatusMessage {
+ None = 0,
+ WaitingToSend = 1,
+ Sending = 2,
+ Sent = 3,
+ Received = 4,
+ Readit = 5
+}
+
+export const MsgDefault: IMessage = {
+ _id: '',
+ idapp: '',
+ source: {
+ event_id: '',
+ infoevent: '',
+ page: ''
+ },
+ origin: {
+ username: '',
+ idapp: ''
+ },
+ dest: {
+ idapp: '',
+ username: ''
+ },
+ message: '',
+ datemsg: new Date(),
+ read: false,
+ deleted: false,
+ status: StatusMessage.None
+}
+
+export interface IMessage {
+ _id?: any
+ idapp?: string
+ source?: ISource
+ origin?: IIdentity
+ dest?: IIdentity
+ message: string
+ datemsg?: Date
+ read?: boolean
+ deleted?: boolean
+ status?: StatusMessage
+ options?: number
+}
+
+export interface IChat {
+ username: string
+ lasttimeActive?: Date
+}
+
+export interface IMsgUsers {
+ username: string
+ msgs: IMessage[]
+ lastdataread?: Date
+}
+
+export interface IMessageState {
+ last_msgs: IMessage[]
+ users_msg: IMsgUsers[]
+}
diff --git a/src/model/UserStore.ts b/src/model/UserStore.ts
index 6715d6e..8a34cb0 100644
--- a/src/model/UserStore.ts
+++ b/src/model/UserStore.ts
@@ -20,6 +20,7 @@ export interface IUserFields {
img?: string
verified_email?: boolean
tokens?: IToken[]
+ lasttimeonline?: Date
}
/*
@@ -27,6 +28,11 @@ password?: string
lang
*/
+export interface IPerm {
+ _id: number
+ label: string
+}
+
export interface IUserState {
my: IUserFields
lang?: string
@@ -42,6 +48,8 @@ export interface IUserState {
isLogged?: boolean
isAdmin?: boolean
isManager?: boolean
+ isTeacher?: boolean
usersList?: IUserFields[]
+ permissionsList?: IPerm[]
countusers?: number
}
diff --git a/src/statics/i18n.js b/src/statics/i18n.js
index e0d16c7..fbfb566 100644
--- a/src/statics/i18n.js
+++ b/src/statics/i18n.js
@@ -4,6 +4,7 @@ const msgglobal = {
it: {
grid: {
editvalues: 'Modifica Valori',
+ addrecord: 'Aggiungi Riga',
showprevedit: 'Mostra Eventi Passati',
columns: 'Colonne',
tableslist: 'Tabelle',
@@ -17,7 +18,9 @@ const msgglobal = {
tableslist: 'Lista Tabelle',
},
manage: {
- menu: 'Gestione'
+ menu: 'Gestione',
+ manager: 'Gestore',
+ nessuno: 'Nessuno'
},
messages: {
menu: 'I tuoi Messaggi'
@@ -49,6 +52,7 @@ const msgglobal = {
db: {
recupdated: 'Record Aggiornato',
recfailed: 'Errore durante aggiornamento Record',
+ reccanceled: 'Annullato Aggiornamento. Ripristinato valore precendente',
deleterecord: 'Elimina Record',
deletetherecord: 'Eliminare il Record?',
deletedrecord: 'Record Cancellato',
@@ -195,6 +199,10 @@ const msgglobal = {
themecolor: 'Tema Colore',
themebgcolor: 'Tema Colore Sfondo'
},
+ where: {
+ code: 'Id',
+ whereicon: 'Icona',
+ },
cal: {
booked: 'Prenotato',
booked_error: 'Prenotazione non avvenuta. Riprovare più tardi',
@@ -289,6 +297,7 @@ const msgglobal = {
es: {
grid: {
editvalues: 'Cambiar valores',
+ addrecord: 'Agregar fila',
showprevedit: 'Mostrar eventos pasados',
columns: 'Columnas',
tableslist: 'Tablas'
@@ -302,7 +311,9 @@ const msgglobal = {
tableslist: 'Listado de tablas',
},
manage: {
- menu: 'Gestionar'
+ menu: 'Gestionar',
+ manager: 'Gerente',
+ nessuno: 'Nadie'
},
messages: {
menu: 'Tus mensajes'
@@ -334,6 +345,7 @@ const msgglobal = {
db: {
recupdated: 'Registro Actualizado',
recfailed: 'Error durante el registro de actualización',
+ reccanceled: 'Actualización cancelada Restaurar valor anterior',
deleterecord: 'Eliminar registro',
deletetherecord: '¿Eliminar el registro?',
deletedrecord: 'Registro cancelado',
@@ -474,6 +486,10 @@ const msgglobal = {
themecolor: 'Tema Colores',
themebgcolor: 'Tema Colores Fondo'
},
+ where: {
+ code: 'Id',
+ whereicon: 'Icono',
+ },
cal: {
booked: 'Reservado',
booked_error: 'Reserva fallida. Intenta nuevamente más tarde',
@@ -565,6 +581,7 @@ const msgglobal = {
fr: {
grid: {
editvalues: 'Changer les valeurs',
+ addrecord: 'Ajouter une ligne',
showprevedit: 'Afficher les événements passés',
columns: 'Colonnes',
tableslist: 'Tables',
@@ -578,7 +595,9 @@ const msgglobal = {
tableslist: 'Liste des tables',
},
manage: {
- menu: 'Gérer'
+ menu: 'Gérer',
+ manager: 'Directeur',
+ nessuno: 'Aucun'
},
messages: {
menu: 'Vos messages'
@@ -610,6 +629,7 @@ const msgglobal = {
db: {
recupdated: 'Enregistrement mis à jour',
recfailed: 'Erreur lors de la mise à jour',
+ reccanceled: 'Mise à jour annulée. Restaurer la valeur précédente',
deleterecord: 'Supprimer l\'enregistrement',
deletetherecord: 'Supprimer l\'enregistrement?',
deletedrecord: 'Enregistrement annulé',
@@ -749,6 +769,10 @@ const msgglobal = {
themecolor: 'Tema Colores',
themebgcolor: 'Tema Colores Fondo'
},
+ where: {
+ code: 'Id',
+ whereicon: 'icône',
+ },
cal: {
booked: 'Réservé',
booked_error: 'La réservation a échoué. Réessayez plus tard',
@@ -840,6 +864,7 @@ const msgglobal = {
enUs: {
grid: {
editvalues: 'Edit Values',
+ addrecord: 'Add Row',
showprevedit: 'Show Past Events',
columns: 'Columns',
tableslist: 'Tables',
@@ -853,7 +878,9 @@ const msgglobal = {
tableslist: 'List of tables',
},
manage: {
- menu: 'Manage'
+ menu: 'Manage',
+ manager: 'Manager',
+ nessuno: 'None'
},
messages: {
menu: 'Your Messages'
@@ -885,6 +912,7 @@ const msgglobal = {
db: {
recupdated: 'Record Updated',
recfailed: 'Error during update Record',
+ reccanceled: 'Canceled Update. Restore previous value',
deleterecord: 'Delete Record',
deletetherecord: 'Delete the Record?',
deletedrecord: 'Record Deleted',
@@ -1023,6 +1051,10 @@ const msgglobal = {
themecolor: 'Theme Color',
themebgcolor: 'Theme Color Background'
},
+ where: {
+ code: 'Id',
+ whereicon: 'Icon',
+ },
cal: {
booked: 'Booked',
booked_error: 'Reservation failed. Try again later',
@@ -1114,6 +1146,7 @@ const msgglobal = {
de: {
grid: {
editvalues: 'Edit Values',
+ addrecord: 'Add Row',
showprevedit: 'Show Past Events',
columns: 'Columns',
tableslist: 'Tables',
@@ -1127,7 +1160,9 @@ const msgglobal = {
tableslist: 'List of tables',
},
manage: {
- menu: 'Manage'
+ menu: 'Manage',
+ manager: 'Manager',
+ nessuno: 'None'
},
messages: {
menu: 'Your Messages'
@@ -1159,6 +1194,7 @@ const msgglobal = {
db: {
recupdated: 'Record Updated',
recfailed: 'Error during update Record',
+ reccanceled: 'Canceled Update. Restore previous value',
deleterecord: 'Delete Record',
deletetherecord: 'Delete the Record?',
deletedrecord: 'Record Deleted',
@@ -1299,6 +1335,10 @@ const msgglobal = {
themecolor: 'Theme Color',
themebgcolor: 'Theme Color Background'
},
+ where: {
+ code: 'Id',
+ whereicon: 'Icon',
+ },
cal: {
booked: 'Booked',
booked_error: 'Reservation failed. Try again later',
diff --git a/src/store/Modules/GlobalStore.ts b/src/store/Modules/GlobalStore.ts
index 4bb0d22..cca45dc 100644
--- a/src/store/Modules/GlobalStore.ts
+++ b/src/store/Modules/GlobalStore.ts
@@ -23,6 +23,7 @@ import { IDataPass, IParamsQuery } from '@src/model/GlobalStore'
import { serv_constants } from '@src/store/Modules/serv_constants'
import { IUserState } from '@src/model'
import { Calendar } from 'element-ui'
+import { fieldsTable } from '@src/store/Modules/fieldsTable'
// import { static_data } from '@src/db/static_data'
let stateConnDefault = 'online'
@@ -284,6 +285,8 @@ namespace Mutations {
return UserStore.state.usersList
else if (table === 'sendmsgs')
return MessageStore.state.last_msgs
+ else if (table === 'permissions')
+ return UserStore.state.permissionsList
else
return null
@@ -296,8 +299,9 @@ namespace Mutations {
try {
const mylist = getListByTable(table)
+ const mykey = fieldsTable.getKeyByTable(table)
- const myrec = mylist.find((event) => event._id === id)
+ const myrec = mylist.find((event) => event[mykey] === id)
// console.log('myrec', myrec)
if (myrec) {
for (const [key, value] of Object.entries(mydata.fieldsvalue)) {
@@ -535,6 +539,10 @@ namespace Actions {
UserStore.mutations.setusersList(res.data.usersList)
}
+ if (res.data.permissionsList) {
+ UserStore.state.permissionsList = res.data.permissionsList
+ }
+
if (res.data.last_msgs) {
MessageStore.state.last_msgs = [...res.data.last_msgs]
}
diff --git a/src/store/Modules/MessageStore.ts b/src/store/Modules/MessageStore.ts
new file mode 100644
index 0000000..66aec22
--- /dev/null
+++ b/src/store/Modules/MessageStore.ts
@@ -0,0 +1,173 @@
+import Api from '@api'
+import { storeBuilder } from './Store/Store'
+
+import { serv_constants } from '../Modules/serv_constants'
+import { toolsext } from '@src/store/Modules/toolsext'
+import { GlobalStore, UserStore, Todos, Projects, CalendarStore } from '@store'
+
+import { IMessage, IMessageState, StatusMessage } from '../../model'
+import { tools } from '@src/store/Modules/tools'
+import { MsgDefault } from '@src/model'
+import { shared_consts } from '@src/common/shared_vuejs'
+
+// State
+const state: IMessageState = {
+ last_msgs: [],
+ users_msg: []
+ // last_update: []
+}
+
+const b = storeBuilder.module('MessageModule', state)
+
+namespace Getters {
+
+ const getlasts_messages = b.read((mystate: IMessageState) => (): IMessage[] => {
+ const ctrec = (mystate.last_msgs) ? mystate.last_msgs.slice(0, 5) : []
+ // const ctrec = (mystate.msgs) ? mystate.msgs.slice().reverse().slice(0, 5) : []
+ return (ctrec)
+
+ }, 'getlasts_messages')
+
+ const getnumMsgUnread = b.read((mystate: IMessageState) => () => {
+ return mystate.last_msgs.filter((msg) => !msg.read).length
+ }, 'getnumMsgUnread')
+
+ export const getters = {
+ get getlasts_messages() {
+ return getlasts_messages()
+ },
+ get getnumMsgUnread() {
+ return getnumMsgUnread()
+ }
+ }
+
+}
+
+namespace Mutations {
+ export const mutations = {
+ }
+}
+
+function setMsg(arrmsg: IMessage[], username) {
+ // console.log('arrmsg', arrmsg)
+ if (arrmsg.length > 0) {
+ let users_msg = state.users_msg.find((rec) => rec.username === username)
+ if (!users_msg) {
+ state.users_msg.push({ username, msgs: [] })
+ users_msg = state.users_msg.find((rec) => rec.username === username)
+ }
+ users_msg.msgs.push(...arrmsg)
+ // console.table(users_msg.msgs)
+
+ // users_msg.msgs = tools.getUnique(users_msg.msgs, '_id')
+ // console.table(users_msg.msgs)
+
+ if (users_msg.msgs) {
+ let userother = users_msg.msgs.slice(-1)[0].dest.username
+ if (userother === UserStore.state.my.username)
+ userother = users_msg.msgs.slice(-1)[0].origin.username
+
+ let index = state.last_msgs.findIndex((rec) => (rec.dest.username === userother) || (rec.origin.username === userother))
+ if (index >= 0) {
+ // Update last message
+ state.last_msgs[index] = users_msg.msgs.slice(-1)[0]
+ } else {
+ state.last_msgs.push(users_msg.msgs.slice(-1)[0])
+ index = state.last_msgs.findIndex((rec) => (rec.dest.username === userother) || (rec.origin.username === userother))
+ }
+ if (state.last_msgs[index])
+ users_msg.lastdataread = state.last_msgs[index].datemsg
+ else
+ users_msg.lastdataread = tools.getLastDateReadReset()
+
+ } else {
+ users_msg.lastdataread = tools.getLastDateReadReset()
+ }
+
+ // console.log('RICeVUTO', arrmsg, 'lastdataread', users_msg.lastdataread)
+ // console.log('state.users_msg', users_msg)
+ }
+}
+
+namespace Actions {
+
+ async function updateMsgDataFromServer(context, { username, lastdataread } ) {
+ // console.log('updateMsgDataFromServer', username, lastdataread)
+
+ return await Api.SendReq(`/sendmsg/${username}/${lastdataread}/${process.env.APP_ID}`, 'GET', null)
+ .then((res) => {
+ console.log('res', res)
+ if (res.status === 200) {
+ setMsg(res.data.arrmsg, username)
+ return true
+ }
+ return false
+ })
+ .catch((error) => {
+ console.error(error)
+ return false
+ })
+
+ }
+
+ async function SendMsgEvent(context, msg: IMessage) {
+ console.log('SendMsgEvent', msg)
+
+ const data: IMessage = { ...MsgDefault, ...msg}
+
+ data.source.page = ''
+ data.idapp = process.env.APP_ID
+ data.origin.idapp = process.env.APP_ID
+ data.origin.username = UserStore.state.my.username
+ data.datemsg = tools.getDateNow()
+ data.status = StatusMessage.WaitingToSend
+ // Options
+ // data.options = tools.SetBit(data.options, shared_consts.MessageOptions.Notify_ByEmail)
+ data.options = tools.SetBit(data.options, shared_consts.MessageOptions.Notify_ByPushNotification)
+
+ console.log('DOPO:')
+ console.table(data)
+
+ return await Api.SendReq('/sendmsg', 'POST', data)
+ .then((res) => {
+ console.log('res', res)
+ if (res.status === 200) {
+ if (res.data.code === serv_constants.RIS_CODE_OK) {
+ data._id = res.data.id
+
+ const myarr = []
+ myarr.push(data)
+
+ setMsg(myarr, data.dest.username)
+ return true
+ }
+ }
+ return false
+ })
+ .catch((error) => {
+ console.error(error)
+ return false
+ })
+
+ }
+
+ export const actions = {
+ updateMsgDataFromServer: b.dispatch(updateMsgDataFromServer),
+ SendMsgEvent: b.dispatch(SendMsgEvent)
+ }
+
+}
+
+const stateGetter = b.state()
+
+// Module
+const MessageModule = {
+ get state() {
+ return stateGetter()
+ },
+ actions: Actions.actions,
+ getters: Getters.getters,
+ mutations: Mutations.mutations
+}
+
+export default MessageModule
diff --git a/src/store/Modules/Store/calendar/CalendarStore.ts b/src/store/Modules/Store/calendar/CalendarStore.ts
index 030f0f8..d3bc490 100644
--- a/src/store/Modules/Store/calendar/CalendarStore.ts
+++ b/src/store/Modules/Store/calendar/CalendarStore.ts
@@ -65,18 +65,6 @@ namespace Getters {
return mystate.bookedevent.filter((bookedevent) => (bookedevent.id_bookedevent === idevent) && (bookedevent.booked) && (showall || (!showall && bookedevent.userId === UserStore.state.my._id) ))
}, 'getEventsBookedByIdEvent')
- const getTeacherName = b.read((mystate: ICalendarState) => (teacherusername) => {
- const op = mystate.operators.find((myop) => myop.username === teacherusername)
- return (op) ? `${op.name} ${op.surname}` : ''
-
- }, 'getTeacherName')
-
- const getTeacher = b.read((mystate: ICalendarState) => (teacherusername) => {
- const op = mystate.operators.find((myop) => myop.username === teacherusername)
- return (op)
-
- }, 'getTeacher')
-
const getWhereRec = b.read((mystate: ICalendarState) => (wherecode) => {
const whererec = mystate.wheres.find((mywhere) => mywhere.code === wherecode)
return (whererec)
@@ -110,9 +98,6 @@ namespace Getters {
get getEventsBookedByIdEvent() {
return getEventsBookedByIdEvent()
},
- get getTeacher() {
- return getTeacher()
- },
get getWhereRec() {
return getWhereRec()
},
@@ -124,12 +109,8 @@ namespace Getters {
},
get getContribtypeRecByLabel() {
return getContribtypeRecByLabel()
- },
- get getTeacherName() {
- return getTeacherName()
}
}
-
}
namespace Mutations {
diff --git a/src/store/Modules/UserStore.ts b/src/store/Modules/UserStore.ts
index 49cf5a8..e0502b2 100644
--- a/src/store/Modules/UserStore.ts
+++ b/src/store/Modules/UserStore.ts
@@ -41,6 +41,7 @@ const state: IUserState = {
isAdmin: false,
isManager: false,
usersList: [],
+ permissionsList: [],
countusers: 0
}
@@ -138,9 +139,11 @@ namespace Getters {
}, 'getUserByUsername')
const getImgByUsername = b.read((mystate: IUserState) => (username): string => {
+ if (username === '')
+ return 'images/avatar/avatar3_small.png'
// Check if is this User!
const myrec = UserStore.getters.getUserByUsername(username)
- if (myrec && !!myrec.img) {
+ if (myrec && !!myrec.img && myrec.img !== '' && myrec.img !== 'undefined') {
return myrec.img
} else {
return 'images/avatar/avatar3_small.png'
@@ -195,8 +198,9 @@ namespace Mutations {
function authUser(mystate: IUserState, data: IUserFields) {
mystate.my = {...data}
- mystate.isAdmin = tools.isBitActive(mystate.my.perm, shared_consts.Permissions.Admin)
- mystate.isManager = tools.isBitActive(mystate.my.perm, shared_consts.Permissions.Manager)
+ mystate.isAdmin = tools.isBitActive(mystate.my.perm, shared_consts.Permissions.Admin.value)
+ mystate.isManager = tools.isBitActive(mystate.my.perm, shared_consts.Permissions.Manager.value)
+ mystate.isTeacher = tools.isBitActive(mystate.my.perm, shared_consts.Permissions.Teacher.value)
// console.log('authUser', 'state.isAdmin', mystate.isAdmin)
console.table(mystate)
diff --git a/src/store/Modules/fieldsTable.ts b/src/store/Modules/fieldsTable.ts
new file mode 100644
index 0000000..1b2e3e9
--- /dev/null
+++ b/src/store/Modules/fieldsTable.ts
@@ -0,0 +1,234 @@
+import { IColGridTable } from '../../model'
+import { lists } from './lists'
+import { tools } from '@src/store/Modules/tools'
+import { shared_consts } from '@src/common/shared_vuejs'
+
+const DeleteRec = {
+ name: 'deleterec',
+ label_trans: 'newsletter.reset',
+ align: 'right',
+ field: tools.NOFIELD,
+ sortable: false,
+ icon: 'fas fa-trash-alt',
+ action: lists.MenuAction.DELETE_RECTABLE,
+ askaction: 'db.deletetherecord',
+ required: true,
+ visuonlyEditVal: true
+}
+
+function AddCol(params: IColGridTable) {
+ return {
+ name: params.name,
+ required: (params.required === undefined) ? false : params.required,
+ label: (params.label === undefined) ? '' : params.label,
+ label_trans: (params.label_trans === undefined) ? '' : params.label_trans,
+ align: (params.align === undefined) ? 'left' : params.align,
+ field: (params.field === undefined) ? params.name : params.field,
+ sortable: (params.sortable === undefined) ? true : params.sortable,
+ disable: (params.disable === undefined) ? false : params.disable,
+ titlepopupedit: (params.titlepopupedit === undefined) ? '' : params.titlepopupedit,
+ visible: (params.visible === undefined) ? true : params.visible,
+ icon: (params.icon === undefined) ? '' : params.icon,
+ action: (params.action === undefined) ? '' : params.action,
+ foredit: (params.foredit === undefined) ? true : params.foredit,
+ fieldtype: (params.fieldtype === undefined) ? tools.FieldType.string : params.fieldtype,
+ visuonlyEditVal: (params.visuonlyEditVal === undefined) ? false : params.visuonlyEditVal,
+ askaction: (params.askaction === undefined) ? '' : params.askaction,
+ jointable: (params.jointable === undefined) ? '' : params.jointable
+ }
+}
+
+const colTableWhere = [
+ AddCol({ name: 'code', label_trans: 'where.code' }),
+ AddCol({ name: 'placename', label_trans: 'cal.where' }),
+ AddCol({ name: 'whereicon', label_trans: 'where.whereicon' }),
+ AddCol(DeleteRec)
+]
+
+const colcontribtype = [
+ AddCol({ name: 'label', label_trans: 'proj.longdescr' }),
+ AddCol({ name: 'showprice', label_trans: 'event.showprice', fieldtype: tools.FieldType.boolean }),
+ AddCol(DeleteRec)
+]
+
+const colTablePermission = [
+ AddCol({ name: '_id', label_trans: 'others.value' }),
+ AddCol({ name: 'label', label_trans: 'proj.longdescr' }),
+ AddCol(DeleteRec)
+]
+
+const colTableOperator = [
+ AddCol({ name: 'username', label_trans: 'reg.username' }),
+ // AddCol({ name: 'name', label_trans: 'reg.name' }),
+ // AddCol({ name: 'surname', label_trans: 'reg.surname' }),
+ // AddCol({ name: 'webpage', label_trans: 'reg.webpage' }),
+ // AddCol({ name: 'email', label_trans: 'reg.email' }),
+ // AddCol({ name: 'cell', label_trans: 'reg.cell' }),
+ // AddCol({ name: 'img', label_trans: 'reg.img' }),
+ AddCol(DeleteRec)]
+
+const colTableEvents = [
+ AddCol({ name: '_id', label_trans: 'event._id' }),
+ AddCol({ name: 'typol', label_trans: 'event.typol' }),
+ AddCol({ name: 'short_tit', label_trans: 'event.short_tit' }),
+ AddCol({ name: 'title', label_trans: 'event.title' }),
+ AddCol({ name: 'details', label_trans: 'event.details' }),
+ AddCol({ name: 'dateTimeStart', label_trans: 'event.dateTimeStart', fieldtype: tools.FieldType.date }),
+ AddCol({ name: 'dateTimeEnd', label_trans: 'event.dateTimeEnd' }),
+ AddCol({ name: 'bgcolor', label_trans: 'event.bgcolor' }),
+ AddCol({ name: 'icon', label_trans: 'event.icon' }),
+ AddCol({ name: 'img_small', label_trans: 'event.img_small' }),
+ AddCol({ name: 'img', label_trans: 'event.img' }),
+ AddCol({ name: 'wherecode', label_trans: 'event.where' }),
+ AddCol({ name: 'contribtype', label_trans: 'event.contribtype' }),
+ AddCol({ name: 'price', label_trans: 'event.price' }),
+ AddCol({ name: 'infoafterprice', label_trans: 'event.infoafterprice' }),
+ AddCol({ name: 'teacher', label_trans: 'event.teacher' }),
+ AddCol({ name: 'teacher2', label_trans: 'event.teacher2' }),
+ AddCol({ name: 'infoextra', label_trans: 'event.infoextra' }),
+ AddCol({ name: 'linkpage', label_trans: 'event.linkpage' }),
+ AddCol({ name: 'linkpdf', label_trans: 'event.linkpdf' }),
+ AddCol({ name: 'nobookable', label_trans: 'event.nobookable', fieldtype: tools.FieldType.boolean }),
+ AddCol({ name: 'news', label_trans: 'event.news', fieldtype: tools.FieldType.boolean }),
+ AddCol({ name: 'canceled', label_trans: 'event.canceled', fieldtype: tools.FieldType.boolean }),
+ AddCol({ name: 'deleted', label_trans: 'event.deleted', fieldtype: tools.FieldType.boolean }),
+ AddCol({ name: 'dupId', label_trans: 'event.dupId' }),
+ AddCol({ name: 'modified', label_trans: 'event.modified', fieldtype: tools.FieldType.boolean }),
+ AddCol(DeleteRec),
+ AddCol({
+ name: 'copyrec',
+ label_trans: 'event.duplicate',
+ align: 'right',
+ field: tools.NOFIELD,
+ sortable: false,
+ icon: 'fas fa-copy',
+ action: lists.MenuAction.DUPLICATE_RECTABLE,
+ askaction: 'db.duplicatedrecord',
+ visuonlyEditVal: true,
+ required: true,
+ visible: true
+ })
+]
+
+export const fieldsTable = {
+ getArrStrByValueBinary(mythis, col: IColGridTable, val) {
+ const arr = this.getArrByValueBinary(mythis, col, val)
+ if (arr.length > 0)
+ return arr.join(' - ')
+ else
+ return '[---]'
+ },
+
+ getArrByValueBinary(mythis, col: IColGridTable, val) {
+ if (col.jointable) {
+ const mylist = this.getTableJoinByName(col.jointable)
+ const key = this.getKeyByTable(col.jointable)
+ const myres = []
+ mylist.forEach((myrec) => {
+ if (tools.isBitActive(val, myrec[key]))
+ myres.push(mythis.$t(myrec.label))
+ })
+
+ return myres
+ } else {
+ return []
+ }
+ },
+
+ getColByTable(table) {
+ if (table === 'permissions') {
+ return ['value', 'label']
+ }
+ },
+ getTableJoinByName(table) {
+ if (table === 'permissions') {
+ return [shared_consts.Permissions.Admin, shared_consts.Permissions.Manager, shared_consts.Permissions.Teacher]
+ }
+ },
+ getrecTableList(mytable) {
+ return this.tablesList.find((rec) => rec.value === mytable)
+ },
+ getKeyByTable(mytable): string {
+ const myrec = this.getrecTableList(mytable)
+ if (myrec)
+ return ((myrec.colkey) ? myrec.colkey : '_id')
+ else
+ return '_id'
+ },
+ getLabelByTable(mytable): string {
+ const myrec = this.getrecTableList(mytable)
+ if (myrec)
+ return ((myrec.collabel) ? myrec.collabel : 'label')
+ else
+ return 'label'
+ },
+ getIconByTable(mytable): string {
+ const myrec = this.getrecTableList(mytable)
+ if (myrec)
+ return ((myrec.icon) ? myrec.icon : '')
+ else
+ return ''
+ },
+ tablesList: [
+ {
+ value: 'operators',
+ label: 'Insegnanti',
+ columns: colTableOperator,
+ colkey: '_id',
+ collabel: 'username'
+ },
+ {
+ value: 'wheres',
+ label: 'Luoghi',
+ columns: colTableWhere,
+ colkey: '_id',
+ collabel: 'placename'
+ },
+ {
+ value: tools.TABEVENTS,
+ label: 'Eventi',
+ columns: colTableEvents,
+ colkey: '_id',
+ collabel: 'title'
+ },
+ {
+ value: 'contribtype',
+ label: 'Tipi di Contributi',
+ columns: colcontribtype,
+ colkey: '_id',
+ collabel: 'label'
+ },
+ {
+ value: 'permissions',
+ label: 'Permessi',
+ columns: colTablePermission,
+ colkey: 'value',
+ collabel: 'label',
+ colicon: 'icon'
+ }
+ ],
+
+ // IColGridTable
+ colTableUsers: [
+ AddCol({ name: 'username', label_trans: 'reg.username' }),
+ AddCol({ name: 'name', label_trans: 'reg.name' }),
+ AddCol({ name: 'surname', label_trans: 'reg.surname' }),
+ AddCol({ name: 'email', label_trans: 'reg.email' }),
+ AddCol({ name: 'date_reg', label_trans: 'reg.date_reg', fieldtype: tools.FieldType.date }),
+ AddCol({ name: 'perm', label_trans: 'reg.perm', fieldtype: tools.FieldType.binary, jointable: 'permissions' }),
+ AddCol({ name: 'img', label_trans: 'reg.img', sortable: false }),
+ AddCol(DeleteRec),
+ AddCol({
+ name: 'copyrec',
+ label_trans: 'event.duplicate',
+ align: 'right',
+ field: tools.NOFIELD,
+ sortable: false,
+ icon: 'fas fa-copy',
+ action: lists.MenuAction.DUPLICATE_RECTABLE,
+ askaction: 'db.duplicatedrecord',
+ visuonlyEditVal: true,
+ visible: true
+ })
+ ]
+}
diff --git a/src/store/Modules/tools.ts b/src/store/Modules/tools.ts
index 0e03529..1c6efaa 100644
--- a/src/store/Modules/tools.ts
+++ b/src/store/Modules/tools.ts
@@ -27,6 +27,7 @@ import { serv_constants } from '@src/store/Modules/serv_constants'
import { shared_consts } from '@src/common/shared_vuejs'
import { dom } from 'quasar'
+
const { height, width } = dom
export interface INotify {
@@ -36,6 +37,23 @@ export interface INotify {
}
export const tools = {
+ listBestColor: [
+ 'blue',
+ 'green',
+ 'purple',
+ 'deep-purple',
+ 'indigo',
+ 'light-blue',
+ 'cyan',
+ 'teal',
+ 'lime',
+ 'orange',
+ 'deeporange',
+ 'grey',
+ 'blue-gray',
+ 'yellow'
+ ],
+
TABEVENTS: 'myevents',
MAX_CHARACTERS: 60,
@@ -95,6 +113,13 @@ export const tools = {
COMPLETED: 10
},
+ FieldType: {
+ boolean: 1,
+ date: 2,
+ string: 4,
+ binary: 8
+ },
+
SelectListNumPeople: [
{
id: 1,
@@ -1397,6 +1422,10 @@ export const tools = {
tools.showNotif(q, msg, { color: 'negative', icon: 'notifications' })
},
+ showNeutralNotif(q: any, msg) {
+ tools.showNotif(q, msg, { color: 'warning', icon: 'notifications' })
+ },
+
showNotif(q: any, msg, data ?: INotify | null
) {
let myicon = data ? data.icon : 'ion-add'
@@ -2470,12 +2499,51 @@ export const tools = {
// return height()
return mythis.$q.screen.height
},
+ getwidth(mythis) {
+ // return height()
+ return mythis.$q.screen.width
+ },
+
+ isIsoDate(str) {
+ if (!/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/.test(str)) return false
+ const d = new Date(str)
+ return d.toISOString() === str
+ },
+
getLastDateReadReset() {
return new Date(1999, 1, 1, 0, 0, 0)
},
isBitActive(bit, whattofind) {
- return ((bit & whattofind) === whattofind)
+ if (whattofind > 0)
+ return ((bit & whattofind) === whattofind)
+ else
+ return false
+ },
+
+ SetBit(myval, bit) {
+ myval = myval | bit
+ return myval
+ },
+ getUnique(arr, comp) {
+
+ const unique = arr
+ .map(e => e[comp])
+
+ // store the keys of the unique objects
+ .map((e, i, final) => final.indexOf(e) === i && i)
+
+ // eliminate the dead keys & store unique objects
+ .filter(e => arr[e]).map(e => arr[e])
+
+ return unique
+ },
+
+ getColorByIndexBest(index) {
+ if (index < this.listBestColor.length - 1)
+ return this.listBestColor[index]
+ else
+ return 'primary'
}
// getLocale() {
diff --git a/src/views/categories/category/category.ts b/src/views/categories/category/category.ts
index 96e7515..9424180 100644
--- a/src/views/categories/category/category.ts
+++ b/src/views/categories/category/category.ts
@@ -76,7 +76,6 @@ export default class Category extends Vue {
this.updatetable()
}
-
created() {
this.loadCat()
}
diff --git a/src/views/messages/messages.scss b/src/views/messages/messages.scss
index 5fca5c7..169b5d5 100644
--- a/src/views/messages/messages.scss
+++ b/src/views/messages/messages.scss
@@ -25,9 +25,23 @@
}
.chat_dest{
-
+ display: flex;
+ flex: 1;
+ justify-content: flex-start;
}
.chat_my{
-
+ display: flex;
+ flex: 1;
+ justify-content: flex-end;
+}
+
+.bottomfixed {
+ // right: 0;
+ // position: fixed;
+ z-index: 9999;
+ // box-sizing: border-box;
+ margin-right: 0;
+ margin-left: auto;
+ // bottom: 0;
}
diff --git a/src/views/messages/messages.ts b/src/views/messages/messages.ts
index 61f7d86..d157a4d 100644
--- a/src/views/messages/messages.ts
+++ b/src/views/messages/messages.ts
@@ -4,10 +4,15 @@ import { toolsext } from '../../store/Modules/toolsext'
import { MessageStore, UserStore } from '../../store/Modules'
import globalroutines from '../../globalroutines/index'
import { tools } from '../../store/Modules/tools'
-import MixinUsers from '../../mixins/mixin-users'
-import { IChat, IMessage, IUserState } from '../../model'
+
+import { IChat, IMessage, IUserState, MsgDefault, StatusMessage } from '../../model'
import { Getter } from 'vuex-class'
import { IMsgUsers } from '../../model/MessageStore'
+import MixinUsers from '../../mixins/mixin-users'
+
+import { scroll } from 'quasar'
+
+const { getScrollTarget, setScrollPosition } = scroll
// import {Loading, QSpinnerFacebook, QSpinnerGears} from 'quasar'
@@ -16,7 +21,7 @@ const namespace = 'MessageModule'
@Component({
name: 'Messages',
mixins: [MixinUsers],
- components: { }
+ components: {}
})
export default class Messages extends Vue {
@@ -24,18 +29,97 @@ export default class Messages extends Vue {
public $q
public mydrawer = true
public miniState = false
+ public usernameloading: string = ''
+ public widthdrawer = 300
public chatsel: IChat = {
username: '',
lasttimeActive: new Date()
}
+ public mytexttosend: string = ''
+ public loading: boolean = false
+
+ // public users_msg_saved: IMsgUsers[] = []
@Getter('getlasts_messages', { namespace })
public lasts_messages: (state: IUserState) => IMessage[]
+ @Watch('$route.params.un')
+ public changeusername() {
+ if (this.$route.params.un === undefined || this.$route.params.un === ':un') {
+ this.usernameloading = this.getLastUserChatted()
+ } else {
+ this.usernameloading = this.$route.params.un
+ }
+
+ if (!this.miniState && tools.isMobile()) {
+ this.miniState = true
+ }
+
+ if (this.usernameloading) {
+ // Retrieve last msgs data from the server
+ this.refreshdata(this.usernameloading)
+ }
+ }
+
+ get styletextbar() {
+
+ let mystr = ''
+
+ if (this.mydrawer) {
+ if (!this.miniState)
+ mystr = `left: ${this.widthdrawer}px;`
+ else
+ mystr = `left: 57px;`
+ } else {
+ mystr = 'left: 0;'
+ }
+
+ // console.log('tools.getwidth', tools.getwidth)
+
+ mystr += ` width: ${tools.getwidth(this) - this.widthdrawer - 40 - 300}px; `
+
+ return mystr
+ }
+
+ public scrollToElement(el) {
+ const target = getScrollTarget(el)
+ const offset = el.offsetTop
+ const duration = 1000
+ // console.log('target', target, 'offset', offset, 'duration', duration)
+ setScrollPosition(target, offset, duration)
+ }
+
+ public refreshdata(username: string) {
+ this.loading = true
+
+ this.chatsel.username = ''
+
+ return MessageStore.actions.updateMsgDataFromServer({
+ username,
+ lastdataread: this.getlastdataread(username)
+ }).then((ris) => {
+ this.usernameloading = username
+ this.chatsel.username = username
+ this.loading = false
+
+ const element = document.getElementById('last')
+ this.scrollToElement(element)
+
+ // this.changemsgs('', '')
+
+ }).catch((err) => {
+ this.loading = false
+ })
+ }
+
public showNotif(msgcode) {
tools.showNotif(this.$q, this.$t(msgcode))
}
+ public getMyUsername() {
+ return UserStore.state.my.username
+ }
+
public drawerClick(e) {
// if in "mini" state and user
// click on drawer, we switch it to "normal" mode
@@ -58,41 +142,106 @@ export default class Messages extends Vue {
return this.chatsel.username === username
}
- @Watch('$route.params.un')
- public changeusername() {
- this.chatsel.username = this.$route.params.un
- if (!this.miniState && tools.isMobile()) {
- this.miniState = true
+ public getLastUserChatted() {
+ const lastmsg: IMessage = MessageStore.getters.getlasts_messages().slice(-1)[0]
+ console.log('lastmsg', lastmsg)
+ if (lastmsg) {
+ return (lastmsg.origin.username !== this.getMyUsername()) ? lastmsg.origin.username : lastmsg.origin.username
+ } else {
+ return ''
}
-
- // Retrieve last msgs data from the server
- MessageStore.actions.updateMsgDataFromServer({username: this.chatsel.username, lastdataread: this.getlastdataread() } )
}
public selChat(mymsg: IMessage) {
- this.$router.replace('/messages/' + mymsg.dest.username)
+ if (this.chatsel.username !== mymsg.dest.username)
+ this.$router.replace('/messages/' + mymsg.dest.username)
+ else {
+ // refresh
+
+ this.refreshdata(this.chatsel.username)
+ }
}
- public msgchat(): IMsgUsers {
+ // @Watch('MessageStore.state.users_msg', { immediate: false, deep: true })
+ // public changemsgs(value: string, oldValue: string) {
+ // console.log('changemsgs')
+ //
+ // const myrec = MessageStore.state.users_msg.find((rec) => rec.username === this.usernameloading)
+ //
+ // console.log('myrec', myrec)
+ //
+ // if (this.users_msg_saved.length < 0)
+ // this.users_msg_saved = []
+ //
+ // this.users_msg_saved[this.usernameloading] = {...myrec}
+ // console.log('this.users_msg_saved', this.users_msg_saved[this.usernameloading])
+ // }
+
+ public msgchat(username): IMsgUsers {
// Get msg for this chat
- return MessageStore.state.users_msg.find((rec) => rec.username === this.chatsel.username)
+ return MessageStore.state.users_msg.find((rec) => rec.username === username)
+ // return this.users_msg_saved[username]
}
public msgchat_records(): IMessage[] {
- const myrec = this.msgchat()
- console.log('myrec', myrec)
+ const myrec = this.msgchat(this.chatsel.username)
+ // console.log('msgchat_records', myrec)
// Get msg for this chat
return (myrec) ? myrec.msgs : []
}
- public getlastdataread(): Date {
- const myrec = this.msgchat()
+ public getlastdataread(username): any {
+ const myrec = this.msgchat(username)
// Get msg for this chat
- return (myrec) ? tools.gettimestampByDate(myrec.lastdataread) : tools.getLastDateReadReset()
+ const lastdata = (myrec) ? myrec.lastdataread : tools.getLastDateReadReset()
+ console.table(myrec)
+ let mydate = ''
+ if (!tools.isIsoDate(lastdata))
+ mydate = lastdata.toISOString()
+ else
+ return lastdata
+
+ // console.log('getlastdataread', mydate)
+ return mydate
}
- public getMsgText(msg: IMessage) {
- return [msg.message]
+ public sendMsg() {
+ const self = this
+
+ const data: IMessage = {
+ dest: {
+ idapp: process.env.APP_ID,
+ username: this.chatsel.username
+ },
+ message: this.mytexttosend
+ }
+ data.dest.username = this.chatsel.username
+ data.message = this.mytexttosend
+
+ this.mytexttosend = ''
+
+ MessageStore.actions.SendMsgEvent(data).then((ris) => {
+ data.status = StatusMessage.Sending
+
+ const element = document.getElementById('last')
+ this.scrollToElement(element)
+
+ if (!ris)
+ tools.showNegativeNotif(self.$q, self.$t('cal.sendmsg_error'))
+
+ // tools.showPositiveNotif(self.$q, self.$t('cal.sendmsg_sent'))
+ // else
+ })
+ }
+
+ public loadMorePosts() {
+ console.log('loadMorePosts')
+ }
+
+ public myonScroll({ target: { scrollTop, clientHeight, scrollHeight }}) {
+ if (scrollTop + clientHeight >= scrollHeight) {
+ this.loadMorePosts()
+ }
}
public created() {
diff --git a/src/views/messages/messages.vue b/src/views/messages/messages.vue
index 2082d30..31948a4 100644
--- a/src/views/messages/messages.vue
+++ b/src/views/messages/messages.vue
@@ -1,5 +1,5 @@
-
+
@@ -36,14 +36,14 @@
-
+
- {{getUserByUsername(msg.dest.username)}}
+ {{getUsernameChatByMsg(msg)}}
- {{msg.message}}
+ {{getMsgText(msg, false)}}
@@ -68,62 +68,102 @@
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
- {{getUserByUsername(chatsel.username)}}
-
- {{func_tools.getDateTimeShortStr(chatsel.lasttimeActive)}}
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
+
-
+
+ {{getUserByUsername(chatsel.username)}}
+
+ {{func_tools.getDateTimeShortStr(chatsel.lasttimeActive)}}
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+