Added basic Log datetime filter
This commit is contained in:
parent
d2ef43f2bb
commit
233b1cffe7
|
@ -28,7 +28,8 @@
|
|||
</template>
|
||||
</v-tooltip>
|
||||
<v-spacer />
|
||||
|
||||
<DateTimePicker v-model="dateIn" class="ma-6" label="Início" />
|
||||
<DateTimePicker v-model="dateOut" class="ma-4" label="Fim" />
|
||||
<v-checkbox v-model="polling" label="Atualizar automaticamente" />
|
||||
</v-toolbar>
|
||||
|
||||
|
@ -86,10 +87,12 @@
|
|||
<script>
|
||||
import gql from 'graphql-tag'
|
||||
import { format, subDays } from 'date-fns'
|
||||
import DateTimePicker from '../components/ui/DatetimePicker'
|
||||
|
||||
import VueJsonPretty from 'vue-json-pretty'
|
||||
|
||||
import 'vue-json-pretty/lib/styles.css'
|
||||
import DatetimePicker from '../components/ui/DatetimePicker.vue'
|
||||
|
||||
const LOGS_QUERY = gql`
|
||||
query($search: String, $dateIn: String, $dateOut: String, $limit: Int) {
|
||||
|
@ -105,7 +108,7 @@ const LOGS_QUERY = gql`
|
|||
`
|
||||
|
||||
export default {
|
||||
components: { VueJsonPretty },
|
||||
components: { VueJsonPretty, DateTimePicker },
|
||||
data: () => ({
|
||||
showLow: true,
|
||||
showInfo: true,
|
223
web/src/components/ui/DatetimePicker.vue
Normal file
223
web/src/components/ui/DatetimePicker.vue
Normal file
|
@ -0,0 +1,223 @@
|
|||
<template>
|
||||
<div>
|
||||
<v-dialog v-model="display" :width="dialogWidth">
|
||||
<template #activator="{ on }">
|
||||
<v-text-field
|
||||
v-bind="textFieldProps"
|
||||
:disabled="disabled"
|
||||
:loading="loading"
|
||||
:label="label"
|
||||
:value="formattedDatetime"
|
||||
readonly
|
||||
outlined
|
||||
v-on="on"
|
||||
>
|
||||
<template #progress>
|
||||
<slot name="progress">
|
||||
<v-progress-linear
|
||||
color="primary"
|
||||
indeterminate
|
||||
absolute
|
||||
height="2"
|
||||
></v-progress-linear>
|
||||
</slot>
|
||||
</template>
|
||||
</v-text-field>
|
||||
</template>
|
||||
|
||||
<v-card>
|
||||
<v-card-text class="px-0 py-0">
|
||||
<v-tabs v-model="activeTab" fixed-tabs>
|
||||
<v-tab key="calendar">
|
||||
<slot name="dateIcon">
|
||||
<v-icon>mdi-calendar</v-icon>
|
||||
</slot>
|
||||
</v-tab>
|
||||
<v-tab key="timer" :disabled="dateSelected">
|
||||
<slot name="timeIcon">
|
||||
<v-icon>mdi-clock</v-icon>
|
||||
</slot>
|
||||
</v-tab>
|
||||
|
||||
<v-tab-item key="calendar">
|
||||
<v-date-picker
|
||||
v-model="date"
|
||||
v-bind="datePickerProps"
|
||||
full-width
|
||||
@input="showTimePicker"
|
||||
/>
|
||||
</v-tab-item>
|
||||
<v-tab-item key="timer">
|
||||
<v-time-picker
|
||||
ref="timer"
|
||||
v-model="time"
|
||||
class="v-time-picker-custom"
|
||||
v-bind="timePickerProps"
|
||||
full-width
|
||||
></v-time-picker>
|
||||
</v-tab-item>
|
||||
</v-tabs>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<slot name="actions" :parent="this">
|
||||
<v-btn color="grey lighten-1" text @click.native="clearHandler">{{
|
||||
clearText
|
||||
}}</v-btn>
|
||||
<v-btn color="green darken-1" text @click="okHandler">{{
|
||||
okText
|
||||
}}</v-btn>
|
||||
</slot>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { format, parse } from 'date-fns'
|
||||
const DEFAULT_DATE = ''
|
||||
const DEFAULT_TIME = '00:00:00'
|
||||
const DEFAULT_DATE_FORMAT = 'yyyy-MM-dd'
|
||||
const DEFAULT_TIME_FORMAT = 'HH:mm:ss'
|
||||
const DEFAULT_DIALOG_WIDTH = 340
|
||||
const DEFAULT_CLEAR_TEXT = 'CLEAR'
|
||||
const DEFAULT_OK_TEXT = 'OK'
|
||||
export default {
|
||||
name: 'VDatetimePicker',
|
||||
model: {
|
||||
prop: 'datetime',
|
||||
event: 'input'
|
||||
},
|
||||
props: {
|
||||
datetime: {
|
||||
type: [Date, String],
|
||||
default: null
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean
|
||||
},
|
||||
loading: {
|
||||
type: Boolean
|
||||
},
|
||||
label: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
dialogWidth: {
|
||||
type: Number,
|
||||
default: DEFAULT_DIALOG_WIDTH
|
||||
},
|
||||
dateFormat: {
|
||||
type: String,
|
||||
default: DEFAULT_DATE_FORMAT
|
||||
},
|
||||
timeFormat: {
|
||||
type: String,
|
||||
default: 'HH:mm'
|
||||
},
|
||||
clearText: {
|
||||
type: String,
|
||||
default: DEFAULT_CLEAR_TEXT
|
||||
},
|
||||
okText: {
|
||||
type: String,
|
||||
default: DEFAULT_OK_TEXT
|
||||
},
|
||||
textFieldProps: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
datePickerProps: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
timePickerProps: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
display: false,
|
||||
activeTab: 0,
|
||||
date: DEFAULT_DATE,
|
||||
time: DEFAULT_TIME
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
dateTimeFormat() {
|
||||
return this.dateFormat + ' ' + this.timeFormat
|
||||
},
|
||||
defaultDateTimeFormat() {
|
||||
return DEFAULT_DATE_FORMAT + ' ' + DEFAULT_TIME_FORMAT
|
||||
},
|
||||
formattedDatetime() {
|
||||
return this.selectedDatetime
|
||||
? format(this.selectedDatetime, this.dateTimeFormat)
|
||||
: ''
|
||||
},
|
||||
selectedDatetime() {
|
||||
if (this.date && this.time) {
|
||||
let datetimeString = this.date + ' ' + this.time
|
||||
if (this.time.length === 5) {
|
||||
datetimeString += ':00'
|
||||
}
|
||||
return parse(datetimeString, this.defaultDateTimeFormat, new Date())
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
},
|
||||
dateSelected() {
|
||||
return !this.date
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
datetime: function () {
|
||||
this.init()
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.init()
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
if (!this.datetime) {
|
||||
return
|
||||
}
|
||||
let initDateTime
|
||||
if (this.datetime instanceof Date) {
|
||||
initDateTime = this.datetime
|
||||
} else if (
|
||||
typeof this.datetime === 'string' ||
|
||||
this.datetime instanceof String
|
||||
) {
|
||||
// see https://stackoverflow.com/a/9436948
|
||||
initDateTime = parse(this.datetime, this.dateTimeFormat, new Date())
|
||||
}
|
||||
this.date = format(initDateTime, DEFAULT_DATE_FORMAT)
|
||||
this.time = format(initDateTime, DEFAULT_TIME_FORMAT)
|
||||
},
|
||||
okHandler() {
|
||||
this.resetPicker()
|
||||
this.$emit('input', this.selectedDatetime)
|
||||
},
|
||||
clearHandler() {
|
||||
this.resetPicker()
|
||||
this.date = DEFAULT_DATE
|
||||
this.time = DEFAULT_TIME
|
||||
this.$emit('input', null)
|
||||
},
|
||||
resetPicker() {
|
||||
this.display = false
|
||||
this.activeTab = 0
|
||||
if (this.$refs.timer) {
|
||||
this.$refs.timer.selectingHour = true
|
||||
}
|
||||
},
|
||||
showTimePicker() {
|
||||
this.activeTab = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -81,12 +81,6 @@ export default {
|
|||
groupTitle: 'Sistema',
|
||||
|
||||
items: [
|
||||
{
|
||||
title: 'Logs',
|
||||
icon: 'mdi-clipboard-text-search',
|
||||
route: { name: 'logs' },
|
||||
role: 'superAdmin'
|
||||
},
|
||||
{
|
||||
title: 'Administração',
|
||||
icon: 'mdi-shield-account',
|
||||
|
|
|
@ -177,16 +177,6 @@ const routes = [
|
|||
import(/* webpackChunkName: "wifi-users" */ '../views/WifiUsers.vue')
|
||||
},
|
||||
|
||||
{
|
||||
path: '/logs',
|
||||
name: 'logs',
|
||||
meta: {
|
||||
title: 'Logs',
|
||||
superAdmin: true
|
||||
},
|
||||
component: () => import(/* webpackChunkName: "logs" */ '../views/Logs.vue')
|
||||
},
|
||||
|
||||
{
|
||||
path: '/system-administration',
|
||||
name: 'system-administration',
|
||||
|
|
|
@ -1,4 +1,12 @@
|
|||
<template>
|
||||
<div>
|
||||
<v-tabs v-model="tab">
|
||||
<v-tab> Logs </v-tab>
|
||||
<v-tab> Manutenção </v-tab>
|
||||
</v-tabs>
|
||||
<v-tabs-items v-model="tab">
|
||||
<v-tab-item><Logs /> </v-tab-item>
|
||||
<v-tab-item>
|
||||
<v-container>
|
||||
<v-row>
|
||||
<v-col cols="12">
|
||||
|
@ -8,23 +16,37 @@
|
|||
</v-card-title>
|
||||
|
||||
<v-card-text>
|
||||
Os usuários são importados automaticamente uma vez ao dia. Se você
|
||||
necessita que sejam atualizados agora, clique no botão abaixo.
|
||||
<v-alert color="info" class="my-4 text-justify" icon="mdi-alert">
|
||||
ATENÇÃO! O processo leva vários minutos! Não repita este processo
|
||||
em um curto espaço de tempo. Você pode acompanhar o progresso no
|
||||
log do servidor.
|
||||
Os usuários são importados automaticamente uma vez ao dia. Se
|
||||
você necessita que sejam atualizados agora, clique no botão
|
||||
abaixo.
|
||||
<v-alert
|
||||
color="info"
|
||||
class="my-4 text-justify"
|
||||
icon="mdi-alert"
|
||||
>
|
||||
ATENÇÃO! O processo leva vários minutos! Não repita este
|
||||
processo em um curto espaço de tempo. Você pode acompanhar o
|
||||
progresso no log do servidor.
|
||||
</v-alert>
|
||||
<v-alert color="warning" class="my-4 text-justify" icon="mdi-alert">
|
||||
ATENÇÃO! Não é necessário executar essa ação para atualização de
|
||||
permissões (roles). As permissões são sempre atualizadas a cada
|
||||
requisição assíncronamente.
|
||||
<v-alert
|
||||
color="warning"
|
||||
class="my-4 text-justify"
|
||||
icon="mdi-alert"
|
||||
>
|
||||
ATENÇÃO! Não é necessário executar essa ação para
|
||||
atualização de permissões (roles). As permissões são sempre
|
||||
atualizadas a cada requisição assíncronamente.
|
||||
</v-alert>
|
||||
</v-card-text>
|
||||
|
||||
<v-card-actions>
|
||||
<v-spacer />
|
||||
<v-btn color="primary" large :elevation="0" @click="importUsers">
|
||||
<v-btn
|
||||
color="primary"
|
||||
large
|
||||
:elevation="0"
|
||||
@click="importUsers"
|
||||
>
|
||||
Importar agora!
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
|
@ -35,25 +57,39 @@
|
|||
<v-card-title class="headline"> Tokens expirados </v-card-title>
|
||||
|
||||
<v-card-text>
|
||||
Tokens expirados não podem ser utilizados, porém são mantidos no
|
||||
banco de dados para consultas. Você pode apagar os tokens expirados
|
||||
usando o botão abaixo.
|
||||
Tokens expirados não podem ser utilizados, porém são mantidos
|
||||
no banco de dados para consultas. Você pode apagar os tokens
|
||||
expirados usando o botão abaixo.
|
||||
</v-card-text>
|
||||
|
||||
<v-card-actions>
|
||||
<v-spacer />
|
||||
<v-btn color="primary" large :elevation="0"> Apagar tokens </v-btn>
|
||||
<v-btn color="primary" large :elevation="0">
|
||||
Apagar tokens
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card></v-col
|
||||
>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</v-tab-item>
|
||||
</v-tabs-items>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Logs from '../components/Logs'
|
||||
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
export default {
|
||||
name: 'SystemAdministration',
|
||||
components: {
|
||||
Logs
|
||||
},
|
||||
data: () => ({
|
||||
tab: 0
|
||||
}),
|
||||
methods: {
|
||||
async importUsers() {
|
||||
const response = await this.$apollo.mutate({
|
||||
|
|
Loading…
Reference in New Issue
Block a user