Files
site/nova/resources/js/Nova.js

227 lines
4.6 KiB
JavaScript
Executable File
Vendored

import Vue from 'vue'
import Meta from 'vue-meta'
import store from '@/store'
import Toasted from 'vue-toasted'
import router from '@/router'
import axios from '@/util/axios'
import numbro from '@/util/numbro'
import PortalVue from 'portal-vue'
import Loading from '@/components/Loading'
import AsyncComputed from 'vue-async-computed'
import resources from '@/store/resources'
import VTooltip from 'v-tooltip'
import Mousetrap from 'mousetrap'
Vue.use(Meta)
Vue.use(PortalVue)
Vue.use(AsyncComputed)
Vue.use(VTooltip)
Vue.use(Toasted, {
router,
theme: 'nova',
position: 'bottom-right',
duration: 6000,
})
export default class Nova {
constructor(config) {
this.bus = new Vue()
this.bootingCallbacks = []
this.config = config
this.useShortcuts = true
}
/**
* Register a callback to be called before Nova starts. This is used to bootstrap
* addons, tools, custom fields, or anything else Nova needs
*/
booting(callback) {
this.bootingCallbacks.push(callback)
}
/**
* Execute all of the booting callbacks.
*/
boot() {
this.bootingCallbacks.forEach(callback => callback(Vue, router, store))
this.bootingCallbacks = []
}
/**
* Register the built-in Vuex modules for each resource
*/
registerStoreModules() {
this.config.resources.forEach(resource => {
store.registerModule(resource.uriKey, resources)
})
}
/**
* Start the Nova app by calling each of the tool's callbacks and then creating
* the underlying Vue instance.
*/
liftOff() {
let _this = this
let mousetrapDefaultStopCallback = Mousetrap.prototype.stopCallback
Mousetrap.prototype.stopCallback = function (e, element, combo) {
if (!_this.useShortcuts) {
return true
}
return mousetrapDefaultStopCallback.call(this, e, element, combo)
}
Mousetrap.init()
this.boot()
this.registerStoreModules()
this.app = new Vue({
el: '#nova',
name: 'Nova',
router,
store,
components: { Loading },
metaInfo: {
titleTemplate: `%s | ${window.config.appName}`,
},
mounted: function () {
this.$loading = this.$refs.loading
_this.$on('error', message => {
this.$toasted.show(message, { type: 'error' })
})
_this.$on('token-expired', () => {
this.$toasted.show(this.__('Sorry, your session has expired.'), {
action: {
onClick: () => location.reload(),
text: this.__('Reload'),
},
duration: null,
type: 'error',
})
})
},
})
}
/**
* Return an axios instance configured to make requests to Nova's API
* and handle certain response codes.
*/
request(options) {
if (options !== undefined) {
return axios(options)
}
return axios
}
/**
* Format a number using numbro.js for consistent number formatting.
*/
formatNumber(number, format) {
const num = numbro(number)
if (format !== undefined) {
return num.format(format)
}
return num.format()
}
/**
* Register a listener on Nova's built-in event bus
*/
$on(...args) {
this.bus.$on(...args)
}
/**
* Register a one-time listener on the event bus
*/
$once(...args) {
this.bus.$once(...args)
}
/**
* Unregister an listener on the event bus
*/
$off(...args) {
this.bus.$off(...args)
}
/**
* Emit an event on the event bus
*/
$emit(...args) {
this.bus.$emit(...args)
}
/**
* Determine if Nova is missing the requested resource with the given uri key
*/
missingResource(uriKey) {
return _.find(this.config.resources, r => r.uriKey == uriKey) == undefined
}
/**
* Show an error message to the user.
*
* @param {string} message
*/
error(message) {
Vue.toasted.show(message, { type: 'error' })
}
/**
* Show a success message to the user.
*
* @param {string} message
*/
success(message) {
Vue.toasted.show(message, { type: 'success' })
}
/**
* Show a warning message to the user.
*
* @param {string} message
*/
warning(message) {
Vue.toasted.show(message, { type: 'warning' })
}
/**
* Register a keyboard shortcut.
*/
addShortcut(keys, callback) {
Mousetrap.bind(keys, callback)
}
/**
* Unbind a keyboard shortcut.
*/
disableShortcut(keys) {
Mousetrap.unbind(keys)
}
/**
* Pause all keyboard shortcuts.
*/
pauseShortcuts() {
this.useShortcuts = false
}
/**
* Resume all keyboard shortcuts.
*/
resumeShortcuts() {
this.useShortcuts = true
}
}