You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
CoreID/app/assets/app/cobalt/Listing.component.js

124 lines
4.6 KiB

import { Component } from '../../lib/vues6/vues6.js'
import { action_service } from '../service/Action.service.js'
import { message_service } from '../service/Message.service.js'
import { resource_service } from '../service/Resource.service.js'
const template = `
<div>
<span v-if="!can_access">
<div class="row m-5">
<div class="col-12 text-center">
<h4 class="pad-top">{{ access_msg }}</h4>
</div>
</div>
</span>
<span v-if="can_access">
<div class="row mb-4">
<div class="col-8"><h3>{{ resource_class.plural }}</h3></div>
<div class="col-4 text-right" v-if="definition.actions">
<button
:class="['mr-2', 'btn', 'btn-'+(action.color || 'secondary'), 'btn-sm']"
type="button"
v-for="action of definition.actions"
@click="perform($event, action)"
v-if="action.position === 'main'"
>{{ action.text }}</button>
</div>
</div>
<div class="row mb-4" v-if="definition.display">
<div class="col-12" v-html="definition.display"></div>
</div>
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col" v-for="col of definition.columns">{{ col.name }}</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr v-for="(row, index) of data">
<th scope="row">{{ index + 1 }}</th>
<td v-for="col of definition.columns">
<span v-if="typeof col.renderer === 'function'">{{ col.renderer(row[col.field]) }}</span>
<span v-if="col.renderer === 'boolean'">{{ row[col.field] ? 'Yes' : 'No' }}</span>
<span v-if="col.renderer !== 'boolean' && typeof col.renderer !== 'function'">{{ col.field in row ? row[col.field] : '-' }}</span>
</td>
<td>
<button
type="button"
:class="['mr-2', 'btn', 'btn-sm', 'btn-'+(action.color || 'secondary')]"
v-for="action of definition.actions"
v-if="action.position === 'row'"
@click="perform($event, action, row)"
><i :class="action.icon" v-if="action.icon"></i> {{ action.text }}</button>
</td>
</tr>
</tbody>
</table>
</span>
</div>
`
export default class ListingComponent extends Component {
static get selector() { return 'cobalt-listing' }
static get template() { return template }
static get props() { return ['resource'] }
definition = {}
data = []
resource_class = {}
access_msg = ''
can_access = false
async vue_on_create() {
// Load the resource
this.resource_class = await resource_service.get(this.resource)
// Make sure we have permission
if ( !(await this.resource_class.can('list')) ) {
this.access_msg = 'Sorry, you do not have permission to view this resource.'
this.can_access = false
return
} else {
this.access_msg = ''
this.can_access = true
}
await this.load()
}
async load() {
this.definition = this.resource_class.listing_definition
this.data = await this.resource_class.list()
}
async perform($event, action, row = undefined) {
if ( action.confirm ) {
message_service.modal({
title: 'Are you sure?',
message: `You are about to ${action.action}${row ? ' this '+this.resource_class.item : ''}. Do you want to continue?`,
buttons: [
{
text: 'Cancel',
type: 'close',
},
{
text: 'Continue',
class: ['btn', 'btn-primary'],
type: 'close',
on_click: async () => {
await action_service.perform({...action, resource: this.resource, ...(row ? {id: row.id} : {})})
await this.load()
},
},
],
})
} else {
await action_service.perform({...action, resource: this.resource, ...(row ? {id: row.id} : {})})
await this.load()
}
}
}