Refactor global instances of $api and $utils to be mixins.

... instead of Vue.prototype variables which is the idiomatic
approach. Also, the refactor enables utils to be instantiated
as a class that takes the i18n object for util functions to have
accesss to i18n translation.
This commit is contained in:
Kailash Nadh 2021-01-26 21:57:27 +05:30
parent afef994e6d
commit dc0465b0af
2 changed files with 46 additions and 38 deletions

View File

@ -7,37 +7,43 @@ import App from './App.vue';
import router from './router'; import router from './router';
import store from './store'; import store from './store';
import * as api from './api'; import * as api from './api';
import utils from './utils';
import { models } from './constants'; import { models } from './constants';
import Utils from './utils';
// Internationalisation. // Internationalisation.
Vue.use(VueI18n); Vue.use(VueI18n);
// Create VueI18n instance with options
const i18n = new VueI18n(); const i18n = new VueI18n();
Vue.use(Buefy, {}); Vue.use(Buefy, {});
Vue.config.productionTip = false; Vue.config.productionTip = false;
// Custom global elements. // Globals.
Vue.prototype.$api = api; const ut = new Utils(i18n);
Vue.prototype.$utils = utils; Vue.mixin({
computed: {
$utils: () => ut,
$api: () => api,
},
Vue.prototype.$reloadServerConfig = () => { methods: {
// Get the config.js <script> tag, remove it, and re-add it. $reloadServerConfig: () => {
let s = document.querySelector('#server-config'); // Get the config.js <script> tag, remove it, and re-add it.
const url = s.getAttribute('src'); let s = document.querySelector('#server-config');
s.remove(); const url = s.getAttribute('src');
s.remove();
s = document.createElement('script');
s.setAttribute('src', url);
s.setAttribute('id', 'server-config');
s.onload = () => {
store.commit('setModelResponse',
{ model: models.serverConfig, data: humps.camelizeKeys(window.CONFIG) });
};
document.body.appendChild(s);
},
},
});
s = document.createElement('script');
s.setAttribute('src', url);
s.setAttribute('id', 'server-config');
s.onload = () => {
store.commit('setModelResponse',
{ model: models.serverConfig, data: humps.camelizeKeys(window.CONFIG) });
};
document.body.appendChild(s);
};
// window.CONFIG is loaded from /api/config.js directly in a <script> tag. // window.CONFIG is loaded from /api/config.js directly in a <script> tag.
if (window.CONFIG) { if (window.CONFIG) {

View File

@ -9,21 +9,22 @@ dayjs.extend(relativeTime);
const reEmail = /(.+?)@(.+?)/ig; const reEmail = /(.+?)@(.+?)/ig;
export default class utils { export default class Utils {
static months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', constructor(i18n) {
'Sep', 'Oct', 'Nov', 'Dec']; this.i18n = i18n;
}
static days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
// Parses an ISO timestamp to a simpler form. // Parses an ISO timestamp to a simpler form.
static niceDate = (stamp, showTime) => { niceDate = (stamp, showTime) => {
if (!stamp) { if (!stamp) {
return ''; return '';
} }
const d = new Date(stamp); const d = new Date(stamp);
let out = `${utils.days[d.getDay()]}, ${d.getDate()}`; const day = this.i18n.t(`globals.days.${(d.getDay() + 1)}`);
out += ` ${utils.months[d.getMonth()]} ${d.getFullYear()}`; const month = this.i18n.t(`globals.months.${(d.getMonth() + 1)}`);
let out = `${day}, ${d.getDate()}`;
out += ` ${month} ${d.getFullYear()}`;
if (showTime) { if (showTime) {
out += ` ${d.getHours()}:${d.getMinutes()}`; out += ` ${d.getHours()}:${d.getMinutes()}`;
} }
@ -31,14 +32,12 @@ export default class utils {
return out; return out;
}; };
static duration(start, end) { duration = (start, end) => dayjs(end).from(dayjs(start), true);
return dayjs(end).from(dayjs(start), true);
}
// Simple, naive, e-mail address check. // Simple, naive, e-mail address check.
static validateEmail = (e) => e.match(reEmail); validateEmail = (e) => e.match(reEmail);
static niceNumber = (n) => { niceNumber = (n) => {
if (n === null || n === undefined) { if (n === null || n === undefined) {
return 0; return 0;
} }
@ -69,20 +68,23 @@ export default class utils {
} }
// UI shortcuts. // UI shortcuts.
static confirm = (msg, onConfirm, onCancel) => { confirm = (msg, onConfirm, onCancel) => {
Dialog.confirm({ Dialog.confirm({
scroll: 'clip', scroll: 'clip',
message: !msg ? 'Are you sure?' : msg, message: !msg ? this.i18n.t('globals.messages.confirm') : msg,
confirmText: this.i18n.t('globals.buttons.ok'),
cancelText: this.i18n.t('globals.buttons.cancel'),
onConfirm, onConfirm,
onCancel, onCancel,
}); });
}; };
static prompt = (msg, inputAttrs, onConfirm, onCancel) => { prompt = (msg, inputAttrs, onConfirm, onCancel) => {
Dialog.prompt({ Dialog.prompt({
scroll: 'clip', scroll: 'clip',
message: msg, message: msg,
confirmText: 'OK', confirmText: this.i18n.t('globals.buttons.ok'),
cancelText: this.i18n.t('globals.buttons.cancel'),
inputAttrs: { inputAttrs: {
type: 'string', type: 'string',
maxlength: 200, maxlength: 200,
@ -94,7 +96,7 @@ export default class utils {
}); });
}; };
static toast = (msg, typ, duration) => { toast = (msg, typ, duration) => {
Toast.open({ Toast.open({
message: msg, message: msg,
type: !typ ? 'is-success' : typ, type: !typ ? 'is-success' : typ,