Trello Release Notes

by Mladen Mihajlovic

HTML

<script src="https://code.jquery.com/jquery-1.7.1.min.js"></script>
<script src="https://www.unpkg.com/[email protected]/dist/vuex.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vue-router.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://api.trello.com/1/client.js?key=df8baae0584a130f1e7372452662d14a"></script>
<link rel="stylesheet" href="https://rawgit.com/Ranks/emojione/master/extras/css/emojione-awesome.css">
<div id="App">
  <router-view></router-view>
</div>

<script type="text/x-template" id="login">
  <div>
    <div><strong>Note:</strong> This does not seem to work in IE.</div>
    <div class="btn" @click="loginUser"><a href="#"><img src="https://d2k1ftgv7pobq7.cloudfront.net/meta/u/res/images/b428584f224c42e98d158dad366351b0/trello-mark-blue.png" width="16" style="vertical-align:middle"> Click to log in to Trello</a></div>
    <div>{{errmessage}}</div>
  </div>
</script>

<script type="text/x-template" id="boards">
  <div>
    <h1>Sprint Boards</h1>
    <div class="user_bar"><div><a href="#" @click="logout" style="float:right">Logout</a></div>Logged in as <img :src="avatar"> <a :href="trello_user_link" target="_blank">{{name}}</a>. </div>
    <ul v-if="boards">
      <li v-for="b in boards" :key="b.id" class="btn">
        <router-link v-bind:to="{ name: 'board', params: { id: b.id, name: b.name } }"><i class="e1a-card_box"></i> {{b.name}}</router-link>
      </li>
    </ul>
    <div v-else>Loading trello boards...</div>
  </div>
</script>

<script type="text/x-template" id="board">
  <div>
    <div class="btn">
      <router-link to="/"><i class="e1a-back"></i> <i class="e1a-card_box"></i> Back to board list</router-link>
    </div>
    <h1>{{name}}</h1>
    <ul v-if="finalList != null">
      <li v-if="finalList.length == 0">No release note items found</li>
      <li v-for="list in finalList" :key="list.id">
        <div class="card">
          <div class="btn"...

CSS

body {
  font: 12pt "Trebuchet MS", Arial, sans-serif;
  color: #333;
}

.user_bar, .card {
  background-color : #fff;
  border-radius: 2px;
  box-shadow: 0 1px 3px rgba(0,0,0,.12), 0 1px 2px rgba(0,0,0,.24);
  padding: 15px;
  margin-bottom: 15px;
}

.user_bar {
  line-height: 30px;
}

.user_bar img {
  vertical-align: middle;
}

.user_bar a {
  color: blue;
  text-decoration: none;
}
.user_bar a:hover {
  color: blue;
   text-decoration: underline;
}
/*
a {
  color: blue;
}

a:hover {
  color: lightblue;
}

a:visited {
  color: red;
}
*/

ul {
  padding: 0;
  margin: 15px 0 0 0;
}

hr {
  width: 70%;
  margin-top: 20px;
  margin-bottom: 20px;
  border: 1px solid lightgray;
}

.card {
  padding: 5px;
}

.card:hover {
  background-color: #fff;
}

.btn {
  list-style-type: none;
  padding: 10px 14px;
  margin: 0;
}

.btn a {
  color: #000;
  bac kgr ound-color: #fff;
  text-decoration: none;
  padding: 10px 14px;
  border-radius: 2px;
  outline: 0;
  outline-offset: 0;
  border: 0;
  border-radius: 2px;
  transition: all .15s ease-in-out;
  -o-transition: all .15s ease-in-out;
  -moz-transition: all .15s ease-in-out;
  -webkit-transition: all .15s ease-in-out;
}

.btn a:hover {
  background-color: #e5e5e5;
  box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .12), 0 1px 2px 0 rgba(0, 0, 0, .24);
}

JavaScript

const login = Vue.component('login', {
  template: '#login',
  data: function() {
    return {
      errmessage: ''
    }
  },
  methods: {
    loginUser: function() {
      this.errmessage = '';

      Trello.authorize({
        type: 'popup',
        persist: true,
        success: this.success,
        error: this.err
      });
    },
    success: function() {
      router.replace('/') //go to initial route
    },
    err: function() {
      this.errmessage = 'Error logging in';
    }
  }
});

const boards = Vue.component('boards', {
  data: function() {
    return {
      boards: null,
      name: '',
      avatar: '',
      username: ''
    };
  },
  template: '#boards',
  computed: {
    trello_user_link: function() {
    	return 'https://trello.com/' + this.username;
    }
  },
  methods: {
  	logout: function() {
    	Trello.deauthorize();
      router.replace('/login');
    },
    fetchData: function() {
      let vm = this;

      Trello.members.get("me", function(member) {
        vm.name = member.fullName;
        
        //vm.avatar = 'https://trello-members.s3.amazonaws.com/' + member.avatarHash + '/30.png';
        vm.avatar = member.avatarUrl + '/30.png';
        vm.username = member.username;
      });

      Trello.get('/member/me/boards', function(response) {
        //console.dir(response);
        vm.boards = response.filter(function(board) {
          return board.name.indexOf('Sprint') > -1;
        });
      }, function(error) {
        console.log('Error getting boards', error);
      });
    }
  },
  watch: {
    // call again the method if the route changes
    '$route': 'fetchData'
  },
  created: function() {
    this.fetchData();
  }
});

const board = Vue.component('board', {
  props: ['id', 'name'],
  template: '#board',
  created: function() {
    this.fetchData();
  },
  watch: {
    '$route': 'fetchData'
  },
  data: function() {
    return {
      lists: [],
      cards: []
    };
  },
  computed: {
    finalList: function()...