浏览代码

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.
Kailash Nadh 4 年之前
父节点
当前提交
dc0465b0af
共有 2 个文件被更改,包括 48 次插入40 次删除
  1. 28 22
      frontend/src/main.js
  2. 20 18
      frontend/src/utils.js

+ 28 - 22
frontend/src/main.js

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

+ 20 - 18
frontend/src/utils.js

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