diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/components/Commit.vue | 53 | ||||
-rw-r--r-- | src/components/HeaderBlue.vue (renamed from src/components/design/HeaderBlue.vue) | 0 | ||||
-rw-r--r-- | src/components/TopAuthor.vue | 16 | ||||
-rw-r--r-- | src/main.js | 5 | ||||
-rw-r--r-- | src/router.js (renamed from src/router/index.js) | 0 | ||||
-rw-r--r-- | src/sass/_bootstrap.sass | 8 | ||||
-rw-r--r-- | src/sass/_commit.sass | 106 | ||||
-rw-r--r-- | src/sass/_header.sass | 1 | ||||
-rw-r--r-- | src/sass/_variables.sass | 3 | ||||
-rw-r--r-- | src/sass/main.sass | 7 | ||||
-rw-r--r-- | src/store.js | 85 | ||||
-rw-r--r-- | src/store/index.js | 15 | ||||
-rw-r--r-- | src/views/Home.vue | 54 |
13 files changed, 333 insertions, 20 deletions
diff --git a/src/components/Commit.vue b/src/components/Commit.vue new file mode 100644 index 0000000..63e1764 --- /dev/null +++ b/src/components/Commit.vue @@ -0,0 +1,53 @@ +<template lang="pug"> + .commit(:id="data.hash") + .repo + a( + :href="'/repo/'+data.repository_url" :title="data.repository_url" + ) {{ data.repository_url }} + + .head + h5 + a(:href="'/commit/'+data.hash") {{ data.hash }} + div + span.tree tree: + h6 + a(:href="'/commit/'+data.tree") {{ data.tree }} + + .author_committer + div + img.avatar( + :src="'https://gravatar.com/avatar/'+author" + :alt="data.author_email" + ) + p Author: + b(:title="data.author_email") {{ data.author_name }} + | <{{data.author_email}}></b> + div + img.avatar( + :src="'https://gravatar.com/avatar/'+committer" + :alt="data.committer_email" + ) + p Committer: + b(:title="data.committer_email") {{ data.committer_name }} + | <{{data.committer_email}}></b> + + .text + p + | {{ first_line(data.text) }} + span.middot ยท + span.date {{ data.date | moment("ddd, D MMM YYYY HH:mm:ss ZZ") }} +</template> + +<script> +export default { + name: 'Commit', + // `author` is the hash md5 of the author's gravatar + // `committer` is the hash md5 of the committer's gravatar + props: ['data', 'author', 'committer'], + methods: { + first_line(text) { + return text.split('\n')[0] + } + } +} +</script> diff --git a/src/components/design/HeaderBlue.vue b/src/components/HeaderBlue.vue index fd6d731..fd6d731 100644 --- a/src/components/design/HeaderBlue.vue +++ b/src/components/HeaderBlue.vue diff --git a/src/components/TopAuthor.vue b/src/components/TopAuthor.vue new file mode 100644 index 0000000..e8a0241 --- /dev/null +++ b/src/components/TopAuthor.vue @@ -0,0 +1,16 @@ +<template lang="pug"> + .top-author + .user + img(:src="'https://gravatar.com/avatar/'+avatar" :alt="data.author_email") + strong(:title="data.author_email") + | {{ data.author_name }} <{{ data.author_email }}> + .number + h2 {{ data.num }} +</template> + +<script> +export default { + name: "TopAuthor", + props: ['data', 'avatar'], +} +</script> diff --git a/src/main.js b/src/main.js index 1329a63..a05771b 100644 --- a/src/main.js +++ b/src/main.js @@ -1,12 +1,13 @@ import Vue from 'vue'; import App from './App.vue'; -import router from './router'; -import store from './store'; +import router from '@/router.js'; +import store from '@/store.js'; import { BootstrapVue } from 'bootstrap-vue'; Vue.config.productionTip = false; Vue.use(BootstrapVue); +Vue.use(require('vue-moment')); new Vue({ router, diff --git a/src/router/index.js b/src/router.js index 5dc4e51..5dc4e51 100644 --- a/src/router/index.js +++ b/src/router.js diff --git a/src/sass/_bootstrap.sass b/src/sass/_bootstrap.sass index 755ffb1..c83c1eb 100644 --- a/src/sass/_bootstrap.sass +++ b/src/sass/_bootstrap.sass @@ -1,8 +1,14 @@ @import "_variables.sass"; -h1 +h1, h2, h3 font-family: $font-family-big +h1 + font-size: 3em + +h2 + font-size: 2em + @mixin breakpoint($point) @if $point == desktop @media (min-width: 70em) diff --git a/src/sass/_commit.sass b/src/sass/_commit.sass new file mode 100644 index 0000000..d59afa0 --- /dev/null +++ b/src/sass/_commit.sass @@ -0,0 +1,106 @@ +@import "_bootstrap.sass"; + +.commit + border-bottom: #ccc 1px solid + padding: 20px 10px + margin: 0 + &:hover + background-color: darken(#fbfcfc, 3%) + .head + > div + span + color: #9f9ca5 + @include breakpoint(phablet) + margin-right: 8px + h6 a + color: $secondary + font-weight: 100 + span + float: left + .author_committer + display: grid + grid-template-columns: 50% 50% + align-items: center + justify-items: center + @include breakpoint(phablet) + grid-template-columns: 100% + div + width: 100% + @include breakpoint(phablet) + &:first-child + padding-bottom: 10px + .avatar + width: 30px + float: left + margin-right: 5px + p + margin: 0 + line-height: 30px + overflow: hidden + height: 30px + text-overflow: ellipsis + white-space: nowrap + padding-right: 5px + h5, h6 + font-weight: bold + font-family: $font-family-mono + font-size: 2em + a + color: $primary + text-decoration: underline + @include breakpoint(phablet) + overflow: hidden + width: 111px + display: block + + h6 + font-size: 1em + a + line-height: 24px + margin-left: 5px + @include breakpoint(phablet) + width: 56px + + + .text + p + margin: 5px 0 0 + span.middot + margin: 0 10px + color: #ccc + span.date + color: $secondary + white-space: pre + display: inline-block + + .repo a + color: #fff + text-decoration: none !important + background: $primary + padding: 3px + float: right + max-width: 200px + overflow: hidden + text-overflow: ellipsis + white-space: nowrap + border-radius: 2px + @include breakpoint(phablet) + max-width: 180px + +.top-author + display: grid + grid-template-columns: 80% 20% + .user + display: flex + img + width: 30px + height: 30px + margin-right: 5px + strong + text-overflow: ellipsis + white-space: nowrap + overflow: hidden + + .number + justify-self: end + color: $secondary diff --git a/src/sass/_header.sass b/src/sass/_header.sass index 33f9271..e64a031 100644 --- a/src/sass/_header.sass +++ b/src/sass/_header.sass @@ -5,6 +5,7 @@ header color: $color-w padding: 10px 0 box-shadow: rgba(0, 0, 0, 0.2) 0 2px 0px + margin-bottom: 30px h1 font-size: 3em margin: 0 diff --git a/src/sass/_variables.sass b/src/sass/_variables.sass index e716c3c..b13c03e 100644 --- a/src/sass/_variables.sass +++ b/src/sass/_variables.sass @@ -2,9 +2,10 @@ @import url('https://fonts.googleapis.com/css2?family=Ubuntu:wght@400;700&display=swap'); $font-family: "Ubuntu", sans-serif +$font-family-mono: "Ubuntu Mono", "Ubuntu", sans-serif $font-family-big: "Bebas Neue", corsive $primary: #34495e -$secondary: #e8a83c +$secondary: #d35400 $color-w: #fafafa diff --git a/src/sass/main.sass b/src/sass/main.sass index 18b025a..deab05d 100644 --- a/src/sass/main.sass +++ b/src/sass/main.sass @@ -1,6 +1,13 @@ @import "_header.sass"; +@import "_commit.sass"; body color: #2c3e50 font-family: $font-family background-color: #fbfcfc + +#home + @include breakpoint(phablet) + flex-direction: column-reverse + > div + margin-bottom: 42px diff --git a/src/store.js b/src/store.js new file mode 100644 index 0000000..79bdaff --- /dev/null +++ b/src/store.js @@ -0,0 +1,85 @@ +import Vue from 'vue' +import Vuex from 'vuex' + +Vue.use(Vuex) + +export default new Vuex.Store({ + state: { + api: process.env.VUE_APP_BACKEND_URL, + loading: false, + loading_top_authors: false, + commits: [], + top_authors: [], + emails: {}, + }, + getters: { + loading: state => { + return state.loading + }, + loading_top_authors: state => { + return state.loading_top_authors + }, + commits: state => { + return state.commits + }, + top_authors: state => { + return state.top_authors + }, + emails: state => { + return state.emails + }, + }, + mutations: { + loading_state: (state, value) => { + state.loading = value + }, + loading_top_authors_state: (state, value) => { + state.loading_top_authors = value + }, + load_commits: (state, value) => { + state.commits = value + }, + load_top_authors: (state, value) => { + state.top_authors = value + }, + load_emails: (state, value) => { + state.emails = value + }, + }, + actions: { + // Get all commits from the api backend + async get_commits({commit}) { + commit('loading_state', true) + await fetch(`${this.state.api}/commit/`) + .then(async response => { + commit('load_commits', await response.json()); + }) + commit('loading_state', false) + }, + // Get all emails and map them like an hash + async get_emails({commit}) { + await fetch(`${this.state.api}/email/`) + .then(async response => { + const emails_list = await response.json(); + const emails_obj = emails_list + .reduce((dict, elem) => { + dict[elem['email']] = elem['hash_md5'] + return dict; + }, {}) + + commit('load_emails', emails_obj); + }) + }, + /// Get the ranking of commits authors + async get_top_authors({commit}) { + commit('loading_top_authors_state', true) + await fetch(`${this.state.api}/commit/top/`) + .then(async response => { + commit('load_top_authors', await response.json()); + }) + commit('loading_top_authors_state', false) + } + }, + modules: { + } +}) diff --git a/src/store/index.js b/src/store/index.js deleted file mode 100644 index 332b916..0000000 --- a/src/store/index.js +++ /dev/null @@ -1,15 +0,0 @@ -import Vue from 'vue' -import Vuex from 'vuex' - -Vue.use(Vuex) - -export default new Vuex.Store({ - state: { - }, - mutations: { - }, - actions: { - }, - modules: { - } -}) diff --git a/src/views/Home.vue b/src/views/Home.vue index 55c3c08..49e42b3 100644 --- a/src/views/Home.vue +++ b/src/views/Home.vue @@ -1,15 +1,67 @@ <template lang="pug"> main header-blue + b-container + b-row#home + b-col(md="8" sm="12") + h2 List of commits + section#commits + .commit(style="padding: 50px" v-if="loading") + b-overlay(:show="true" spinner-large) + commit-card( + v-else + v-for="i in commits" :key="i.hash" :data="i" + :author="emails[i.author_email]" + :committer="emails[i.committer_email]" + ) + b-col(md="4" sm="12") + h2 Top authors + b-list-group + b-list-group-item(v-if="loading_top_authors") + b-overlay(:show="true" spinner-large) + b-list-group-item( + v-else v-for="author in top_authors.slice(0, 7)" :key="author.email" + button + ) + author( + :data="author" + :avatar="emails[author.author_email]" + ) </template> <script> -import HeaderBlue from '@/components/design/HeaderBlue'; +import HeaderBlue from '@/components/HeaderBlue'; +import Commit from '@/components/Commit'; +import TopAuthor from '@/components/TopAuthor'; export default { name: "Home", components: { 'header-blue': HeaderBlue, + 'commit-card': Commit, + 'author': TopAuthor, + }, + mounted() { + this.$store.dispatch('get_commits'); + this.$store.dispatch('get_emails'); + this.$store.dispatch('get_top_authors'); + }, + computed: { + commits: function() { + return this.$store.getters.commits; + }, + emails: function() { + return this.$store.getters.emails; + }, + top_authors: function() { + return this.$store.getters.top_authors; + }, + loading: function() { + return this.$store.getters.loading; + }, + loading_top_authors: function() { + return this.$store.getters.loading_top_authors; + } } } </script> |