Skip to content

Instantly share code, notes, and snippets.

@IgorDePaula
Created March 24, 2018 18:27
Show Gist options
  • Save IgorDePaula/505d684d3c2b481a5b9044a4a28a8704 to your computer and use it in GitHub Desktop.
Save IgorDePaula/505d684d3c2b481a5b9044a4a28a8704 to your computer and use it in GitHub Desktop.
export default (props, component) => ({
render (h) {
return h(component, { props })
}
})
<template>
<div>
<v-card width="100%">
<v-card-title>
<h1>{{name}}</h1>
<v-spacer></v-spacer>
<v-text-field
append-icon="search"
label="Pesquisar"
single-line
hide-details
v-model="search"
></v-text-field>
<v-btn
color="primary"
dark
depressed
@click.stop="dialog = !dialog">
<v-icon>add</v-icon>
</v-btn>
</v-card-title>
<v-data-table
:headers="headers"
:items="items"
:loading="loading"
class="elevation-1"
:expand="true"
:total-items="totalItems"
:pagination.sync="pagination">
<template slot="items" slot-scope="props">
<tr>
<component v-bind="field" v-on="onOptions" :key="index++"
v-for="(field, index) in headers" :model="getValue(props.item, field.value)"
:is="field.type"></component>
</tr>
</template>
<v-progress-linear slot="progress" color="blue" indeterminate></v-progress-linear>
<template slot="no-data">
<v-alert :value="true" color="error" icon="warning">
Desculpe, nenhuma informação a ser mostrada =(
</v-alert>
</template>
</v-data-table>
</v-card>
<pop-window @saved="reload" :name="name" :model="model" :endpoint="endpoint" :schema="formSchema"
:dialog="dialog"
@closePopWindow="dialog = !dialog"></pop-window>
</div>
</template>
<script>
import Options from './Options'
import PopWindow from './PopWindow'
import TdView from '../Support/TDView'
export default {
name: 'grid',
components: {Options, PopWindow, TdView},
props: {
name: {
required: true,
type: String
},
endpoint: {
required: true,
type: String
},
headers: {
required: true,
type: Array
},
formSchema: {
required: true,
type: Object
}
},
data() {
return {
search: '',
pagination: {},
items: [],
dialog: false,
loading: true,
totalItems: 0,
model: {},
index:0,
onOptions:{}
}
},
watch: {
pagination: {
handler() {
const {sortBy, descending, page, rowsPerPage} = this.pagination
this.getDataFromApi(sortBy, descending, page, rowsPerPage, this.search)
},
deep: true
},
search: {
handler() {
const {sortBy, descending, page, rowsPerPage} = this.pagination
this.getDataFromApi(sortBy, descending, page, rowsPerPage, this.search)
}
}
},
mounted() {
const {sortBy, descending, page, rowsPerPage} = this.pagination
this.getDataFromApi(sortBy, descending, page, rowsPerPage, this.search)
this.model = this.formSchema.model
this.getOns()
},
methods: {
getedModel(model) {
console.log(model)
this.model = model
this.dialog = true
},
getOns(){
let self = this
this.headers.forEach(item => {
if(item.hasOwnProperty('on')){
this.onOptions = item.on(this)
}
})
},
reload() {
const {sortBy, descending, page, rowsPerPage} = this.pagination
this.getDataFromApi(sortBy, descending, page, rowsPerPage, this.search)
},
getDataFromApi(sortBy, descending, page, rowsPerPage, search) {
const params = {
page: page,
sortBy: sortBy,
descending: descending,
perPage: rowsPerPage,
search: search
}
this.$http.get(this.endpoint, {params: params}).then(this.fillItens).catch(this.catchErrors)
},
catchErrors(e) {
console.log(e)
this.loading = false
},
fillItens(data) {
this.items = data.data.data
this.loading = false
this.totalItems = data.data.total
this.pagination.rowsPerPage = data.data.per_page
},
getValue(col, val) {
if(!val){
return col
}
return _.get(col, val)
}
}
}
</script>
import factory from '../factory'
import Grid from '../Grid'
let props = {
name: 'Cursos',
headers: [{
text: '#',
align: 'left',
sortable: false,
value: 'id',
type: 'td-view',
class: 'text-xs-right'
}, {
text: 'Nome',
align: 'left',
sortable: false,
value: 'name',
type: 'td-view',
class: ''
}, {
text: 'Sigla',
align: 'left',
sortable: false,
value: 'initials',
type: 'td-view',
class: ''
}, {
text: 'Opções',
align: 'left',
sortable: false,
value: '',
type: 'options',
class: '',
options: $this => {
return [
{icon: 'contacts', title: 'Keep', handler: item => $this.$emit('selectedModel', item)},
{icon: 'history', title: 'Inbox', handler: item => console.log(JSON.stringify(item))},
{icon: 'content_copy', title: 'Hangouts', handler: item => $this.$router.push('/disciplines')},
{icon: 'add', title: 'Messenger', handler: item => console.log(JSON.stringify(item))},
{icon: 'settings', title: 'Google+', handler: item => console.log(JSON.stringify(item))}
]
},
on: ($this) => {
return {
selectedModel: (model) => $this.getedModel(model)
}
}
}
],
endpoint: '/curse',
formSchema: {
schema: [
{
name: 'name',
label: 'Nome',
value: '',
class: '',
type: 'v-text-field',
rules: [
v => !!v || 'É obrigatório'
]
},
{
name: 'initials',
label: 'Sigla',
value: '',
class: '',
type: 'v-text-field',
rules: [
v => !!v || 'É obrigatório'
]
},
{
name: 'value',
label: 'Valor (R$)',
class: '',
type: 'v-text-field',
rules: [
v => !!v || 'É obrigatório'
]
},
{
name: 'program',
label: 'Programa',
value: '',
textarea: true,
class: '',
type: 'v-text-field',
rules: [
v => !!v || 'É obrigatório'
]
},
{
name: 'objective',
label: 'Objetivos',
value: '',
textarea: true,
class: '',
type: 'v-text-field',
rules: [
v => !!v || 'É obrigatório'
]
},
{
name: 'public',
label: 'Público',
value: '',
textarea: true,
class: '',
type: 'v-text-field',
rules: [
v => !!v || 'É obrigatório'
]
},
{
name: 'teaser',
label: 'Teaser',
value: '',
class: '',
type: 'v-text-field',
rules: [
v => !!v || 'É obrigatório'
]
},
{
name: 'ambit_id',
label: 'Âmbito',
class: '',
type: 'v-select',
rules: [
v => !!v || 'É obrigatório',
],
items: [],
uri: '/ambit',
loading: true,
'item-text': 'name',
'item-value': 'id'
}
],
model:
{
id: 0,
name: '',
initials: '',
value: '',
program: '',
objective: '',
public: '',
teaser: '',
ambit_id: ''
}
}
}
export default factory(props, Grid)
<template>
<v-menu offset-y>
<v-btn color="primary" dark slot="activator">Opções</v-btn>
<v-list>
<v-list-tile v-for="(item, key) in elements" :key="key" @click="">
<v-list-tile-title @click="click(item, $event)">
<v-icon>{{item.icon}}</v-icon>
{{ item.title }}</v-list-tile-title>
</v-list-tile>
</v-list>
</v-menu>
</template>
<script>
export default {
name: "options",
props:{
options:{
required: true
},
model:{
required: true
}
},
data(){
return {
elements: []
}
},
methods: {
click(item, $event) {
$event.preventDefault();
item.handler(this.model);
},
renderElements() {
if (typeof this.options === "function") {
this.elements = this.options(this);
return;
}
if (Array.isArray(this.options)) {
this.elements = this.options;
return;
}
this.elements = [];
}
},
created(){
this.renderElements()
}
}
</script>
<template>
<v-dialog
v-model="dialog"
fullscreen
transition="dialog-bottom-transition"
:overlay="false"
scrollable
>
<v-card tile>
<v-toolbar card dark color="primary">
<v-btn icon @click.native="close()" dark>
<v-icon>close</v-icon>
</v-btn>
<v-toolbar-title>{{name}}</v-toolbar-title>
<v-spacer></v-spacer>
<v-toolbar-items>
<v-btn dark flat @click.native="save($event)">Save</v-btn>
</v-toolbar-items>
</v-toolbar>
<v-card-text>
<component v-bind="comp" :key="index" v-for="(comp, index) in schema.schema"
:rules="comp.rules"
v-model="model[comp.name]" :is="comp.type"></component>
</v-card-text>
</v-card>
</v-dialog>
</template>
<script>
export default {
name: "pop-window",
props: {
dialog: {
required: true,
type: Boolean
},
schema: {
required: true,
type: [Array, Object]
},
name: {
required: true,
type: String
},
model: {
required: true,
type: Object
},
endpoint: {
required: true,
type: String
}
},
data() {
return {
widgets: {},
sound: {},
notifications: {},
items: [],
uri: '',
elements: []
}
},
computed: {
opened() {
return this.dialog
}
},
methods: {
renderSelect(schema) {
let self = this
schema.forEach(s => {
if (s.hasOwnProperty('uri')) {
self.$http.get(s.uri).then((result) => {
s.items = result.data
s.loading = false
})
}
})
},
close() {
this.$emit('closePopWindow')
},
fillItens(data) {
this.items = data.data.data
},
save($event) {
let model = this.model
if (model.id > 0) {
this.$http.put(`${this.endpoint}/${model.id}`, model);
}
if (model.id == 0) {
this.$http.post(this.endpoint, model)
}
this.$emit('saved')
this.close()
}
},
created() {
this.renderSelect(this.schema.schema)
}
}
</script>
<template>
<td>{{model}}</td>
</template>
<script>
export default {
name: "td-view",
props:{
model:{
required: true,
type: [Object, String, Number]
}
}
}
</script>
<style scoped>
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment