First stuff works
Show a list of active GitLab projects.
This commit is contained in:
parent
cc0337cec2
commit
47f3db0834
10 changed files with 270 additions and 80 deletions
|
@ -1,5 +1,7 @@
|
|||
# git-dashboard
|
||||
|
||||
**WARNING: THIS IS ALPHA SOFTWARE! DO NOT USE IT! IF YOU DO, IT IS ON YOUR OWN RISK! IT MAY DESTROY YOUR COMPUTER, BURN YOUR HOUSE AND KILL YOUR KITTEN**
|
||||
|
||||
## Project setup
|
||||
```
|
||||
yarn install
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"bulma": "^0.9.3",
|
||||
"core-js": "^3.6.5",
|
||||
"vue": "^3.0.0"
|
||||
},
|
||||
|
|
|
@ -6,12 +6,17 @@
|
|||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.3/css/bulma.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<div id="app"></div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
||||
|
|
75
src/App.vue
75
src/App.vue
|
@ -1,27 +1,68 @@
|
|||
<template>
|
||||
<img alt="Vue logo" src="./assets/logo.png">
|
||||
<HelloWorld msg="Welcome to Your Vue.js + TypeScript App"/>
|
||||
<h1 class="title">My GitLab Dashboard</h1>
|
||||
<gitlab-auth
|
||||
v-if="!authorized"
|
||||
@authTokenSubmit="authTokenSubmit"
|
||||
:auth-error="authError"
|
||||
></gitlab-auth>
|
||||
<div v-if="authorized" class="columns">
|
||||
<div class="column is-one-quarter">
|
||||
<gitlab-user :gitlabToken="gitlabToken"></gitlab-user>
|
||||
</div>
|
||||
<div class="column">
|
||||
<gitlab-projects
|
||||
:gitlabToken="gitlabToken"
|
||||
:gitlabId="gitlabId"
|
||||
></gitlab-projects>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import HelloWorld from './components/HelloWorld.vue';
|
||||
import { defineComponent } from "vue";
|
||||
import GitlabAuth from "./components/GitlabAuth.vue";
|
||||
import GitlabUser from "./components/GitlabUser.vue";
|
||||
import GitlabProjects from "./components/GitlabProjects.vue";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'App',
|
||||
name: "App",
|
||||
components: {
|
||||
HelloWorld
|
||||
GitlabAuth,
|
||||
GitlabUser,
|
||||
GitlabProjects,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
gitlabToken: "",
|
||||
gitlabId: 0,
|
||||
authorized: false, // temp property, should be replaced by an empty gitlabToken
|
||||
authError: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
authTokenSubmit(authToken: string) {
|
||||
if (!authToken) return;
|
||||
|
||||
fetch("https://gitlab.com/api/v4/user", {
|
||||
headers: {
|
||||
"PRIVATE-TOKEN": authToken,
|
||||
},
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
if (data.id) {
|
||||
this.gitlabId = data.id;
|
||||
} else {
|
||||
throw new Error("Auth token not valid");
|
||||
}
|
||||
this.gitlabToken = authToken;
|
||||
this.authorized = true;
|
||||
})
|
||||
.catch((Error) => {
|
||||
console.log(Error);
|
||||
this.authError = true;
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
#app {
|
||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-align: center;
|
||||
color: #2c3e50;
|
||||
margin-top: 60px;
|
||||
}
|
||||
</style>
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 6.7 KiB |
48
src/components/GitlabAuth.vue
Normal file
48
src/components/GitlabAuth.vue
Normal file
|
@ -0,0 +1,48 @@
|
|||
<template>
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<p class="title is-4">GitLab Authentication required</p>
|
||||
<p class="mb-5">
|
||||
Please create a GitLab authentication token over at
|
||||
<a
|
||||
href="https://gitlab.com/-/profile/personal_access_tokens"
|
||||
taget="blank"
|
||||
>GitLab.com</a
|
||||
>
|
||||
(API scope is enought) and enter it here. Attention: Currently the token
|
||||
is not stored in any way by this app so it is recommended to save in a
|
||||
safe place e.g. a password store for the next use.
|
||||
</p>
|
||||
<div class="field has-addons has-addons-centered">
|
||||
<p class="control">
|
||||
<input
|
||||
@keyup.enter="$emit('authTokenSubmit', authToken)"
|
||||
v-model="authToken"
|
||||
class="input"
|
||||
type="text"
|
||||
placeholder="GitLab Access Token"
|
||||
/>
|
||||
</p>
|
||||
<p class="control">
|
||||
<a @click="$emit('authTokenSubmit', authToken)" class="button is-primary">Submit</a>
|
||||
</p>
|
||||
</div>
|
||||
<div v-if="authError" class="notification is-danger">
|
||||
<strong>Authentication failed!</strong> Please double check your authentication token.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "GitlabAuth",
|
||||
props: ['authError'],
|
||||
emits: ['authTokenSubmit'],
|
||||
data() {
|
||||
return {
|
||||
authToken: ""
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
93
src/components/GitlabProjects.vue
Normal file
93
src/components/GitlabProjects.vue
Normal file
|
@ -0,0 +1,93 @@
|
|||
<template>
|
||||
<div class="box">
|
||||
<h3 class="title is-3">Active Projects</h3>
|
||||
<article
|
||||
v-for="project in projects"
|
||||
class="media"
|
||||
:href="project.web_url"
|
||||
:key="project"
|
||||
>
|
||||
<div class="media-left" v-if="project.avatar_url">
|
||||
<figure class="image is-64x64">
|
||||
<img :src="project.avatar_url" />
|
||||
</figure>
|
||||
</div>
|
||||
<div class="media-content">
|
||||
<div class="content">
|
||||
<h5 class="subtitle is-5 is-spaced">{{ project.name }}</h5>
|
||||
<div class="tags" v-if="project.topics">
|
||||
<span
|
||||
v-for="topic in project.topics"
|
||||
:key="topic"
|
||||
class="tag is-link"
|
||||
>{{ topic }}</span
|
||||
>
|
||||
</div>
|
||||
<small>Last activity: {{ project.last_activity_at }}</small>
|
||||
<p v-if="project.description">{{ project.description }}</p>
|
||||
<p v-if="project.issues_enabled && project.open_issues_count">
|
||||
{{ project.open_issues_count }} open issues
|
||||
</p>
|
||||
<div class="buttons">
|
||||
<a
|
||||
target="blank"
|
||||
:href="project.web_url"
|
||||
class="button is-primary is-rounded"
|
||||
>Visit</a
|
||||
>
|
||||
<a
|
||||
target="blank"
|
||||
:href="`${project.web_url}/-/issues`"
|
||||
class="button is-rounded"
|
||||
>Issues</a
|
||||
>
|
||||
<a
|
||||
target="blank"
|
||||
:href="`${project.web_url}/-/merge_requests`"
|
||||
class="button is-rounded"
|
||||
>Merge Requests</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "GitlabProjects",
|
||||
props: {
|
||||
gitlabToken: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
gitlabId: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
projects: {},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
fetch(
|
||||
`https://gitlab.com/api/v4/users/${this.gitlabId}/projects?archived=false&order_by=last_activity_at`,
|
||||
{
|
||||
headers: {
|
||||
"PRIVATE-TOKEN": this.gitlabToken,
|
||||
},
|
||||
}
|
||||
)
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
this.projects = data;
|
||||
})
|
||||
.catch((Error) => {
|
||||
console.log(Error);
|
||||
});
|
||||
},
|
||||
};
|
||||
</script>
|
56
src/components/GitlabUser.vue
Normal file
56
src/components/GitlabUser.vue
Normal file
|
@ -0,0 +1,56 @@
|
|||
<template>
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<figure class="image is-4by4">
|
||||
<img :src="user.avatar_url" alt="Profile Picture" />
|
||||
</figure>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<p class="title is-4"><a :href="user.web_url">{{ user.name }}</a></p>
|
||||
<p class="subtitle is-6">{{ user.username }}</p>
|
||||
<div class="content">
|
||||
{{ user.bio }}
|
||||
</div>
|
||||
</div>
|
||||
<footer class="card-footer">
|
||||
<p class="card-footer-item">
|
||||
<span>{{ user.location }}</span>
|
||||
</p>
|
||||
<p class="card-footer-item">
|
||||
<span><a :href="user.website_url">{{ user.website_url_nice }}</a></span>
|
||||
</p>
|
||||
</footer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "GitlabUser",
|
||||
props: {
|
||||
gitlabToken: {
|
||||
type: String,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
user: {}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
fetch("https://gitlab.com/api/v4/user", {
|
||||
headers: {
|
||||
"PRIVATE-TOKEN": this.gitlabToken
|
||||
},
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
this.user = data;
|
||||
this.user.website_url_nice = this.user.website_url.substring(8);
|
||||
})
|
||||
.catch((Error) => {
|
||||
console.log(Error);
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
|
@ -1,61 +0,0 @@
|
|||
<template>
|
||||
<div class="hello">
|
||||
<h1>{{ msg }}</h1>
|
||||
<p>
|
||||
For a guide and recipes on how to configure / customize this project,<br>
|
||||
check out the
|
||||
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
|
||||
</p>
|
||||
<h3>Installed CLI Plugins</h3>
|
||||
<ul>
|
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-typescript" target="_blank" rel="noopener">typescript</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
|
||||
</ul>
|
||||
<h3>Essential Links</h3>
|
||||
<ul>
|
||||
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
|
||||
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
|
||||
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
|
||||
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
|
||||
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
|
||||
</ul>
|
||||
<h3>Ecosystem</h3>
|
||||
<ul>
|
||||
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
|
||||
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
|
||||
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
|
||||
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'HelloWorld',
|
||||
props: {
|
||||
msg: String,
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped lang="scss">
|
||||
h3 {
|
||||
margin: 40px 0 0;
|
||||
}
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
li {
|
||||
display: inline-block;
|
||||
margin: 0 10px;
|
||||
}
|
||||
a {
|
||||
color: #42b983;
|
||||
}
|
||||
</style>
|
|
@ -2419,6 +2419,11 @@ builtin-status-codes@^3.0.0:
|
|||
resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
|
||||
integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=
|
||||
|
||||
bulma@^0.9.3:
|
||||
version "0.9.3"
|
||||
resolved "https://registry.yarnpkg.com/bulma/-/bulma-0.9.3.tgz#ddccb7436ebe3e21bf47afe01d3c43a296b70243"
|
||||
integrity sha512-0d7GNW1PY4ud8TWxdNcP6Cc8Bu7MxcntD/RRLGWuiw/s0a9P+XlH/6QoOIrmbj6o8WWJzJYhytiu9nFjTszk1g==
|
||||
|
||||
bytes@3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
|
||||
|
|
Reference in a new issue