Add "model index" component

at least, the beginnings of one.  a little clunky yet but seems do get the job
done...
This commit is contained in:
Lance Edgar 2019-11-06 19:27:16 -06:00
parent d87c4dfc50
commit 2c728216a1
3 changed files with 206 additions and 0 deletions

View file

@ -2,10 +2,12 @@ import ByjoveApp from './app'
import ByjoveMenu from './menu'
import ByjoveLogo from './logo'
import ByjoveFeedback from './feedback'
import ByjoveModelIndex from './model-index'
export {
ByjoveApp,
ByjoveMenu,
ByjoveLogo,
ByjoveFeedback,
ByjoveModelIndex,
}

View file

@ -0,0 +1,176 @@
<template>
<div :class="getModelSlug()">
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li>{{ getModelIndexTitle() }}</li>
</ul>
</nav>
<b-button v-if="allowCreate && hasModelPerm('create')"
class="new-object"
type="is-primary"
tag="router-link"
:to="getModelPathPrefix() + '/new'">
New {{ getModelTitle() }}
</b-button>
<slot></slot>
<b-menu>
<b-menu-list>
<b-menu-item v-for="obj in records"
:key="obj.uuid"
:label="renderLabel(obj)"
:tag="hasModelPerm('view') ? 'router-link' : 'a'"
:to="getModelPathPrefix() + '/' + obj.uuid">
</b-menu-item>
</b-menu-list>
</b-menu>
</div>
</template>
<script>
export default {
name: 'ByjoveModelIndex',
props: {
modelName: String,
modelSlug: String,
modelTitle: String,
modelTitlePlural: String,
modelIndexTitle: String,
modelPermissionPrefix: String,
modelPathPrefix: String,
labelRenderer: Function,
apiIndexUrl: String,
apiIndexSort: Object,
apiIndexFilters: Array,
allowCreate: {
type: Boolean,
default: true,
},
},
data: function() {
return {
records: [],
}
},
mounted() {
this.fetchData()
},
watch: {
'apiIndexFilters' (to, from) {
this.fetchData()
},
},
methods: {
fetchData() {
let params = {
filters: JSON.stringify(this.apiIndexFilters),
orderBy: this.apiIndexSort.field,
ascending: (this.apiIndexSort.dir == 'asc') ? 1 : 0,
}
this.$http.get(this.getApiIndexUrl(), {params: params}).then(response => {
this.records = response.data.data
}, response => {
if (response.status == 403) { // forbidden; redirect to home page
this.$buefy.toast.open({
message: "You do not have permission to access that page.",
type: 'is-danger',
position: 'is-bottom',
})
this.$router.push('/')
} else {
this.$buefy.toast.open({
message: "Failed to fetch page data!",
type: 'is-danger',
position: 'is-bottom',
})
}
})
},
getModelSlug() {
if (this.modelSlug) {
return this.modelSlug
}
return this.modelName.toLowerCase() + 's'
},
getModelTitle() {
if (this.modelTitle) {
return this.modelTitle
}
return this.modelName
},
getModelTitlePlural() {
if (this.modelTitlePlural) {
return this.modelTitlePlural
}
return this.getModelTitle() + 's'
},
getModelIndexTitle() {
if (this.modelIndexTitle) {
return this.modelIndexTitle
}
return this.getModelTitlePlural()
},
getModelPathPrefix() {
if (this.modelPathPrefix) {
return this.modelPathPrefix
}
return '/' + this.getModelSlug()
},
getApiIndexUrl() {
if (this.apiIndexUrl) {
return this.apiIndexUrl
}
return '/api/' + this.getModelSlug()
},
getModelPermissionPrefix() {
if (this.modelPermissionPrefix) {
return this.modelPermissionPrefix
}
return this.getModelSlug()
},
hasPerm(perm) {
// if user is root then assume permission
if (this.$store.state.user && this.$store.state.user.is_root) {
return true
}
// otherwise do true perm check for user
return this.$store.state.permissions.includes(perm)
},
hasModelPerm(perm) {
// do normal check, but first add prefix
let prefix = this.getModelPermissionPrefix()
return this.hasPerm(prefix + '.' + perm)
},
renderLabel(obj) {
if (this.labelRenderer) {
return this.labelRenderer(obj)
}
return obj._str
},
},
}
</script>
<style>
.new-object {
margin-bottom: 0.5rem;
}
</style>

View file

@ -0,0 +1,28 @@
// Import vue component
import ByjoveModelIndex from './ByjoveModelIndex.vue'
// Declare install function executed by Vue.use()
export function install(Vue) {
if (install.installed) return;
install.installed = true;
Vue.component('ByjoveModelIndex', ByjoveModelIndex);
}
// Create module definition for Vue.use()
const plugin = {
install,
};
// Auto-install when vue is found (eg. in browser via <script> tag)
let GlobalVue = null;
if (typeof window !== 'undefined') {
GlobalVue = window.Vue;
} else if (typeof global !== 'undefined') {
GlobalVue = global.Vue;
}
if (GlobalVue) {
GlobalVue.use(plugin);
}
// To allow use as module (npm/webpack/etc.) export component
export default ByjoveModelIndex