Vue

by Nicke Manarin

HTML

<link rel="stylesheet" href="https://unpkg.com/buefy/dist/buefy.min.css">
<link rel="stylesheet" href="https://cdn.materialdesignicons.com/2.0.46/css/materialdesignicons.min.css">
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script src="https://unpkg.com/buefy/dist/buefy.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue-resource.min.js"></script>
<div id="app">
  <section>
    <div class="hero">
      <div class="hero-body">
        <div class="container">
          <h2 class="title is-size-3 has-text-centered">Latest Releases</h2>
          <p class="subtitle has-text-centered">All the previous releases</p>

          <b-table :data="downloads" ref="table" :loading="isLoading" hoverable detailed detail-key="version" selectable @select="toggle" paginated :per-page="perPage" :current-page.sync="currentPage" :scrollable="false" aria-next-label="Next page" aria-previous-label="Previous page" aria-page-label="Page" aria-current-label="Current page" :default-sort-direction="defaultSortOrder" :default-sort="[sortField, sortOrder]">

            <template slot-scope="props">
              <b-table-column class="is-unselectable" cell-class="has-pointer-cursor" field="version" label="Version" width="70" :custom-sort="sortVersion" sortable>
                <span class="tag" :class="versionType(props.row.is_prerelease)">
                  {{ props.row.version }}
                </span>
              </b-table-column>

              <b-table-column class="is-unselectable" cell-class="has-pointer-cursor" field="download_count" label="Download Count" sortable numeric>
                {{ props.row.download_count.toLocaleString() }}
              </b-table-column>

              <b-table-column class="is-unselectable" cell-class="has-pointer-cursor" field="release_date" label="Release Date" sortable centered>
                {{props.row.release_date ? new Date(props.row.release_date).toLocaleDateString() : "unknown"}}
     ...

CSS

// Import Bulma's core
@import "~bulma/sass/utilities/_all";

// Set your colors
//$primary: #53b4df;
//$primary: #1c9cd6;
//$primary: #2d8db8;
//$primary: #1d7ca7;

$primary: #5cadd5;
//$primary: #427a8a;
$primary-invert: findColorInvert($primary);
$white: #f8f9fa;
$black: findColorInvert($white);

// Setup $colors to use as bulma classes (e.g. 'is-twitter')
$colors: (
  "white": ($white, $black),
  "black": ($black, $white),
  "light": ($light, $light-invert),
  "dark": ($dark, $dark-invert),
  "primary": ($primary, $primary-invert),
  "info": ($info, $info-invert),
  "success": ($success, $success-invert),
  "warning": ($warning, $warning-invert),
  "danger": ($danger, $danger-invert)
);

// Import Bulma and Buefy styles
@import "~bulma";
@import "~buefy/src/scss/buefy";

//Custom global styles.
// html {
//   overflow-y: auto !important;
// }

#app {
  font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", Roboto, Oxygen,
    Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", Helvetica,
    Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

Vue

import Vue from "vue";
import VueResource from "vue-resource";
import Buefy from "buefy";

Vue.use(VueResource);
Vue.use(Buefy);

Vue.prototype.$release = {};
Vue.config.productionTip = false;

const example = {
  el: "#app",
  
  data() {
    return {
      downloads: [],
      aux: {},
      isLoading: true,
      totalDownloads: 0,
      totalDays: 0,
      sortField: "version",
      sortOrder: "desc",
      defaultSortOrder: "desc",
      currentPage: 1,
      perPage: 10
    };
  },
    
  created() {
    this.load();
  },
  
  methods: {
		sortVersion(a, b, isAsc){
      return this.compareVersion(a.version, b.version) * (isAsc ? 1 : -1);
    },
    compareVersion(versionA, versionB){
      var versionsA = versionA.split(/\./g), versionsB = versionB.split(/\./g);

      while (versionsA.length || versionsB.length) {
        var a = Number(versionsA.shift()), b = Number(versionsB.shift());

        if (a == b)
          continue;

        return (a > b || isNaN(b)) ? 1 : -1;
      }

      return -1;
    },
    isEmpty(obj) {
      for(var i in obj) 
        return false; 

      return true;
    },
    dateDiff(date1, date2) {
      var datediff = date1.getTime() - date2.getTime(); //Store the getTime diff - or +
      return datediff / (24 * 60 * 60 * 1000); //Convert values to -/+ days and return value.
    },
    since(older, newer) {
      //Years.
      var years = newer.getFullYear() - older.getFullYear();

      if (years > 0)
        return years == 1 ? "an year ago" : `${years} years ago`;

      //Months.
      var months = newer.getMonth() - older.getMonth();

      if (months > 0)
        return months == 1 ? "a month ago" : `${months} months ago`;

      //Days and weeks.
      var days = newer.getDate() - older.getDate();
      var weeks = (days / 7).toFixed(0);

      if (weeks > 0)
        return weeks == 1 ? "a week ago" : `${weeks} weeks ago`;

      if (days > 0) return days == 1 ? "a day ago" : `${days} days ago`;

      //Minutes.
    ...