Compare commits
12 Commits
dependabot
...
master
Author | SHA1 | Date |
---|---|---|
elee | 0cd11ce578 | |
elee | 583dd58e20 | |
elee | 4d32019249 | |
elee | 81a2faf4ab | |
elee | d1b067e81b | |
elee | 9c4598973d | |
elee | 8794196988 | |
elee | 7de411662d | |
Simone Gotti | 77f7af09ab | |
Simone Gotti | 3f2c57394a | |
Simone Gotti | ca0c494425 | |
Simone Gotti | 5086f0a4ec |
|
@ -77,7 +77,8 @@ local task_build(version, arch) = {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
environment: {
|
environment: {
|
||||||
DOCKERAUTH: { from_variable: 'dockerauth' },
|
DOCKERAUTH: { from_variable: 'harbor-auth' },
|
||||||
|
DOCKERURL: { from_variable: 'harbor-url' },
|
||||||
},
|
},
|
||||||
shell: '/busybox/sh',
|
shell: '/busybox/sh',
|
||||||
working_dir: '/workspace',
|
working_dir: '/workspace',
|
||||||
|
@ -90,13 +91,13 @@ local task_build(version, arch) = {
|
||||||
cat << EOF > /kaniko/.docker/config.json
|
cat << EOF > /kaniko/.docker/config.json
|
||||||
{
|
{
|
||||||
"auths": {
|
"auths": {
|
||||||
"https://index.docker.io/v1/": { "auth" : "$DOCKERAUTH" }
|
"$DOCKERURL": { "auth" : "$DOCKERAUTH" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|||,
|
|||,
|
||||||
},
|
},
|
||||||
{ type: 'run', command: '/kaniko/executor --destination sorintlab/agola-web:$AGOLA_GIT_TAG' },
|
{ type: 'run', command: '/kaniko/executor --destination $DOCKERURL/tux/agola-web:$AGOLA_GIT_TAG' },
|
||||||
],
|
],
|
||||||
depends: ['checkout code and save to workspace'],
|
depends: ['checkout code and save to workspace'],
|
||||||
when: {
|
when: {
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = {
|
||||||
|
singleQuote: true,
|
||||||
|
};
|
|
@ -1,4 +1,4 @@
|
||||||
FROM node:lts-alpine AS web_build
|
FROM node:12-alpine AS web_build
|
||||||
|
|
||||||
WORKDIR /agola-web
|
WORKDIR /agola-web
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
presets: [
|
presets: ['@vue/cli-plugin-babel/preset'],
|
||||||
'@vue/cli-plugin-babel/preset'
|
};
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,12 +2,8 @@
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"paths": {
|
"paths": {
|
||||||
"*": [
|
"*": ["types/*"]
|
||||||
"types/*"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"include": [
|
"include": ["./src/**/*"]
|
||||||
"./src/**/*"
|
|
||||||
]
|
|
||||||
}
|
}
|
|
@ -1977,6 +1977,13 @@
|
||||||
"yallist": "^2.1.2"
|
"yallist": "^2.1.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"prettier": {
|
||||||
|
"version": "1.19.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz",
|
||||||
|
"integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"source-map": {
|
"source-map": {
|
||||||
"version": "0.6.1",
|
"version": "0.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||||
|
@ -9849,11 +9856,10 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"prettier": {
|
"prettier": {
|
||||||
"version": "1.19.1",
|
"version": "2.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz",
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz",
|
||||||
"integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==",
|
"integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"pretty-error": {
|
"pretty-error": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
"eslint": "^6.7.2",
|
"eslint": "^6.7.2",
|
||||||
"eslint-plugin-vue": "^6.2.2",
|
"eslint-plugin-vue": "^6.2.2",
|
||||||
"node-sass": "^4.14.1",
|
"node-sass": "^4.14.1",
|
||||||
|
"prettier": "2.5.1",
|
||||||
"sass-loader": "^8.0.2",
|
"sass-loader": "^8.0.2",
|
||||||
"tailwindcss": "^1.9.6",
|
"tailwindcss": "^1.9.6",
|
||||||
"vue-template-compiler": "^2.6.12"
|
"vue-template-compiler": "^2.6.12"
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
"plugins": [
|
plugins: [require('tailwindcss')('tailwind.js'), require('autoprefixer')()],
|
||||||
require('tailwindcss')('tailwind.js'),
|
};
|
||||||
require('autoprefixer')(),
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
61
src/App.vue
61
src/App.vue
|
@ -1,7 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<nav class="bg-gray-800 p-3 text-white">
|
<nav class="bg-gray-800 p-3 text-white">
|
||||||
<div class="container flex items-center justify-between flex-wrap bg-gray-800">
|
<div
|
||||||
|
class="container flex items-center justify-between flex-wrap bg-gray-800"
|
||||||
|
>
|
||||||
<div class="mr-6">
|
<div class="mr-6">
|
||||||
<router-link
|
<router-link
|
||||||
class="font-semibold flex items-center flex-shrink-0 text-xl tracking-tight"
|
class="font-semibold flex items-center flex-shrink-0 text-xl tracking-tight"
|
||||||
|
@ -28,12 +30,12 @@
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="w-full block flex-grow lg:flex lg:items-center lg:w-auto"
|
class="w-full block flex-grow lg:flex lg:items-center lg:w-auto"
|
||||||
:class="{'hidden' : !navActive}"
|
:class="{ hidden: !navActive }"
|
||||||
>
|
>
|
||||||
<div class="text-sm lg:flex-grow"></div>
|
<div class="text-sm lg:flex-grow"></div>
|
||||||
<div v-if="user" class="relative mr-3">
|
<div v-if="user" class="relative mr-3">
|
||||||
<button
|
<button
|
||||||
v-click-outside="() => createDropdownActive = false"
|
v-click-outside="() => (createDropdownActive = false)"
|
||||||
@click="createDropdownActive = !createDropdownActive"
|
@click="createDropdownActive = !createDropdownActive"
|
||||||
class="relative flex items-center focus:outline-none"
|
class="relative flex items-center focus:outline-none"
|
||||||
>
|
>
|
||||||
|
@ -49,7 +51,8 @@
|
||||||
<router-link
|
<router-link
|
||||||
class="block px-4 py-2 hover:bg-blue-500 hover:text-white"
|
class="block px-4 py-2 hover:bg-blue-500 hover:text-white"
|
||||||
to="/neworganization"
|
to="/neworganization"
|
||||||
>New Organization</router-link>
|
>New Organization</router-link
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -57,7 +60,7 @@
|
||||||
<div v-if="user" class="relative">
|
<div v-if="user" class="relative">
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<button
|
<button
|
||||||
v-click-outside="() => userDropdownActive = false"
|
v-click-outside="() => (userDropdownActive = false)"
|
||||||
@click="userDropdownActive = !userDropdownActive"
|
@click="userDropdownActive = !userDropdownActive"
|
||||||
class="relative flex items-center focus:outline-none"
|
class="relative flex items-center focus:outline-none"
|
||||||
>
|
>
|
||||||
|
@ -98,18 +101,30 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="navbar-item">
|
<div v-else class="navbar-item">
|
||||||
<router-link class="btn btn-blue" to="/register">Sign up</router-link>
|
<router-link class="btn btn-blue" to="/register"
|
||||||
<router-link class="ml-2 btn btn-blue" to="/login">Login</router-link>
|
>Sign up</router-link
|
||||||
|
>
|
||||||
|
<router-link class="ml-2 btn btn-blue" to="/login"
|
||||||
|
>Login</router-link
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div v-if="error" class="container h-screen" role="alert">
|
<div v-if="error" class="container h-screen" role="alert">
|
||||||
<div v-if="error" class="h-full flex justify-center items-center" role="alert">
|
<div
|
||||||
|
v-if="error"
|
||||||
|
class="h-full flex justify-center items-center"
|
||||||
|
role="alert"
|
||||||
|
>
|
||||||
<div v-if="error" class="w-full" role="alert">
|
<div v-if="error" class="w-full" role="alert">
|
||||||
<div class="bg-red-500 text-white font-bold rounded-t px-4 py-2">Error</div>
|
<div class="bg-red-500 text-white font-bold rounded-t px-4 py-2">
|
||||||
<div class="border border-t-0 border-red-400 rounded-b bg-red-100 px-4 py-3 text-red-700">
|
Error
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="border border-t-0 border-red-400 rounded-b bg-red-100 px-4 py-3 text-red-700"
|
||||||
|
>
|
||||||
<p class="mb-8">Failed to fetch data: {{ error }}</p>
|
<p class="mb-8">Failed to fetch data: {{ error }}</p>
|
||||||
<button class="btn btn-red" @click="reload()">Retry</button>
|
<button class="btn btn-red" @click="reload()">Retry</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -123,48 +138,46 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as vClickOutside from "v-click-outside-x";
|
import * as vClickOutside from 'v-click-outside-x';
|
||||||
|
|
||||||
import { mapGetters } from "vuex";
|
import { mapGetters } from 'vuex';
|
||||||
|
|
||||||
import { ownerSettingsLink } from "@/util/link.js";
|
import { ownerSettingsLink } from '@/util/link.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "App",
|
name: 'App',
|
||||||
directives: {
|
directives: {
|
||||||
clickOutside: vClickOutside.directive
|
clickOutside: vClickOutside.directive,
|
||||||
},
|
},
|
||||||
components: {},
|
components: {},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(["error", "user"])
|
...mapGetters(['error', 'user']),
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
routerActive: true,
|
routerActive: true,
|
||||||
navActive: false,
|
navActive: false,
|
||||||
userDropdownActive: false,
|
userDropdownActive: false,
|
||||||
createDropdownActive: false
|
createDropdownActive: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
$route: function () {
|
$route: function () {
|
||||||
this.userDropdownActive = false;
|
this.userDropdownActive = false;
|
||||||
this.createDropdownActive = false;
|
this.createDropdownActive = false;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
// method to reload current view from https://github.com/vuejs/vue-router/issues/296#issuecomment-356530037
|
// method to reload current view from https://github.com/vuejs/vue-router/issues/296#issuecomment-356530037
|
||||||
methods: {
|
methods: {
|
||||||
ownerSettingsLink: ownerSettingsLink,
|
ownerSettingsLink: ownerSettingsLink,
|
||||||
reload() {
|
reload() {
|
||||||
this.$store.dispatch("setError", null);
|
this.$store.dispatch('setError', null);
|
||||||
this.routerActive = false;
|
this.routerActive = false;
|
||||||
this.$nextTick(() => (this.routerActive = true));
|
this.$nextTick(() => (this.routerActive = true));
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
|
@ -8,19 +8,21 @@
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Organization name"
|
placeholder="Organization name"
|
||||||
v-model="orgName"
|
v-model="orgName"
|
||||||
>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" v-model="orgIsPrivate">
|
<input type="checkbox" v-model="orgIsPrivate" />
|
||||||
Private
|
Private
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
|
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
|
||||||
@click="createOrg()"
|
@click="createOrg()"
|
||||||
>Create Organization</button>
|
>
|
||||||
|
Create Organization
|
||||||
|
</button>
|
||||||
<div
|
<div
|
||||||
v-if="createOrgError"
|
v-if="createOrgError"
|
||||||
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
||||||
|
@ -32,19 +34,19 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { createOrganization } from "@/util/data.js";
|
import { createOrganization } from '@/util/data.js';
|
||||||
|
|
||||||
import { ownerLink } from "@/util/link.js";
|
import { ownerLink } from '@/util/link.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: {},
|
||||||
name: "createorganization",
|
name: 'createorganization',
|
||||||
props: {},
|
props: {},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
createOrgError: null,
|
createOrgError: null,
|
||||||
orgIsPrivate: false,
|
orgIsPrivate: false,
|
||||||
orgName: null
|
orgName: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -54,9 +56,9 @@ export default {
|
||||||
async createOrg() {
|
async createOrg() {
|
||||||
this.resetErrors();
|
this.resetErrors();
|
||||||
|
|
||||||
let visibility = "public";
|
let visibility = 'public';
|
||||||
if (this.orgIsPrivate) {
|
if (this.orgIsPrivate) {
|
||||||
visibility = "private";
|
visibility = 'private';
|
||||||
}
|
}
|
||||||
|
|
||||||
let { error } = await createOrganization(this.orgName, visibility);
|
let { error } = await createOrganization(this.orgName, visibility);
|
||||||
|
@ -65,14 +67,11 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$router.push(ownerLink("org", this.orgName));
|
this.$router.push(ownerLink('org', this.orgName));
|
||||||
}
|
|
||||||
},
|
},
|
||||||
created: async function() {}
|
},
|
||||||
|
created: async function () {},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,17 +7,18 @@
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Project Name"
|
placeholder="Project Name"
|
||||||
v-model="projectName"
|
v-model="projectName"
|
||||||
>
|
/>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" v-model="projectIsPrivate">
|
<input type="checkbox" v-model="projectIsPrivate" />
|
||||||
Private
|
Private
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label class="checkbox">
|
<label class="checkbox">
|
||||||
<input type="checkbox" v-model="pass_vars_to_forked_pr" />
|
<input type="checkbox" v-model="pass_vars_to_forked_pr" />
|
||||||
Pass variables to run even if triggered by PR from forked repo (DANGEROUS)
|
Pass variables to run even if triggered by PR from forked repo
|
||||||
|
(DANGEROUS)
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3 flex items-center">
|
<div class="mb-3 flex items-center">
|
||||||
|
@ -31,31 +32,48 @@
|
||||||
v-for="(rs, index) in remoteSources"
|
v-for="(rs, index) in remoteSources"
|
||||||
v-bind:key="rs.id"
|
v-bind:key="rs.id"
|
||||||
:value="index"
|
:value="index"
|
||||||
>{{ rs.name }}</option>
|
>
|
||||||
|
{{ rs.name }}
|
||||||
|
</option>
|
||||||
</select>
|
</select>
|
||||||
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2">
|
<div
|
||||||
<svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
|
class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2"
|
||||||
<path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"></path>
|
>
|
||||||
|
<svg
|
||||||
|
class="fill-current h-4 w-4"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"
|
||||||
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
class="ml-3 btn btn-blue"
|
class="ml-3 btn btn-blue"
|
||||||
v-bind:class="{ 'spinner': fetchRemoteReposLoading }"
|
v-bind:class="{ spinner: fetchRemoteReposLoading }"
|
||||||
:disabled="selectedRemoteSourceIndex == null"
|
:disabled="selectedRemoteSourceIndex == null"
|
||||||
@click="fetchRemoteRepos()"
|
@click="fetchRemoteRepos()"
|
||||||
>Fetch remote repositories</button>
|
>
|
||||||
|
Fetch remote repositories
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="remoteRepos.length">
|
<div v-if="remoteRepos.length">
|
||||||
<h4 class="text-xl">Available remote repositories</h4>
|
<h4 class="text-xl">Available remote repositories</h4>
|
||||||
<remoterepos :remoterepos="remoteRepos" v-on:reposelected="repoSelected($event)"/>
|
<remoterepos
|
||||||
|
:remoterepos="remoteRepos"
|
||||||
|
v-on:reposelected="repoSelected($event)"
|
||||||
|
/>
|
||||||
<button
|
<button
|
||||||
class="btn btn-blue"
|
class="btn btn-blue"
|
||||||
v-bind:class="{ 'spinner': createProjectLoading }"
|
v-bind:class="{ spinner: createProjectLoading }"
|
||||||
:disabled="!createProjectButtonEnabled"
|
:disabled="!createProjectButtonEnabled"
|
||||||
@click="createProject()"
|
@click="createProject()"
|
||||||
>Create Project</button>
|
>
|
||||||
|
Create Project
|
||||||
|
</button>
|
||||||
<div
|
<div
|
||||||
v-if="createProjectError"
|
v-if="createProjectError"
|
||||||
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
||||||
|
@ -72,20 +90,20 @@ import {
|
||||||
fetchCurrentUser,
|
fetchCurrentUser,
|
||||||
fetchRemoteSources,
|
fetchRemoteSources,
|
||||||
createProject,
|
createProject,
|
||||||
userRemoteRepos
|
userRemoteRepos,
|
||||||
} from "@/util/data.js";
|
} from '@/util/data.js';
|
||||||
|
|
||||||
import { projectLink } from "@/util/link.js";
|
import { projectLink } from '@/util/link.js';
|
||||||
|
|
||||||
import remoterepos from "@/components/remoterepos.vue";
|
import remoterepos from '@/components/remoterepos.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { remoterepos },
|
components: { remoterepos },
|
||||||
name: "createproject",
|
name: 'createproject',
|
||||||
props: {
|
props: {
|
||||||
ownertype: String,
|
ownertype: String,
|
||||||
ownername: String,
|
ownername: String,
|
||||||
projectgroupref: Array
|
projectgroupref: Array,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -98,15 +116,15 @@ export default {
|
||||||
remoteSources: null,
|
remoteSources: null,
|
||||||
remoteRepos: [],
|
remoteRepos: [],
|
||||||
selectedRemoteSourceIndex: null,
|
selectedRemoteSourceIndex: null,
|
||||||
projectName: "",
|
projectName: '',
|
||||||
projectIsPrivate: false,
|
projectIsPrivate: false,
|
||||||
remoteRepoPath: null
|
remoteRepoPath: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
createProjectButtonEnabled: function () {
|
createProjectButtonEnabled: function () {
|
||||||
return this.projectName.length && this.remoteRepoPath;
|
return this.projectName.length && this.remoteRepoPath;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
watch: {},
|
watch: {},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -143,7 +161,7 @@ export default {
|
||||||
let { data, error } = await userRemoteRepos(remoteSource.id);
|
let { data, error } = await userRemoteRepos(remoteSource.id);
|
||||||
this.stopFetchRemoteReposLoading();
|
this.stopFetchRemoteReposLoading();
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.remoteRepos = data;
|
this.remoteRepos = data;
|
||||||
|
@ -155,11 +173,11 @@ export default {
|
||||||
if (this.projectgroupref) {
|
if (this.projectgroupref) {
|
||||||
refArray = [...refArray, ...this.projectgroupref];
|
refArray = [...refArray, ...this.projectgroupref];
|
||||||
}
|
}
|
||||||
let parentref = refArray.join("/");
|
let parentref = refArray.join('/');
|
||||||
|
|
||||||
let visibility = "public";
|
let visibility = 'public';
|
||||||
if (this.projectIsPrivate) {
|
if (this.projectIsPrivate) {
|
||||||
visibility = "private";
|
visibility = 'private';
|
||||||
}
|
}
|
||||||
|
|
||||||
let remoteSource = this.remoteSources[this.selectedRemoteSourceIndex];
|
let remoteSource = this.remoteSources[this.selectedRemoteSourceIndex];
|
||||||
|
@ -186,12 +204,12 @@ export default {
|
||||||
this.$router.push(
|
this.$router.push(
|
||||||
projectLink(this.ownertype, this.ownername, projectref)
|
projectLink(this.ownertype, this.ownername, projectref)
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created: async function () {
|
created: async function () {
|
||||||
let { data, error } = await fetchCurrentUser();
|
let { data, error } = await fetchCurrentUser();
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.user = data;
|
this.user = data;
|
||||||
|
@ -199,7 +217,7 @@ export default {
|
||||||
// TODO(sgotti) filter only remote source where the user has a linked account
|
// TODO(sgotti) filter only remote source where the user has a linked account
|
||||||
({ data, error } = await fetchRemoteSources());
|
({ data, error } = await fetchRemoteSources());
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,10 +233,8 @@ export default {
|
||||||
}
|
}
|
||||||
this.remoteSources = remoteSources;
|
this.remoteSources = remoteSources;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,11 @@
|
||||||
<button
|
<button
|
||||||
@click="clicked"
|
@click="clicked"
|
||||||
class="relative flex items-center focus:outline-none bg-green-500 hover:bg-green-600 text-white font-semibold hover:text-white py-2 px-4 border border-green-700 rounded rounded-r-none"
|
class="relative flex items-center focus:outline-none bg-green-500 hover:bg-green-600 text-white font-semibold hover:text-white py-2 px-4 border border-green-700 rounded rounded-r-none"
|
||||||
>{{ buttonValue }}</button>
|
>
|
||||||
|
{{ buttonValue }}
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
v-click-outside="() => dropdownActive = false"
|
v-click-outside="() => (dropdownActive = false)"
|
||||||
@click="dropdownActive = !dropdownActive"
|
@click="dropdownActive = !dropdownActive"
|
||||||
class="relative flex items-center focus:outline-none bg-green-500 hover:bg-green-600 text-white font-semibold hover:text-white py-2 px-4 border border-l-0 border-green-700 rounded rounded-l-none"
|
class="relative flex items-center focus:outline-none bg-green-500 hover:bg-green-600 text-white font-semibold hover:text-white py-2 px-4 border border-l-0 border-green-700 rounded rounded-l-none"
|
||||||
>
|
>
|
||||||
|
@ -24,14 +26,16 @@
|
||||||
href="#"
|
href="#"
|
||||||
class="block px-4 py-2 hover:bg-blue-500 hover:text-white"
|
class="block px-4 py-2 hover:bg-blue-500 hover:text-white"
|
||||||
@click="setButton('project')"
|
@click="setButton('project')"
|
||||||
>New Project</a>
|
>New Project</a
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
class="block px-4 py-2 hover:bg-blue-500 hover:text-white"
|
class="block px-4 py-2 hover:bg-blue-500 hover:text-white"
|
||||||
@click="setButton('projectgroup')"
|
@click="setButton('projectgroup')"
|
||||||
>New Project Group</a>
|
>New Project Group</a
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -40,28 +44,28 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as vClickOutside from "v-click-outside-x";
|
import * as vClickOutside from 'v-click-outside-x';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: {},
|
||||||
directives: {
|
directives: {
|
||||||
clickOutside: vClickOutside.directive
|
clickOutside: vClickOutside.directive,
|
||||||
},
|
},
|
||||||
name: "createprojectbutton",
|
name: 'createprojectbutton',
|
||||||
props: {},
|
props: {},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
dropdownActive: false,
|
dropdownActive: false,
|
||||||
type: "project"
|
type: 'project',
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
buttonValue: function () {
|
buttonValue: function () {
|
||||||
if (this.type == "project") {
|
if (this.type == 'project') {
|
||||||
return "New Project";
|
return 'New Project';
|
||||||
}
|
|
||||||
return "New Project Group";
|
|
||||||
}
|
}
|
||||||
|
return 'New Project Group';
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
setButton(type) {
|
setButton(type) {
|
||||||
|
@ -69,12 +73,10 @@ export default {
|
||||||
this.dropdownActive = false;
|
this.dropdownActive = false;
|
||||||
},
|
},
|
||||||
clicked() {
|
clicked() {
|
||||||
this.$emit("click", this.type);
|
this.$emit('click', this.type);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
|
@ -7,20 +7,22 @@
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Project Group Name"
|
placeholder="Project Group Name"
|
||||||
v-model="projectGroupName"
|
v-model="projectGroupName"
|
||||||
>
|
/>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" v-model="projectGroupIsPrivate">
|
<input type="checkbox" v-model="projectGroupIsPrivate" />
|
||||||
Private
|
Private
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
|
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
|
||||||
v-bind:class="{ 'spinner': createProjectGroupLoading }"
|
v-bind:class="{ spinner: createProjectGroupLoading }"
|
||||||
:disabled="!createProjectGroupButtonEnabled"
|
:disabled="!createProjectGroupButtonEnabled"
|
||||||
@click="createProjectGroup()"
|
@click="createProjectGroup()"
|
||||||
>Create ProjectGroup</button>
|
>
|
||||||
|
Create ProjectGroup
|
||||||
|
</button>
|
||||||
<div
|
<div
|
||||||
v-if="createProjectGroupError"
|
v-if="createProjectGroupError"
|
||||||
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
||||||
|
@ -32,31 +34,31 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { createProjectGroup } from "@/util/data.js";
|
import { createProjectGroup } from '@/util/data.js';
|
||||||
|
|
||||||
import { projectGroupLink } from "@/util/link.js";
|
import { projectGroupLink } from '@/util/link.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: {},
|
||||||
name: "createprojectgroup",
|
name: 'createprojectgroup',
|
||||||
props: {
|
props: {
|
||||||
ownertype: String,
|
ownertype: String,
|
||||||
ownername: String,
|
ownername: String,
|
||||||
projectgroupref: Array
|
projectgroupref: Array,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
createProjectGroupError: null,
|
createProjectGroupError: null,
|
||||||
createProjectGroupLoading: false,
|
createProjectGroupLoading: false,
|
||||||
createProjectGroupLoadingTimeout: null,
|
createProjectGroupLoadingTimeout: null,
|
||||||
projectGroupName: "",
|
projectGroupName: '',
|
||||||
projectGroupIsPrivate: false
|
projectGroupIsPrivate: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
createProjectGroupButtonEnabled: function () {
|
createProjectGroupButtonEnabled: function () {
|
||||||
return this.projectGroupName.length;
|
return this.projectGroupName.length;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
resetErrors() {
|
resetErrors() {
|
||||||
|
@ -78,11 +80,11 @@ export default {
|
||||||
if (this.projectgroupref) {
|
if (this.projectgroupref) {
|
||||||
refArray = [...refArray, ...this.projectgroupref];
|
refArray = [...refArray, ...this.projectgroupref];
|
||||||
}
|
}
|
||||||
let parentref = refArray.join("/");
|
let parentref = refArray.join('/');
|
||||||
|
|
||||||
let visibility = "public";
|
let visibility = 'public';
|
||||||
if (this.projectGroupIsPrivate) {
|
if (this.projectGroupIsPrivate) {
|
||||||
visibility = "private";
|
visibility = 'private';
|
||||||
}
|
}
|
||||||
|
|
||||||
this.startProjectGroupLoading();
|
this.startProjectGroupLoading();
|
||||||
|
@ -104,12 +106,9 @@ export default {
|
||||||
this.$router.push(
|
this.$router.push(
|
||||||
projectGroupLink(this.ownertype, this.ownername, projectgroupref)
|
projectGroupLink(this.ownertype, this.ownername, projectgroupref)
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,17 +12,31 @@
|
||||||
</h1>
|
</h1>
|
||||||
<form
|
<form
|
||||||
class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4"
|
class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4"
|
||||||
@submit.prevent="$emit('createSource', { token, name, type, clientId, clientSecret, url, skipVerify, sshHostKey, skipSshHostKeyCheck })"
|
@submit.prevent="
|
||||||
|
$emit('createSource', {
|
||||||
|
token,
|
||||||
|
name,
|
||||||
|
type,
|
||||||
|
clientId,
|
||||||
|
clientSecret,
|
||||||
|
url,
|
||||||
|
skipVerify,
|
||||||
|
sshHostKey,
|
||||||
|
skipSshHostKeyCheck,
|
||||||
|
})
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label class="block text-sm font-bold mb-2" for="token">Agola Admin token</label>
|
<label class="block text-sm font-bold mb-2" for="token"
|
||||||
|
>Agola Admin token</label
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||||
id="token"
|
id="token"
|
||||||
type="password"
|
type="password"
|
||||||
placeholder="Agola Admin token"
|
placeholder="Agola Admin token"
|
||||||
v-model="token"
|
v-model="token"
|
||||||
>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label class="block text-sm font-bold mb-2" for="type">Type</label>
|
<label class="block text-sm font-bold mb-2" for="type">Type</label>
|
||||||
|
@ -37,7 +51,9 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label class="block text-sm font-bold mb-2" for="name">Source name</label>
|
<label class="block text-sm font-bold mb-2" for="name"
|
||||||
|
>Source name</label
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||||
id="name"
|
id="name"
|
||||||
|
@ -45,17 +61,19 @@
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Source name (only numbers, letters and -)"
|
placeholder="Source name (only numbers, letters and -)"
|
||||||
v-model="name"
|
v-model="name"
|
||||||
>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label class="block text-sm font-bold mb-2" for="url">Source API URL</label>
|
<label class="block text-sm font-bold mb-2" for="url"
|
||||||
|
>Source API URL</label
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||||
id="url"
|
id="url"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="API URL"
|
placeholder="API URL"
|
||||||
v-model="url"
|
v-model="url"
|
||||||
>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4 flex flex-row">
|
<div class="mb-4 flex flex-row">
|
||||||
<input
|
<input
|
||||||
|
@ -63,11 +81,15 @@
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
class="h-6 w-6 border border-gray-300 rounded-md checked:bg-blue-600 checked:border-transparent focus:outline-none"
|
class="h-6 w-6 border border-gray-300 rounded-md checked:bg-blue-600 checked:border-transparent focus:outline-none"
|
||||||
v-model="skipVerify"
|
v-model="skipVerify"
|
||||||
|
/>
|
||||||
|
<label class="text-sm mt-auto font-bold mx-2" for="skip_verify"
|
||||||
|
>Skip TLS certificate validation</label
|
||||||
>
|
>
|
||||||
<label class="text-sm mt-auto font-bold mx-2" for="skip_verify">Skip TLS certificate validation</label>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label class="block text-sm font-bold mb-2" for="ssh_key">Source Public SSH Key</label>
|
<label class="block text-sm font-bold mb-2" for="ssh_key"
|
||||||
|
>Source Public SSH Key</label
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||||
id="ssh_key"
|
id="ssh_key"
|
||||||
|
@ -75,7 +97,7 @@
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
placeholder="Public SSH key"
|
placeholder="Public SSH key"
|
||||||
v-model="sshHostKey"
|
v-model="sshHostKey"
|
||||||
>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4 flex flex-row">
|
<div class="mb-4 flex flex-row">
|
||||||
<input
|
<input
|
||||||
|
@ -83,45 +105,52 @@
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
class="h-6 w-6 border border-gray-300 rounded-md checked:bg-blue-600 checked:border-transparent focus:outline-none"
|
class="h-6 w-6 border border-gray-300 rounded-md checked:bg-blue-600 checked:border-transparent focus:outline-none"
|
||||||
v-model="skipSshHostKeyCheck"
|
v-model="skipSshHostKeyCheck"
|
||||||
|
/>
|
||||||
|
<label class="text-sm mt-auto font-bold mx-2" for="skip_ssh_key_check"
|
||||||
|
>Skip SSH host key check</label
|
||||||
>
|
>
|
||||||
<label class="text-sm mt-auto font-bold mx-2" for="skip_ssh_key_check">Skip SSH host key check</label>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label class="block text-sm font-bold mb-2" for="client_id">Source client ID</label>
|
<label class="block text-sm font-bold mb-2" for="client_id"
|
||||||
|
>Source client ID</label
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||||
id="client_id"
|
id="client_id"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Client ID"
|
placeholder="Client ID"
|
||||||
v-model="clientId"
|
v-model="clientId"
|
||||||
>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label class="block text-sm font-bold mb-2" for="client_secret">Source client secret</label>
|
<label class="block text-sm font-bold mb-2" for="client_secret"
|
||||||
|
>Source client secret</label
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||||
id="client_secret"
|
id="client_secret"
|
||||||
type="password"
|
type="password"
|
||||||
placeholder="Client secret"
|
placeholder="Client secret"
|
||||||
v-model="clientSecret"
|
v-model="clientSecret"
|
||||||
>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-center">
|
<div class="flex justify-center">
|
||||||
<button
|
<button
|
||||||
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
|
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
|
||||||
type="submit"
|
type="submit"
|
||||||
>Create</button>
|
>
|
||||||
|
Create
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { GITHUB_SSH_KEY, GITHUB_API_URL } from "@/util/data"
|
import { GITHUB_SSH_KEY, GITHUB_API_URL } from '@/util/data';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "CreateSourceForm",
|
name: 'CreateSourceForm',
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
name: null,
|
name: null,
|
||||||
|
@ -137,7 +166,7 @@ export default {
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
type: function (value) {
|
type: function (value) {
|
||||||
if (value === "github") {
|
if (value === 'github') {
|
||||||
this.url = GITHUB_API_URL;
|
this.url = GITHUB_API_URL;
|
||||||
this.sshHostKey = GITHUB_SSH_KEY;
|
this.sshHostKey = GITHUB_SSH_KEY;
|
||||||
this.skipVerify = false;
|
this.skipVerify = false;
|
||||||
|
@ -147,5 +176,3 @@ export default {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -43,18 +43,18 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { apiurl, fetch } from "@/util/auth";
|
import { apiurl, fetch } from '@/util/auth';
|
||||||
import AnsiUp from "ansi_up";
|
import AnsiUp from 'ansi_up';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Log",
|
name: 'Log',
|
||||||
props: {
|
props: {
|
||||||
show: Boolean,
|
show: Boolean,
|
||||||
runid: String,
|
runid: String,
|
||||||
taskid: String,
|
taskid: String,
|
||||||
setup: Boolean,
|
setup: Boolean,
|
||||||
step: Number,
|
step: Number,
|
||||||
stepphase: String
|
stepphase: String,
|
||||||
},
|
},
|
||||||
computed: {},
|
computed: {},
|
||||||
data() {
|
data() {
|
||||||
|
@ -65,7 +65,7 @@ export default {
|
||||||
fetchAbort: null,
|
fetchAbort: null,
|
||||||
|
|
||||||
items: [],
|
items: [],
|
||||||
lastitem: "",
|
lastitem: '',
|
||||||
lines: [],
|
lines: [],
|
||||||
formatter: formatter,
|
formatter: formatter,
|
||||||
es: null,
|
es: null,
|
||||||
|
@ -73,7 +73,7 @@ export default {
|
||||||
streaming: false,
|
streaming: false,
|
||||||
done: false,
|
done: false,
|
||||||
logExists: null,
|
logExists: null,
|
||||||
error: null
|
error: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -83,7 +83,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
let follow = false;
|
let follow = false;
|
||||||
if (this.stepphase == "running") {
|
if (this.stepphase == 'running') {
|
||||||
follow = true;
|
follow = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,14 +94,14 @@ export default {
|
||||||
this.logExists = null;
|
this.logExists = null;
|
||||||
this.error = null;
|
this.error = null;
|
||||||
|
|
||||||
let path = "/logs?runID=" + this.runid + "&taskID=" + this.taskid;
|
let path = '/logs?runID=' + this.runid + '&taskID=' + this.taskid;
|
||||||
if (this.setup) {
|
if (this.setup) {
|
||||||
path += "&setup";
|
path += '&setup';
|
||||||
} else {
|
} else {
|
||||||
path += "&step=" + this.step;
|
path += '&step=' + this.step;
|
||||||
}
|
}
|
||||||
if (follow) {
|
if (follow) {
|
||||||
path += "&follow";
|
path += '&follow';
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -111,7 +111,7 @@ export default {
|
||||||
this.streaming = true;
|
this.streaming = true;
|
||||||
const reader = res.body.getReader();
|
const reader = res.body.getReader();
|
||||||
|
|
||||||
let lastline = "";
|
let lastline = '';
|
||||||
let j = 0;
|
let j = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
let { done, value } = await reader.read();
|
let { done, value } = await reader.read();
|
||||||
|
@ -122,12 +122,12 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let data = new TextDecoder("utf-8").decode(value, { stream: true });
|
let data = new TextDecoder('utf-8').decode(value, { stream: true });
|
||||||
|
|
||||||
let part = "";
|
let part = '';
|
||||||
for (var i = 0; i < data.length; i++) {
|
for (var i = 0; i < data.length; i++) {
|
||||||
let c = data.charAt(i);
|
let c = data.charAt(i);
|
||||||
if (c == "\r") {
|
if (c == '\r') {
|
||||||
// replace lastline from start, simulating line feed (go to start of line)
|
// replace lastline from start, simulating line feed (go to start of line)
|
||||||
// this isn't perfect since the previous line contents could have
|
// this isn't perfect since the previous line contents could have
|
||||||
// been written using different colors and this will lose them but
|
// been written using different colors and this will lose them but
|
||||||
|
@ -136,17 +136,17 @@ export default {
|
||||||
lastline.slice(0, j) + part + lastline.slice(j + part.length);
|
lastline.slice(0, j) + part + lastline.slice(j + part.length);
|
||||||
j = 0;
|
j = 0;
|
||||||
this.lastitem = this.formatter.ansi_to_html(lastline);
|
this.lastitem = this.formatter.ansi_to_html(lastline);
|
||||||
part = "";
|
part = '';
|
||||||
} else if (c == "\n") {
|
} else if (c == '\n') {
|
||||||
lastline =
|
lastline =
|
||||||
lastline.slice(0, j) + part + lastline.slice(j + part.length);
|
lastline.slice(0, j) + part + lastline.slice(j + part.length);
|
||||||
j += part.length;
|
j += part.length;
|
||||||
this.lastitem = this.formatter.ansi_to_html(lastline);
|
this.lastitem = this.formatter.ansi_to_html(lastline);
|
||||||
this.items.push(this.lastitem);
|
this.items.push(this.lastitem);
|
||||||
this.lastitem = "";
|
this.lastitem = '';
|
||||||
lastline = "";
|
lastline = '';
|
||||||
j = 0;
|
j = 0;
|
||||||
part = "";
|
part = '';
|
||||||
} else {
|
} else {
|
||||||
part += c;
|
part += c;
|
||||||
}
|
}
|
||||||
|
@ -174,7 +174,7 @@ export default {
|
||||||
this.fetchAbort.abort();
|
this.fetchAbort.abort();
|
||||||
}
|
}
|
||||||
this.fetchAbort = new AbortController();
|
this.fetchAbort = new AbortController();
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
show: function (post, pre) {
|
show: function (post, pre) {
|
||||||
|
@ -193,14 +193,14 @@ export default {
|
||||||
if (this.fetching) {
|
if (this.fetching) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (post == "running") {
|
if (post == 'running') {
|
||||||
this.abortFetch();
|
this.abortFetch();
|
||||||
this.getLogs(true);
|
this.getLogs(true);
|
||||||
} else {
|
} else {
|
||||||
this.abortFetch();
|
this.abortFetch();
|
||||||
this.getLogs(false);
|
this.getLogs(false);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
this.fetchAbort = new AbortController();
|
this.fetchAbort = new AbortController();
|
||||||
|
@ -217,6 +217,6 @@ export default {
|
||||||
if (this.es !== null) {
|
if (this.es !== null) {
|
||||||
this.es.close();
|
this.es.close();
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -5,50 +5,53 @@
|
||||||
@submit.prevent="$emit('login', { username, password })"
|
@submit.prevent="$emit('login', { username, password })"
|
||||||
>
|
>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label class="block text-sm font-bold mb-2" for="username">Username</label>
|
<label class="block text-sm font-bold mb-2" for="username"
|
||||||
|
>Username</label
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||||
id="username"
|
id="username"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Username"
|
placeholder="Username"
|
||||||
v-model="username"
|
v-model="username"
|
||||||
>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-6">
|
<div class="mb-6">
|
||||||
<label class="block text-sm font-bold mb-2" for="password">Password</label>
|
<label class="block text-sm font-bold mb-2" for="password"
|
||||||
|
>Password</label
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
class="appearance-none border rounded w-full py-2 px-3 mb-3 leading-tight focus:outline-none focus:shadow-outline"
|
class="appearance-none border rounded w-full py-2 px-3 mb-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||||
id="password"
|
id="password"
|
||||||
type="password"
|
type="password"
|
||||||
placeholder="******************"
|
placeholder="******************"
|
||||||
v-model="password"
|
v-model="password"
|
||||||
>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-center">
|
<div class="flex justify-center">
|
||||||
<button
|
<button
|
||||||
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
|
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
|
||||||
type="submit"
|
type="submit"
|
||||||
>{{action}} with {{name}}</button>
|
>
|
||||||
|
{{ action }} with {{ name }}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "LoginForm",
|
name: 'LoginForm',
|
||||||
props: {
|
props: {
|
||||||
action: String,
|
action: String,
|
||||||
name: String
|
name: String,
|
||||||
},
|
},
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
username: null,
|
username: null,
|
||||||
password: null
|
password: null,
|
||||||
};
|
};
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,39 +12,38 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { fetchOrgMembers } from "@/util/data.js";
|
import { fetchOrgMembers } from '@/util/data.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: {},
|
||||||
name: "orgmembers",
|
name: 'orgmembers',
|
||||||
props: {
|
props: {
|
||||||
orgname: String
|
orgname: String,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
members: []
|
members: [],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
$route: async function () {
|
$route: async function () {
|
||||||
this.fetchOrgMembers(this.orgname);
|
this.fetchOrgMembers(this.orgname);
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async fetchOrgMembers(orgname) {
|
async fetchOrgMembers(orgname) {
|
||||||
let { data, error } = await fetchOrgMembers(orgname);
|
let { data, error } = await fetchOrgMembers(orgname);
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.members = data.members;
|
this.members = data.members;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
this.fetchOrgMembers(this.orgname);
|
this.fetchOrgMembers(this.orgname);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
|
@ -8,51 +8,61 @@
|
||||||
<span class="mx-2">/</span>
|
<span class="mx-2">/</span>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<router-link :to="ownerLink(ownertype, ownername)">{{ownername}}</router-link>
|
<router-link :to="ownerLink(ownertype, ownername)">{{
|
||||||
|
ownername
|
||||||
|
}}</router-link>
|
||||||
</li>
|
</li>
|
||||||
<li v-for="(ref, i) in projectref" v-bind:key="i">
|
<li v-for="(ref, i) in projectref" v-bind:key="i">
|
||||||
<span class="mx-2">/</span>
|
<span class="mx-2">/</span>
|
||||||
<router-link
|
<router-link
|
||||||
v-if="i + 1 < projectref.length"
|
v-if="i + 1 < projectref.length"
|
||||||
:to="projectGroupLink(ownertype, ownername, projectref.slice(0, i+1))"
|
:to="
|
||||||
>{{ref}}</router-link>
|
projectGroupLink(ownertype, ownername, projectref.slice(0, i + 1))
|
||||||
|
"
|
||||||
|
>{{ ref }}</router-link
|
||||||
|
>
|
||||||
<router-link
|
<router-link
|
||||||
v-else
|
v-else
|
||||||
:to="projectLink(ownertype, ownername, projectref.slice(0, i + 1))"
|
:to="projectLink(ownertype, ownername, projectref.slice(0, i + 1))"
|
||||||
>{{ref}}</router-link>
|
>{{ ref }}</router-link
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li v-for="(ref, i) in projectgroupref" v-bind:key="i">
|
<li v-for="(ref, i) in projectgroupref" v-bind:key="i">
|
||||||
<span class="mx-2">/</span>
|
<span class="mx-2">/</span>
|
||||||
<router-link
|
<router-link
|
||||||
:to="projectGroupLink(ownertype, ownername, projectgroupref.slice(0, i+1))"
|
:to="
|
||||||
>{{ref}}</router-link>
|
projectGroupLink(
|
||||||
|
ownertype,
|
||||||
|
ownername,
|
||||||
|
projectgroupref.slice(0, i + 1)
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>{{ ref }}</router-link
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
</nav>
|
</nav>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ownerLink, projectLink, projectGroupLink } from "@/util/link.js";
|
import { ownerLink, projectLink, projectGroupLink } from '@/util/link.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "projbreadcrumbs",
|
name: 'projbreadcrumbs',
|
||||||
components: {},
|
components: {},
|
||||||
props: {
|
props: {
|
||||||
ownertype: String,
|
ownertype: String,
|
||||||
ownername: String,
|
ownername: String,
|
||||||
projectref: Array,
|
projectref: Array,
|
||||||
projectgroupref: Array
|
projectgroupref: Array,
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
ownerLink: ownerLink,
|
ownerLink: ownerLink,
|
||||||
projectLink: projectLink,
|
projectLink: projectLink,
|
||||||
projectGroupLink: projectGroupLink
|
projectGroupLink: projectGroupLink,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
||||||
<style scoped lang="scss">
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -20,7 +20,9 @@
|
||||||
Private
|
Private
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-blue" @click="updateProjectGroup()">Update</button>
|
<button class="btn btn-blue" @click="updateProjectGroup()">
|
||||||
|
Update
|
||||||
|
</button>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="updateProjectGroupError"
|
v-if="updateProjectGroupError"
|
||||||
|
@ -35,14 +37,22 @@
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<p class="panel-title">Secrets</p>
|
<p class="panel-title">Secrets</p>
|
||||||
<div class="p-4">
|
<div class="p-4">
|
||||||
<projectsecrets :secrets="secrets" :allsecrets="allsecrets" type="projectgroup" />
|
<projectsecrets
|
||||||
|
:secrets="secrets"
|
||||||
|
:allsecrets="allsecrets"
|
||||||
|
type="projectgroup"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<p class="panel-title">Variables</p>
|
<p class="panel-title">Variables</p>
|
||||||
<div class="p-4">
|
<div class="p-4">
|
||||||
<projectvars :variables="variables" :allvariables="allvariables" type="projectgroup" />
|
<projectvars
|
||||||
|
:variables="variables"
|
||||||
|
:allvariables="allvariables"
|
||||||
|
type="projectgroup"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -56,16 +66,13 @@
|
||||||
>
|
>
|
||||||
<p>
|
<p>
|
||||||
This operation
|
This operation
|
||||||
<strong>CANNOT</strong> be undone.
|
<strong>CANNOT</strong> be undone. This operation will remove
|
||||||
This operation will remove
|
|
||||||
<strong>{{ projectGroupPath }}</strong>
|
<strong>{{ projectGroupPath }}</strong>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<label class="block mb-2">
|
<label class="block mb-2">
|
||||||
Please type the project group name for confirmation:
|
Please type the project group name for confirmation:
|
||||||
<span
|
<span class="text-red-500 font-bold">{{ projectGroupName }}</span>
|
||||||
class="text-red-500 font-bold"
|
|
||||||
>{{ projectGroupName }}</span>
|
|
||||||
</label>
|
</label>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<input
|
<input
|
||||||
|
@ -79,7 +86,9 @@
|
||||||
class="btn btn-red"
|
class="btn btn-red"
|
||||||
@click="deleteProjectGroup()"
|
@click="deleteProjectGroup()"
|
||||||
:disabled="!deleteButtonEnabled"
|
:disabled="!deleteButtonEnabled"
|
||||||
>Delete Project Group</button>
|
>
|
||||||
|
Delete Project Group
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -98,21 +107,21 @@ import {
|
||||||
fetchSecrets,
|
fetchSecrets,
|
||||||
fetchVariables,
|
fetchVariables,
|
||||||
updateProjectGroup,
|
updateProjectGroup,
|
||||||
deleteProjectGroup
|
deleteProjectGroup,
|
||||||
} from "@/util/data.js";
|
} from '@/util/data.js';
|
||||||
|
|
||||||
import { projectGroupLink } from "@/util/link.js";
|
import { projectGroupLink } from '@/util/link.js';
|
||||||
|
|
||||||
import projectsecrets from "@/components/projectsecrets";
|
import projectsecrets from '@/components/projectsecrets';
|
||||||
import projectvars from "@/components/projectvars";
|
import projectvars from '@/components/projectvars';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { projectsecrets, projectvars },
|
components: { projectsecrets, projectvars },
|
||||||
name: "projectgroupsettings",
|
name: 'projectgroupsettings',
|
||||||
props: {
|
props: {
|
||||||
ownertype: String,
|
ownertype: String,
|
||||||
ownername: String,
|
ownername: String,
|
||||||
projectgroupref: Array
|
projectgroupref: Array,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -124,7 +133,7 @@ export default {
|
||||||
allsecrets: [],
|
allsecrets: [],
|
||||||
variables: [],
|
variables: [],
|
||||||
allvariables: [],
|
allvariables: [],
|
||||||
projectGroupNameToDelete: ""
|
projectGroupNameToDelete: '',
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -132,8 +141,8 @@ export default {
|
||||||
return this.projectgroupref[this.projectgroupref.length - 1];
|
return this.projectgroupref[this.projectgroupref.length - 1];
|
||||||
},
|
},
|
||||||
projectGroupPath: function () {
|
projectGroupPath: function () {
|
||||||
return ["", this.ownertype, this.ownername, ...this.projectgroupref].join(
|
return ['', this.ownertype, this.ownername, ...this.projectgroupref].join(
|
||||||
"/"
|
'/'
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
deleteButtonEnabled: function () {
|
deleteButtonEnabled: function () {
|
||||||
|
@ -141,7 +150,7 @@ export default {
|
||||||
},
|
},
|
||||||
isRootProjectGroup() {
|
isRootProjectGroup() {
|
||||||
return this.projectgroupref.length == 0;
|
return this.projectgroupref.length == 0;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
resetErrors() {
|
resetErrors() {
|
||||||
|
@ -154,12 +163,12 @@ export default {
|
||||||
let projectgroupref = [
|
let projectgroupref = [
|
||||||
this.ownertype,
|
this.ownertype,
|
||||||
this.ownername,
|
this.ownername,
|
||||||
...this.projectgroupref
|
...this.projectgroupref,
|
||||||
].join("/");
|
].join('/');
|
||||||
|
|
||||||
let visibility = "public";
|
let visibility = 'public';
|
||||||
if (this.projectGroupIsPrivate) {
|
if (this.projectGroupIsPrivate) {
|
||||||
visibility = "private";
|
visibility = 'private';
|
||||||
}
|
}
|
||||||
let { error } = await updateProjectGroup(
|
let { error } = await updateProjectGroup(
|
||||||
projectgroupref,
|
projectgroupref,
|
||||||
|
@ -175,8 +184,8 @@ export default {
|
||||||
let projectgroupref = [
|
let projectgroupref = [
|
||||||
this.ownertype,
|
this.ownertype,
|
||||||
this.ownername,
|
this.ownername,
|
||||||
...this.projectgroupref
|
...this.projectgroupref,
|
||||||
].join("/");
|
].join('/');
|
||||||
|
|
||||||
if (this.projectGroupNameToDelete == this.projectGroupName) {
|
if (this.projectGroupNameToDelete == this.projectGroupName) {
|
||||||
let { error } = await deleteProjectGroup(projectgroupref);
|
let { error } = await deleteProjectGroup(projectgroupref);
|
||||||
|
@ -192,70 +201,68 @@ export default {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created: async function () {
|
created: async function () {
|
||||||
let projectgroupref = [
|
let projectgroupref = [
|
||||||
this.ownertype,
|
this.ownertype,
|
||||||
this.ownername,
|
this.ownername,
|
||||||
...this.projectgroupref
|
...this.projectgroupref,
|
||||||
].join("/");
|
].join('/');
|
||||||
|
|
||||||
let { data, error } = await fetchProjectGroup(projectgroupref);
|
let { data, error } = await fetchProjectGroup(projectgroupref);
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.projectGroup = data;
|
this.projectGroup = data;
|
||||||
this.projectGroupIsPrivate = this.projectGroup.visibility == "private";
|
this.projectGroupIsPrivate = this.projectGroup.visibility == 'private';
|
||||||
|
|
||||||
({ data, error } = await fetchSecrets(
|
({ data, error } = await fetchSecrets(
|
||||||
"projectgroup",
|
'projectgroup',
|
||||||
projectgroupref,
|
projectgroupref,
|
||||||
false
|
false
|
||||||
));
|
));
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.secrets = data;
|
this.secrets = data;
|
||||||
|
|
||||||
({ data, error } = await fetchSecrets(
|
({ data, error } = await fetchSecrets(
|
||||||
"projectgroup",
|
'projectgroup',
|
||||||
projectgroupref,
|
projectgroupref,
|
||||||
true
|
true
|
||||||
));
|
));
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.allsecrets = data;
|
this.allsecrets = data;
|
||||||
|
|
||||||
({ data, error } = await fetchVariables(
|
({ data, error } = await fetchVariables(
|
||||||
"projectgroup",
|
'projectgroup',
|
||||||
projectgroupref,
|
projectgroupref,
|
||||||
false
|
false
|
||||||
));
|
));
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.variables = data;
|
this.variables = data;
|
||||||
|
|
||||||
({ data, error } = await fetchVariables(
|
({ data, error } = await fetchVariables(
|
||||||
"projectgroup",
|
'projectgroup',
|
||||||
projectgroupref,
|
projectgroupref,
|
||||||
true
|
true
|
||||||
));
|
));
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.allvariables = data;
|
this.allvariables = data;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
|
@ -2,12 +2,19 @@
|
||||||
<div>
|
<div>
|
||||||
<h4 class="text-xl my-3">Projects</h4>
|
<h4 class="text-xl my-3">Projects</h4>
|
||||||
<div v-if="fetchProjectsLoading" class="ml-6 flex w-48">
|
<div v-if="fetchProjectsLoading" class="ml-6 flex w-48">
|
||||||
<div v-bind:class="{ 'spinner': fetchProjectsLoading }"></div>
|
<div v-bind:class="{ spinner: fetchProjectsLoading }"></div>
|
||||||
</div>
|
</div>
|
||||||
<ul v-else-if="projects.length > 0">
|
<ul v-else-if="projects.length > 0">
|
||||||
<li class="mb-2 border rounded-l" v-for="project in projects" v-bind:key="project.id">
|
<li
|
||||||
|
class="mb-2 border rounded-l"
|
||||||
|
v-for="project in projects"
|
||||||
|
v-bind:key="project.id"
|
||||||
|
>
|
||||||
<div class="pl-4 py-4 flex items-center">
|
<div class="pl-4 py-4 flex items-center">
|
||||||
<router-link class="item" :to="projectLink(ownertype, ownername, ref(project.name))">
|
<router-link
|
||||||
|
class="item"
|
||||||
|
:to="projectLink(ownertype, ownername, ref(project.name))"
|
||||||
|
>
|
||||||
<span class="font-bold">{{ project.name }}</span>
|
<span class="font-bold">{{ project.name }}</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
|
@ -19,7 +26,7 @@
|
||||||
|
|
||||||
<h4 class="text-xl my-3">Project Groups</h4>
|
<h4 class="text-xl my-3">Project Groups</h4>
|
||||||
<div v-if="fetchProjectGroupsLoading" class="ml-6 flex w-48">
|
<div v-if="fetchProjectGroupsLoading" class="ml-6 flex w-48">
|
||||||
<div v-bind:class="{ 'spinner': fetchProjectGroupsLoading }"></div>
|
<div v-bind:class="{ spinner: fetchProjectGroupsLoading }"></div>
|
||||||
</div>
|
</div>
|
||||||
<ul v-else-if="projectgroups.length > 0">
|
<ul v-else-if="projectgroups.length > 0">
|
||||||
<li
|
<li
|
||||||
|
@ -44,18 +51,18 @@
|
||||||
<script>
|
<script>
|
||||||
import {
|
import {
|
||||||
fetchProjectGroupProjects,
|
fetchProjectGroupProjects,
|
||||||
fetchProjectGroupSubgroups
|
fetchProjectGroupSubgroups,
|
||||||
} from "@/util/data.js";
|
} from '@/util/data.js';
|
||||||
|
|
||||||
import { projectLink, projectGroupLink } from "@/util/link.js";
|
import { projectLink, projectGroupLink } from '@/util/link.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: {},
|
||||||
name: "Projects",
|
name: 'Projects',
|
||||||
props: {
|
props: {
|
||||||
ownertype: String,
|
ownertype: String,
|
||||||
ownername: String,
|
ownername: String,
|
||||||
projectgroupref: Array
|
projectgroupref: Array,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -65,7 +72,7 @@ export default {
|
||||||
fetchProjectsLoading: false,
|
fetchProjectsLoading: false,
|
||||||
|
|
||||||
projects: [],
|
projects: [],
|
||||||
projectgroups: []
|
projectgroups: [],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -76,7 +83,7 @@ export default {
|
||||||
this.fetchAbort = new AbortController();
|
this.fetchAbort = new AbortController();
|
||||||
this.fetchProjects(this.ownertype, this.ownername);
|
this.fetchProjects(this.ownertype, this.ownername);
|
||||||
this.fetchProjectGroups(this.ownertype, this.ownername);
|
this.fetchProjectGroups(this.ownertype, this.ownername);
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
startFetchProjectsLoading() {
|
startFetchProjectsLoading() {
|
||||||
|
@ -107,7 +114,7 @@ export default {
|
||||||
|
|
||||||
this.startFetchProjectsLoading();
|
this.startFetchProjectsLoading();
|
||||||
let { data, error, aborted } = await fetchProjectGroupProjects(
|
let { data, error, aborted } = await fetchProjectGroupProjects(
|
||||||
projectgroupref.join("/"),
|
projectgroupref.join('/'),
|
||||||
this.fetchAbort.signal
|
this.fetchAbort.signal
|
||||||
);
|
);
|
||||||
this.stopFetchProjectsLoading();
|
this.stopFetchProjectsLoading();
|
||||||
|
@ -115,7 +122,7 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.projects = data;
|
this.projects = data;
|
||||||
|
@ -127,7 +134,7 @@ export default {
|
||||||
}
|
}
|
||||||
this.startFetchProjectGroupsLoading();
|
this.startFetchProjectGroupsLoading();
|
||||||
let { data, error, aborted } = await fetchProjectGroupSubgroups(
|
let { data, error, aborted } = await fetchProjectGroupSubgroups(
|
||||||
projectgroupref.join("/"),
|
projectgroupref.join('/'),
|
||||||
this.fetchAbort.signal
|
this.fetchAbort.signal
|
||||||
);
|
);
|
||||||
this.stopFetchProjectGroupsLoading();
|
this.stopFetchProjectGroupsLoading();
|
||||||
|
@ -135,13 +142,13 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.projectgroups = data;
|
this.projectgroups = data;
|
||||||
},
|
},
|
||||||
projectLink: projectLink,
|
projectLink: projectLink,
|
||||||
projectGroupLink: projectGroupLink
|
projectGroupLink: projectGroupLink,
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
this.fetchAbort = new AbortController();
|
this.fetchAbort = new AbortController();
|
||||||
|
@ -152,9 +159,8 @@ export default {
|
||||||
if (this.fetchAbort) {
|
if (this.fetchAbort) {
|
||||||
this.fetchAbort.abort();
|
this.fetchAbort.abort();
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
|
@ -7,33 +7,34 @@
|
||||||
<hr class="my-6 border-t" />
|
<hr class="my-6 border-t" />
|
||||||
|
|
||||||
<h5 class="text-2xl">All secrets (local and inherited)</h5>
|
<h5 class="text-2xl">All secrets (local and inherited)</h5>
|
||||||
<secrets v-if="allsecrets.length" :secrets="allsecrets" :showparentpath="true" />
|
<secrets
|
||||||
|
v-if="allsecrets.length"
|
||||||
|
:secrets="allsecrets"
|
||||||
|
:showparentpath="true"
|
||||||
|
/>
|
||||||
<span v-else>No secrets</span>
|
<span v-else>No secrets</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import secrets from "@/components/secrets";
|
import secrets from '@/components/secrets';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { secrets },
|
components: { secrets },
|
||||||
name: "projectsecrets",
|
name: 'projectsecrets',
|
||||||
props: {
|
props: {
|
||||||
secrets: Array,
|
secrets: Array,
|
||||||
allsecrets: Array,
|
allsecrets: Array,
|
||||||
type: String
|
type: String,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
typetitle() {
|
typetitle() {
|
||||||
if (this.type == "project") return "Project";
|
if (this.type == 'project') return 'Project';
|
||||||
if (this.type == "projectgroup") return "Project group";
|
if (this.type == 'projectgroup') return 'Project group';
|
||||||
return "";
|
return '';
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,8 @@
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label class="checkbox">
|
<label class="checkbox">
|
||||||
<input type="checkbox" v-model="project.pass_vars_to_forked_pr" />
|
<input type="checkbox" v-model="project.pass_vars_to_forked_pr" />
|
||||||
Pass variables to run even if triggered by PR from forked repo (DANGEROUS)
|
Pass variables to run even if triggered by PR from forked repo
|
||||||
|
(DANGEROUS)
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-blue" @click="updateProject()">Update</button>
|
<button class="btn btn-blue" @click="updateProject()">Update</button>
|
||||||
|
@ -38,14 +39,22 @@
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<p class="panel-title">Secrets</p>
|
<p class="panel-title">Secrets</p>
|
||||||
<div class="p-4">
|
<div class="p-4">
|
||||||
<projectsecrets :secrets="secrets" :allsecrets="allsecrets" type="project" />
|
<projectsecrets
|
||||||
|
:secrets="secrets"
|
||||||
|
:allsecrets="allsecrets"
|
||||||
|
type="project"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<p class="panel-title">Variables</p>
|
<p class="panel-title">Variables</p>
|
||||||
<div class="p-4">
|
<div class="p-4">
|
||||||
<projectvars :variables="variables" :allvariables="allvariables" type="project" />
|
<projectvars
|
||||||
|
:variables="variables"
|
||||||
|
:allvariables="allvariables"
|
||||||
|
type="project"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -59,16 +68,13 @@
|
||||||
>
|
>
|
||||||
<p>
|
<p>
|
||||||
This operation
|
This operation
|
||||||
<strong>CANNOT</strong> be undone.
|
<strong>CANNOT</strong> be undone. This operation will remove
|
||||||
This operation will remove
|
|
||||||
<strong>{{ projectPath }}</strong>
|
<strong>{{ projectPath }}</strong>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<label class="block mb-2">
|
<label class="block mb-2">
|
||||||
Please type the project name for confirmation:
|
Please type the project name for confirmation:
|
||||||
<span
|
<span class="text-red-500 font-bold">{{ projectName }}</span>
|
||||||
class="text-red-500 font-bold"
|
|
||||||
>{{ projectName }}</span>
|
|
||||||
</label>
|
</label>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<input
|
<input
|
||||||
|
@ -82,7 +88,9 @@
|
||||||
class="btn btn-red"
|
class="btn btn-red"
|
||||||
@click="deleteProject()"
|
@click="deleteProject()"
|
||||||
:disabled="!deleteButtonEnabled"
|
:disabled="!deleteButtonEnabled"
|
||||||
>Delete Project</button>
|
>
|
||||||
|
Delete Project
|
||||||
|
</button>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="deleteProjectError"
|
v-if="deleteProjectError"
|
||||||
|
@ -93,21 +101,30 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="p-4 border-t">
|
<div class="p-4 border-t">
|
||||||
<h4 class="mb-4 title text-xl">Change remote repository linked account</h4>
|
<h4 class="mb-4 title text-xl">
|
||||||
|
Change remote repository linked account
|
||||||
|
</h4>
|
||||||
<div
|
<div
|
||||||
class="mb-4 bg-red-100 border-l-4 border-red-500 text-red-700 p-4 rounded"
|
class="mb-4 bg-red-100 border-l-4 border-red-500 text-red-700 p-4 rounded"
|
||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
<p>This operation will change the linked account associated with the project remote repository to the current user linked account</p>
|
<p>
|
||||||
|
This operation will change the linked account associated with the
|
||||||
|
project remote repository to the current user linked account
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-red" @click="updateRepoLinkedAccount()">Change</button>
|
<button class="btn btn-red" @click="updateRepoLinkedAccount()">
|
||||||
|
Change
|
||||||
|
</button>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="updateRepoLinkedAccountError"
|
v-if="updateRepoLinkedAccountError"
|
||||||
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
<span class="block sm:inline">{{ updateRepoLinkedAccountError }}</span>
|
<span class="block sm:inline">{{
|
||||||
|
updateRepoLinkedAccountError
|
||||||
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -121,21 +138,21 @@ import {
|
||||||
fetchVariables,
|
fetchVariables,
|
||||||
updateProject,
|
updateProject,
|
||||||
deleteProject,
|
deleteProject,
|
||||||
projectUpdateRepoLinkedAccount
|
projectUpdateRepoLinkedAccount,
|
||||||
} from "@/util/data.js";
|
} from '@/util/data.js';
|
||||||
|
|
||||||
import { projectGroupLink } from "@/util/link.js";
|
import { projectGroupLink } from '@/util/link.js';
|
||||||
|
|
||||||
import projectsecrets from "@/components/projectsecrets";
|
import projectsecrets from '@/components/projectsecrets';
|
||||||
import projectvars from "@/components/projectvars";
|
import projectvars from '@/components/projectvars';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { projectsecrets, projectvars },
|
components: { projectsecrets, projectvars },
|
||||||
name: "projectsettings",
|
name: 'projectsettings',
|
||||||
props: {
|
props: {
|
||||||
ownertype: String,
|
ownertype: String,
|
||||||
ownername: String,
|
ownername: String,
|
||||||
projectref: Array
|
projectref: Array,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -148,7 +165,7 @@ export default {
|
||||||
allsecrets: [],
|
allsecrets: [],
|
||||||
variables: [],
|
variables: [],
|
||||||
allvariables: [],
|
allvariables: [],
|
||||||
projectNameToDelete: ""
|
projectNameToDelete: '',
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -156,11 +173,11 @@ export default {
|
||||||
return this.projectref[this.projectref.length - 1];
|
return this.projectref[this.projectref.length - 1];
|
||||||
},
|
},
|
||||||
projectPath: function () {
|
projectPath: function () {
|
||||||
return ["", this.ownertype, this.ownername, ...this.projectref].join("/");
|
return ['', this.ownertype, this.ownername, ...this.projectref].join('/');
|
||||||
},
|
},
|
||||||
deleteButtonEnabled: function () {
|
deleteButtonEnabled: function () {
|
||||||
return this.projectNameToDelete == this.projectName;
|
return this.projectNameToDelete == this.projectName;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
resetErrors() {
|
resetErrors() {
|
||||||
|
@ -174,12 +191,12 @@ export default {
|
||||||
let projectref = [
|
let projectref = [
|
||||||
this.ownertype,
|
this.ownertype,
|
||||||
this.ownername,
|
this.ownername,
|
||||||
...this.projectref
|
...this.projectref,
|
||||||
].join("/");
|
].join('/');
|
||||||
|
|
||||||
let visibility = "public";
|
let visibility = 'public';
|
||||||
if (this.projectIsPrivate) {
|
if (this.projectIsPrivate) {
|
||||||
visibility = "private";
|
visibility = 'private';
|
||||||
}
|
}
|
||||||
let { error } = await updateProject(
|
let { error } = await updateProject(
|
||||||
projectref,
|
projectref,
|
||||||
|
@ -198,8 +215,8 @@ export default {
|
||||||
let projectref = [
|
let projectref = [
|
||||||
this.ownertype,
|
this.ownertype,
|
||||||
this.ownername,
|
this.ownername,
|
||||||
...this.projectref
|
...this.projectref,
|
||||||
].join("/");
|
].join('/');
|
||||||
|
|
||||||
if (this.projectNameToDelete == this.projectName) {
|
if (this.projectNameToDelete == this.projectName) {
|
||||||
let { error } = await deleteProject(projectref);
|
let { error } = await deleteProject(projectref);
|
||||||
|
@ -222,60 +239,59 @@ export default {
|
||||||
let projectref = [
|
let projectref = [
|
||||||
this.ownertype,
|
this.ownertype,
|
||||||
this.ownername,
|
this.ownername,
|
||||||
...this.projectref
|
...this.projectref,
|
||||||
].join("/");
|
].join('/');
|
||||||
|
|
||||||
let { error } = await projectUpdateRepoLinkedAccount(projectref);
|
let { error } = await projectUpdateRepoLinkedAccount(projectref);
|
||||||
if (error) {
|
if (error) {
|
||||||
this.updateRepoLinkedAccountError = error;
|
this.updateRepoLinkedAccountError = error;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created: async function () {
|
created: async function () {
|
||||||
let projectref = [this.ownertype, this.ownername, ...this.projectref].join(
|
let projectref = [this.ownertype, this.ownername, ...this.projectref].join(
|
||||||
"/"
|
'/'
|
||||||
);
|
);
|
||||||
|
|
||||||
let { data, error } = await fetchProject(projectref);
|
let { data, error } = await fetchProject(projectref);
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.project = data;
|
this.project = data;
|
||||||
this.projectIsPrivate = this.project.visibility == "private";
|
this.projectIsPrivate = this.project.visibility == 'private';
|
||||||
|
|
||||||
({ data, error } = await fetchSecrets("project", projectref, false));
|
({ data, error } = await fetchSecrets('project', projectref, false));
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.secrets = data;
|
this.secrets = data;
|
||||||
|
|
||||||
({ data, error } = await fetchSecrets("project", projectref, true));
|
({ data, error } = await fetchSecrets('project', projectref, true));
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.allsecrets = data;
|
this.allsecrets = data;
|
||||||
|
|
||||||
({ data, error } = await fetchVariables("project", projectref, false));
|
({ data, error } = await fetchVariables('project', projectref, false));
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.variables = data;
|
this.variables = data;
|
||||||
|
|
||||||
({ data, error } = await fetchVariables("project", projectref, true));
|
({ data, error } = await fetchVariables('project', projectref, true));
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.allvariables = data;
|
this.allvariables = data;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
|
@ -7,32 +7,34 @@
|
||||||
<hr class="my-6 border-t" />
|
<hr class="my-6 border-t" />
|
||||||
|
|
||||||
<h5 class="text-2xl">All variables (local and inherited)</h5>
|
<h5 class="text-2xl">All variables (local and inherited)</h5>
|
||||||
<vars v-if="allvariables.length" :variables="allvariables" :showparentpath="true" />
|
<vars
|
||||||
|
v-if="allvariables.length"
|
||||||
|
:variables="allvariables"
|
||||||
|
:showparentpath="true"
|
||||||
|
/>
|
||||||
<span v-else>No variables</span>
|
<span v-else>No variables</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import vars from "@/components/vars";
|
import vars from '@/components/vars';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { vars },
|
components: { vars },
|
||||||
name: "projectvars",
|
name: 'projectvars',
|
||||||
props: {
|
props: {
|
||||||
variables: Array,
|
variables: Array,
|
||||||
allvariables: Array,
|
allvariables: Array,
|
||||||
type: String
|
type: String,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
typetitle() {
|
typetitle() {
|
||||||
if (this.type == "project") return "Project";
|
if (this.type == 'project') return 'Project';
|
||||||
if (this.type == "projectgroup") return "Project group";
|
if (this.type == 'projectgroup') return 'Project group';
|
||||||
return "";
|
return '';
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,9 @@
|
||||||
@submit.prevent="$emit('login', { username })"
|
@submit.prevent="$emit('login', { username })"
|
||||||
>
|
>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label class="block text-sm font-bold mb-2" for="username">Remote Username</label>
|
<label class="block text-sm font-bold mb-2" for="username"
|
||||||
|
>Remote Username</label
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||||
id="username"
|
id="username"
|
||||||
|
@ -13,38 +15,38 @@
|
||||||
placeholder="Username"
|
placeholder="Username"
|
||||||
:disabled="true"
|
:disabled="true"
|
||||||
v-model="remoteUsername"
|
v-model="remoteUsername"
|
||||||
>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label class="block text-sm font-bold mb-2" for="username">Username</label>
|
<label class="block text-sm font-bold mb-2" for="username"
|
||||||
|
>Username</label
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||||
id="username"
|
id="username"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Username"
|
placeholder="Username"
|
||||||
v-model="username"
|
v-model="username"
|
||||||
>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-center">
|
<div class="flex justify-center">
|
||||||
<button
|
<button
|
||||||
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
|
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
|
||||||
type="submit"
|
type="submit"
|
||||||
>Register</button>
|
>
|
||||||
|
Register
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "RegisterForm",
|
name: 'RegisterForm',
|
||||||
props: {
|
props: {
|
||||||
remoteUsername: String,
|
remoteUsername: String,
|
||||||
username: String
|
username: String,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
v-bind:key="repo.id"
|
v-bind:key="repo.id"
|
||||||
@click="select(index)"
|
@click="select(index)"
|
||||||
>
|
>
|
||||||
<input type="radio" :checked="selectedrepo == index">
|
<input type="radio" :checked="selectedrepo == index" />
|
||||||
{{ repo.path }}
|
{{ repo.path }}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -18,23 +18,22 @@
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: {},
|
||||||
name: "remoterepos",
|
name: 'remoterepos',
|
||||||
props: {
|
props: {
|
||||||
remoterepos: Array
|
remoterepos: Array,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
selectedrepo: null
|
selectedrepo: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
select(index) {
|
select(index) {
|
||||||
this.selectedrepo = index;
|
this.selectedrepo = index;
|
||||||
this.$emit("reposelected", this.remoterepos[index].path);
|
this.$emit('reposelected', this.remoterepos[index].path);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
|
@ -31,15 +31,23 @@
|
||||||
<span
|
<span
|
||||||
class="mr-3 rounded px-2 py-1 text-xs"
|
class="mr-3 rounded px-2 py-1 text-xs"
|
||||||
:class="'is-' + runResultClass(run)"
|
:class="'is-' + runResultClass(run)"
|
||||||
>{{ runStatus(run) | capitalize }}</span>
|
>{{ runStatus(run) | capitalize }}</span
|
||||||
|
>
|
||||||
<span
|
<span
|
||||||
v-if="stillRunning(run)"
|
v-if="stillRunning(run)"
|
||||||
class="rounded bg-gray-500 text-white px-2 py-1 text-xs"
|
class="rounded bg-gray-500 text-white px-2 py-1 text-xs"
|
||||||
>Still running</span>
|
>Still running</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="mb-6">
|
||||||
|
{{ run.annotations.message.split(/\r?\n/)[0] }}
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-6">{{run.annotations.message.split(/\r?\n/)[0]}}</div>
|
|
||||||
<div>
|
<div>
|
||||||
<a :href="run.annotations.commit_link" class="block" target="_blank">
|
<a
|
||||||
|
:href="run.annotations.commit_link"
|
||||||
|
class="block"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
<i class="mdi mdi-source-commit mdi-rotate-90"></i>
|
<i class="mdi mdi-source-commit mdi-rotate-90"></i>
|
||||||
<span>{{ run.annotations.commit_sha.substring(0, 8) }}</span>
|
<span>{{ run.annotations.commit_sha.substring(0, 8) }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
@ -85,12 +93,18 @@
|
||||||
<div class="w-1/6 flex items-start justify-between">
|
<div class="w-1/6 flex items-start justify-between">
|
||||||
<div class="relative ml-auto mr-3">
|
<div class="relative ml-auto mr-3">
|
||||||
<div
|
<div
|
||||||
v-if="run.can_restart_from_scratch || run.can_restart_from_failed_tasks"
|
v-if="
|
||||||
|
run.can_restart_from_scratch ||
|
||||||
|
run.can_restart_from_failed_tasks
|
||||||
|
"
|
||||||
class="flex"
|
class="flex"
|
||||||
v-click-outside="() => dropdownActive = false"
|
v-click-outside="() => (dropdownActive = false)"
|
||||||
>
|
>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<button class="btn btn-blue" @click="dropdownActive = !dropdownActive">
|
<button
|
||||||
|
class="btn btn-blue"
|
||||||
|
@click="dropdownActive = !dropdownActive"
|
||||||
|
>
|
||||||
<span>Restart</span>
|
<span>Restart</span>
|
||||||
<i class="ml-3 mdi mdi-restart" aria-hidden="true"></i>
|
<i class="ml-3 mdi mdi-restart" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
|
@ -107,14 +121,16 @@
|
||||||
v-if="run.can_restart_from_scratch"
|
v-if="run.can_restart_from_scratch"
|
||||||
class="block px-4 py-2 hover:bg-blue-500 hover:text-white cursor-pointer"
|
class="block px-4 py-2 hover:bg-blue-500 hover:text-white cursor-pointer"
|
||||||
@click="restartRun(run.id, true)"
|
@click="restartRun(run.id, true)"
|
||||||
>From start</a>
|
>From start</a
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
v-if="run.can_restart_from_failed_tasks"
|
v-if="run.can_restart_from_failed_tasks"
|
||||||
class="block px-4 py-2 hover:bg-blue-500 hover:text-white cursor-pointer"
|
class="block px-4 py-2 hover:bg-blue-500 hover:text-white cursor-pointer"
|
||||||
@click="restartRun(run.id)"
|
@click="restartRun(run.id)"
|
||||||
>From failed tasks</a>
|
>From failed tasks</a
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -122,13 +138,17 @@
|
||||||
class="btn btn-red"
|
class="btn btn-red"
|
||||||
v-if="run.phase == 'queued'"
|
v-if="run.phase == 'queued'"
|
||||||
@click="cancelRun(run.id)"
|
@click="cancelRun(run.id)"
|
||||||
>Cancel</button>
|
>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
class="btn btn-red"
|
class="btn btn-red"
|
||||||
v-if="run.phase == 'running'"
|
v-if="run.phase == 'running'"
|
||||||
:disabled="run.stopping"
|
:disabled="run.stopping"
|
||||||
@click="stopRun(run.id)"
|
@click="stopRun(run.id)"
|
||||||
>Stop</button>
|
>
|
||||||
|
Stop
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -138,27 +158,27 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as vClickOutside from "v-click-outside-x";
|
import * as vClickOutside from 'v-click-outside-x';
|
||||||
|
|
||||||
import { cancelRun, stopRun, restartRun } from "@/util/data.js";
|
import { cancelRun, stopRun, restartRun } from '@/util/data.js';
|
||||||
import { userDirectRunLink, projectRunLink } from "@/util/link.js";
|
import { userDirectRunLink, projectRunLink } from '@/util/link.js';
|
||||||
import { runStatus, runResultClass } from "@/util/run.js";
|
import { runStatus, runResultClass } from '@/util/run.js';
|
||||||
|
|
||||||
import * as moment from "moment";
|
import * as moment from 'moment';
|
||||||
import momentDurationFormatSetup from "moment-duration-format";
|
import momentDurationFormatSetup from 'moment-duration-format';
|
||||||
|
|
||||||
momentDurationFormatSetup(moment);
|
momentDurationFormatSetup(moment);
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "rundetail",
|
name: 'rundetail',
|
||||||
directives: {
|
directives: {
|
||||||
clickOutside: vClickOutside.directive
|
clickOutside: vClickOutside.directive,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
ownertype: String,
|
ownertype: String,
|
||||||
ownername: String,
|
ownername: String,
|
||||||
projectref: Array,
|
projectref: Array,
|
||||||
run: Object
|
run: Object,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -166,7 +186,7 @@ export default {
|
||||||
stopRunError: null,
|
stopRunError: null,
|
||||||
cancelRunError: null,
|
cancelRunError: null,
|
||||||
restartRunError: null,
|
restartRunError: null,
|
||||||
dropdownActive: false
|
dropdownActive: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -178,14 +198,14 @@ export default {
|
||||||
this.restartRunError = null;
|
this.restartRunError = null;
|
||||||
},
|
},
|
||||||
stillRunning(run) {
|
stillRunning(run) {
|
||||||
return run.result != "unknown" && run.phase == "running";
|
return run.result != 'unknown' && run.phase == 'running';
|
||||||
},
|
},
|
||||||
taskClass(task) {
|
taskClass(task) {
|
||||||
if (task.status == "success") return "success";
|
if (task.status == 'success') return 'success';
|
||||||
if (task.status == "failed") return "failed";
|
if (task.status == 'failed') return 'failed';
|
||||||
if (task.status == "stopped") return "failed";
|
if (task.status == 'stopped') return 'failed';
|
||||||
if (task.status == "running") return "running";
|
if (task.status == 'running') return 'running';
|
||||||
return "unknown";
|
return 'unknown';
|
||||||
},
|
},
|
||||||
async stopRun(runid) {
|
async stopRun(runid) {
|
||||||
this.resetErrors();
|
this.resetErrors();
|
||||||
|
@ -207,7 +227,7 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.run.phase = "cancelled";
|
this.run.phase = 'cancelled';
|
||||||
},
|
},
|
||||||
async restartRun(runid, fromStart) {
|
async restartRun(runid, fromStart) {
|
||||||
this.dropdownActive = false;
|
this.dropdownActive = false;
|
||||||
|
@ -231,7 +251,7 @@ export default {
|
||||||
this.$router.push(runLink);
|
this.$router.push(runLink);
|
||||||
},
|
},
|
||||||
duration(run) {
|
duration(run) {
|
||||||
let formatString = "h:mm:ss[s]";
|
let formatString = 'h:mm:ss[s]';
|
||||||
let start = moment(run.start_time);
|
let start = moment(run.start_time);
|
||||||
let end = moment(run.end_time);
|
let end = moment(run.end_time);
|
||||||
|
|
||||||
|
@ -244,30 +264,29 @@ export default {
|
||||||
return moment.duration(end.diff(start)).format(formatString);
|
return moment.duration(end.diff(start)).format(formatString);
|
||||||
},
|
},
|
||||||
endTime(run) {
|
endTime(run) {
|
||||||
let formatString = "lll";
|
let formatString = 'lll';
|
||||||
let end = moment(run.end_time);
|
let end = moment(run.end_time);
|
||||||
|
|
||||||
if (run.end_time === null) {
|
if (run.end_time === null) {
|
||||||
return "";
|
return '';
|
||||||
}
|
}
|
||||||
return "Finished " + end.format(formatString);
|
return 'Finished ' + end.format(formatString);
|
||||||
},
|
},
|
||||||
endTimeHuman(run) {
|
endTimeHuman(run) {
|
||||||
let end = moment(run.end_time);
|
let end = moment(run.end_time);
|
||||||
|
|
||||||
if (run.end_time === null) {
|
if (run.end_time === null) {
|
||||||
return "";
|
return '';
|
||||||
}
|
}
|
||||||
return end.fromNow();
|
return end.fromNow();
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
window.setInterval(() => {
|
window.setInterval(() => {
|
||||||
this.now = moment();
|
this.now = moment();
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ml-6 flex w-48">
|
<div class="ml-6 flex w-48">
|
||||||
<div v-bind:class="{ 'spinner': fetchRunsLoading }"></div>
|
<div v-bind:class="{ spinner: fetchRunsLoading }"></div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="runs">
|
<div v-if="runs">
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -67,14 +67,20 @@
|
||||||
<span
|
<span
|
||||||
v-if="waitingApproval(run)"
|
v-if="waitingApproval(run)"
|
||||||
class="w-2/12 bg-gray-200 rounded-full px-3 py-1 text-sm text-center font-semibold mr-2"
|
class="w-2/12 bg-gray-200 rounded-full px-3 py-1 text-sm text-center font-semibold mr-2"
|
||||||
>Waiting Approval</span>
|
>Waiting Approval</span
|
||||||
|
>
|
||||||
<span
|
<span
|
||||||
v-if="stillRunning(run)"
|
v-if="stillRunning(run)"
|
||||||
class="w-2/12 bg-gray-200 rounded-full px-3 py-1 text-sm text-center font-semibold mr-2"
|
class="w-2/12 bg-gray-200 rounded-full px-3 py-1 text-sm text-center font-semibold mr-2"
|
||||||
>Still running</span>
|
>Still running</span
|
||||||
|
>
|
||||||
<div class="w-32">
|
<div class="w-32">
|
||||||
<span>#{{ run.counter }}</span>
|
<span>#{{ run.counter }}</span>
|
||||||
<a :href="run.annotations.commit_link" class="block" target="_blank">
|
<a
|
||||||
|
:href="run.annotations.commit_link"
|
||||||
|
class="block"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
<i class="mdi mdi-source-commit mdi-rotate-90 mr-1"></i>
|
<i class="mdi mdi-source-commit mdi-rotate-90 mr-1"></i>
|
||||||
<span>{{ run.annotations.commit_sha.substring(0, 8) }}</span>
|
<span>{{ run.annotations.commit_sha.substring(0, 8) }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
@ -97,7 +103,9 @@
|
||||||
v-if="hasMoreRuns"
|
v-if="hasMoreRuns"
|
||||||
class="bg-transparent hover:bg-blue-500 text-blue-700 font-semibold hover:text-white py-2 px-4 border border-blue-500 hover:border-transparent rounded"
|
class="bg-transparent hover:bg-blue-500 text-blue-700 font-semibold hover:text-white py-2 px-4 border border-blue-500 hover:border-transparent rounded"
|
||||||
@click="loadMoreRuns()"
|
@click="loadMoreRuns()"
|
||||||
>Load more...</button>
|
>
|
||||||
|
Load more...
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="runs && runs.length == 0" class>No runs</div>
|
<div v-if="runs && runs.length == 0" class>No runs</div>
|
||||||
|
@ -105,22 +113,22 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { fetchUser, fetchProject, fetchRuns } from "@/util/data.js";
|
import { fetchUser, fetchProject, fetchRuns } from '@/util/data.js';
|
||||||
import { userDirectRunLink, projectRunLink } from "@/util/link.js";
|
import { userDirectRunLink, projectRunLink } from '@/util/link.js';
|
||||||
import { runResultClass } from "@/util/run.js";
|
import { runResultClass } from '@/util/run.js';
|
||||||
import * as moment from "moment";
|
import * as moment from 'moment';
|
||||||
import momentDurationFormatSetup from "moment-duration-format";
|
import momentDurationFormatSetup from 'moment-duration-format';
|
||||||
|
|
||||||
momentDurationFormatSetup(moment);
|
momentDurationFormatSetup(moment);
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: {},
|
||||||
name: "runs",
|
name: 'runs',
|
||||||
props: {
|
props: {
|
||||||
ownertype: String,
|
ownertype: String,
|
||||||
ownername: String,
|
ownername: String,
|
||||||
projectref: Array,
|
projectref: Array,
|
||||||
query: String
|
query: String,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -137,7 +145,7 @@ export default {
|
||||||
wantedRunsNumber: 25,
|
wantedRunsNumber: 25,
|
||||||
hasMoreRuns: false,
|
hasMoreRuns: false,
|
||||||
project: null,
|
project: null,
|
||||||
user: null
|
user: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -145,7 +153,7 @@ export default {
|
||||||
this.runs = null;
|
this.runs = null;
|
||||||
this.hasMoreRuns = false;
|
this.hasMoreRuns = false;
|
||||||
this.update();
|
this.update();
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
projectRunLink: projectRunLink,
|
projectRunLink: projectRunLink,
|
||||||
|
@ -161,7 +169,7 @@ export default {
|
||||||
this.fetchRunsLoading = false;
|
this.fetchRunsLoading = false;
|
||||||
},
|
},
|
||||||
stillRunning(run) {
|
stillRunning(run) {
|
||||||
return run.result != "unknown" && run.phase == "running";
|
return run.result != 'unknown' && run.phase == 'running';
|
||||||
},
|
},
|
||||||
waitingApproval(run) {
|
waitingApproval(run) {
|
||||||
return run.tasks_waiting_approval.length > 0;
|
return run.tasks_waiting_approval.length > 0;
|
||||||
|
@ -183,8 +191,8 @@ export default {
|
||||||
let projectref = [
|
let projectref = [
|
||||||
this.ownertype,
|
this.ownertype,
|
||||||
this.ownername,
|
this.ownername,
|
||||||
...this.projectref
|
...this.projectref,
|
||||||
].join("/");
|
].join('/');
|
||||||
|
|
||||||
let { data, error, aborted } = await fetchProject(
|
let { data, error, aborted } = await fetchProject(
|
||||||
projectref,
|
projectref,
|
||||||
|
@ -194,7 +202,7 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.project = data;
|
this.project = data;
|
||||||
|
@ -212,7 +220,7 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.user = data;
|
this.user = data;
|
||||||
|
@ -228,17 +236,17 @@ export default {
|
||||||
let group;
|
let group;
|
||||||
let lastrun = false;
|
let lastrun = false;
|
||||||
if (this.project !== null) {
|
if (this.project !== null) {
|
||||||
if (this.query == "branches") {
|
if (this.query == 'branches') {
|
||||||
group = "/project/" + this.project.id + "/branch";
|
group = '/project/' + this.project.id + '/branch';
|
||||||
} else if (this.query == "tags") {
|
} else if (this.query == 'tags') {
|
||||||
group = "/project/" + this.project.id + "/tag";
|
group = '/project/' + this.project.id + '/tag';
|
||||||
} else if (this.query == "pullrequests") {
|
} else if (this.query == 'pullrequests') {
|
||||||
group = "/project/" + this.project.id + "/pr";
|
group = '/project/' + this.project.id + '/pr';
|
||||||
} else {
|
} else {
|
||||||
group = "/project/" + this.project.id;
|
group = '/project/' + this.project.id;
|
||||||
}
|
}
|
||||||
} else if (this.user !== null) {
|
} else if (this.user !== null) {
|
||||||
group = "/user/" + this.user.id;
|
group = '/user/' + this.user.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
let newRuns = [];
|
let newRuns = [];
|
||||||
|
@ -289,7 +297,7 @@ export default {
|
||||||
}, 2000);
|
}, 2000);
|
||||||
},
|
},
|
||||||
duration(run) {
|
duration(run) {
|
||||||
let formatString = "h:mm:ss[s]";
|
let formatString = 'h:mm:ss[s]';
|
||||||
let start = moment(run.start_time);
|
let start = moment(run.start_time);
|
||||||
let end = moment(run.end_time);
|
let end = moment(run.end_time);
|
||||||
|
|
||||||
|
@ -302,22 +310,22 @@ export default {
|
||||||
return moment.duration(end.diff(start)).format(formatString);
|
return moment.duration(end.diff(start)).format(formatString);
|
||||||
},
|
},
|
||||||
endTime(run) {
|
endTime(run) {
|
||||||
let formatString = "lll";
|
let formatString = 'lll';
|
||||||
let end = moment(run.end_time);
|
let end = moment(run.end_time);
|
||||||
|
|
||||||
if (run.end_time === null) {
|
if (run.end_time === null) {
|
||||||
return "";
|
return '';
|
||||||
}
|
}
|
||||||
return "Finished " + end.format(formatString);
|
return 'Finished ' + end.format(formatString);
|
||||||
},
|
},
|
||||||
endTimeHuman(run) {
|
endTimeHuman(run) {
|
||||||
let end = moment(run.end_time);
|
let end = moment(run.end_time);
|
||||||
|
|
||||||
if (run.end_time === null) {
|
if (run.end_time === null) {
|
||||||
return "";
|
return '';
|
||||||
}
|
}
|
||||||
return end.fromNow();
|
return end.fromNow();
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
window.setInterval(() => {
|
window.setInterval(() => {
|
||||||
|
@ -331,9 +339,8 @@ export default {
|
||||||
this.fetchAbort.abort();
|
this.fetchAbort.abort();
|
||||||
}
|
}
|
||||||
clearTimeout(this.fetchRunsSchedule);
|
clearTimeout(this.fetchRunsSchedule);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
|
@ -7,7 +7,12 @@
|
||||||
>
|
>
|
||||||
<div>{{ fetchRunError }}</div>
|
<div>{{ fetchRunError }}</div>
|
||||||
</div>
|
</div>
|
||||||
<rundetail :run="run" :ownertype="ownertype" :ownername="ownername" :projectref="projectref" />
|
<rundetail
|
||||||
|
:run="run"
|
||||||
|
:ownertype="ownertype"
|
||||||
|
:ownername="ownername"
|
||||||
|
:projectref="projectref"
|
||||||
|
/>
|
||||||
<div v-if="run">
|
<div v-if="run">
|
||||||
<div v-if="run.phase != 'setuperror'">
|
<div v-if="run.phase != 'setuperror'">
|
||||||
<div class="flex items-center my-6 justify-between">
|
<div class="flex items-center my-6 justify-between">
|
||||||
|
@ -42,7 +47,8 @@
|
||||||
class="font-mono leading-snug text-xs"
|
class="font-mono leading-snug text-xs"
|
||||||
v-for="(error, i) in run.setup_errors"
|
v-for="(error, i) in run.setup_errors"
|
||||||
v-bind:key="i"
|
v-bind:key="i"
|
||||||
>{{error}}</pre>
|
>{{ error }}</pre
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -50,21 +56,21 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { fetchRun } from "@/util/data.js";
|
import { fetchRun } from '@/util/data.js';
|
||||||
import { userDirectRunTaskLink, projectRunTaskLink } from "@/util/link.js";
|
import { userDirectRunTaskLink, projectRunTaskLink } from '@/util/link.js';
|
||||||
|
|
||||||
import rundetail from "@/components/rundetail.vue";
|
import rundetail from '@/components/rundetail.vue';
|
||||||
import tasks from "@/components/tasks.vue";
|
import tasks from '@/components/tasks.vue';
|
||||||
import tasksgraph from "@/components/tasksgraph.vue";
|
import tasksgraph from '@/components/tasksgraph.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "runsummary",
|
name: 'runsummary',
|
||||||
components: { rundetail, tasks, tasksgraph },
|
components: { rundetail, tasks, tasksgraph },
|
||||||
props: {
|
props: {
|
||||||
ownertype: String,
|
ownertype: String,
|
||||||
ownername: String,
|
ownername: String,
|
||||||
projectref: Array,
|
projectref: Array,
|
||||||
runid: String
|
runid: String,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -80,7 +86,7 @@ export default {
|
||||||
taskYSpace: 20,
|
taskYSpace: 20,
|
||||||
hoverTask: null,
|
hoverTask: null,
|
||||||
|
|
||||||
tasksDisplay: "graph"
|
tasksDisplay: 'graph',
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -93,7 +99,7 @@ export default {
|
||||||
this.fetchAbort = new AbortController();
|
this.fetchAbort = new AbortController();
|
||||||
|
|
||||||
this.fetchRun();
|
this.fetchRun();
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
runTaskLink(task) {
|
runTaskLink(task) {
|
||||||
|
@ -110,16 +116,16 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
parents(task) {
|
parents(task) {
|
||||||
return Object.keys(task.depends).map(key => {
|
return Object.keys(task.depends).map((key) => {
|
||||||
return this.run.tasks[task.depends[key].task_id].name;
|
return this.run.tasks[task.depends[key].task_id].name;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
taskClass(task) {
|
taskClass(task) {
|
||||||
if (task.status == "success") return "success";
|
if (task.status == 'success') return 'success';
|
||||||
if (task.status == "failed") return "failed";
|
if (task.status == 'failed') return 'failed';
|
||||||
if (task.status == "stopped") return "failed";
|
if (task.status == 'stopped') return 'failed';
|
||||||
if (task.status == "running") return "running";
|
if (task.status == 'running') return 'running';
|
||||||
return "unknown";
|
return 'unknown';
|
||||||
},
|
},
|
||||||
async fetchRun() {
|
async fetchRun() {
|
||||||
let { data, error, aborted } = await fetchRun(
|
let { data, error, aborted } = await fetchRun(
|
||||||
|
@ -145,9 +151,8 @@ export default {
|
||||||
let task = tasks[taskID];
|
let task = tasks[taskID];
|
||||||
task.link = this.runTaskLink(task);
|
task.link = this.runTaskLink(task);
|
||||||
task.parents = this.parents(task);
|
task.parents = this.parents(task);
|
||||||
task.waiting_approval = this.run.tasks_waiting_approval.includes(
|
task.waiting_approval =
|
||||||
taskID
|
this.run.tasks_waiting_approval.includes(taskID);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.scheduleFetchRun();
|
this.scheduleFetchRun();
|
||||||
|
@ -157,7 +162,7 @@ export default {
|
||||||
this.fetchRunSchedule = setTimeout(() => {
|
this.fetchRunSchedule = setTimeout(() => {
|
||||||
this.fetchRun();
|
this.fetchRun();
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
this.fetchAbort = new AbortController();
|
this.fetchAbort = new AbortController();
|
||||||
|
@ -168,9 +173,8 @@ export default {
|
||||||
this.fetchAbort.abort();
|
this.fetchAbort.abort();
|
||||||
}
|
}
|
||||||
clearTimeout(this.fetchRunSchedule);
|
clearTimeout(this.fetchRunSchedule);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
|
@ -6,7 +6,9 @@
|
||||||
<div class="flex" v-for="secret in secrets" v-bind:key="secret.id">
|
<div class="flex" v-for="secret in secrets" v-bind:key="secret.id">
|
||||||
<div class="w-2/12">
|
<div class="w-2/12">
|
||||||
<span class="name">{{ secret.name }}</span>
|
<span class="name">{{ secret.name }}</span>
|
||||||
<div v-if="showparentpath" class="text-sm font-light">from {{secret.parent_path}}</div>
|
<div v-if="showparentpath" class="text-sm font-light">
|
||||||
|
from {{ secret.parent_path }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -15,16 +17,12 @@
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: {},
|
||||||
name: "secrets",
|
name: 'secrets',
|
||||||
props: {
|
props: {
|
||||||
secrets: Array,
|
secrets: Array,
|
||||||
showparentpath: Boolean
|
showparentpath: Boolean,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,18 +20,24 @@
|
||||||
<div v-if="step.type == 'run'">
|
<div v-if="step.type == 'run'">
|
||||||
<div class="p-3 rounded-t bg-gray-900 text-white">
|
<div class="p-3 rounded-t bg-gray-900 text-white">
|
||||||
<span>
|
<span>
|
||||||
<span class="w-2/12 bg-gray-700 rounded-l px-3 py-1 text-center font-semibold">Shell</span>
|
<span
|
||||||
|
class="w-2/12 bg-gray-700 rounded-l px-3 py-1 text-center font-semibold"
|
||||||
|
>Shell</span
|
||||||
|
>
|
||||||
<span
|
<span
|
||||||
class="w-2/12 bg-gray-600 rounded-r px-3 py-1 text-center font-semibold mr-2"
|
class="w-2/12 bg-gray-600 rounded-r px-3 py-1 text-center font-semibold mr-2"
|
||||||
>{{ step.shell}}</span>
|
>{{ step.shell }}</span
|
||||||
|
>
|
||||||
</span>
|
</span>
|
||||||
<span v-if="step.exit_status != undefined">
|
<span v-if="step.exit_status != undefined">
|
||||||
<span
|
<span
|
||||||
class="w-2/12 bg-gray-700 rounded-l px-3 py-1 text-center font-semibold"
|
class="w-2/12 bg-gray-700 rounded-l px-3 py-1 text-center font-semibold"
|
||||||
>Exit Status</span>
|
>Exit Status</span
|
||||||
|
>
|
||||||
<span
|
<span
|
||||||
class="w-2/12 bg-gray-600 rounded-r px-3 py-1 text-center font-semibold mr-2"
|
class="w-2/12 bg-gray-600 rounded-r px-3 py-1 text-center font-semibold mr-2"
|
||||||
>{{ step.exit_status}}</span>
|
>{{ step.exit_status }}</span
|
||||||
|
>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -40,22 +46,27 @@
|
||||||
>
|
>
|
||||||
<i
|
<i
|
||||||
class="inline-block mr-1 mdi mdi-arrow-right"
|
class="inline-block mr-1 mdi mdi-arrow-right"
|
||||||
:class="{ 'arrow-down': commandActive, 'arrow-right': !commandActive }"
|
:class="{
|
||||||
|
'arrow-down': commandActive,
|
||||||
|
'arrow-right': !commandActive,
|
||||||
|
}"
|
||||||
></i>
|
></i>
|
||||||
<span>Command</span>
|
<span>Command</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-show="commandActive"
|
v-show="commandActive"
|
||||||
class="p-3 bg-gray-900 text-white overflow-x-auto"
|
class="p-3 bg-gray-900 text-white overflow-x-auto"
|
||||||
:class="{ 'rounded': step.type != 'run' }"
|
:class="{ rounded: step.type != 'run' }"
|
||||||
>
|
>
|
||||||
<pre class="font-mono text-xs">{{ step.command }}</pre>
|
<pre class="font-mono text-xs">{{ step.command }}</pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="step.type == 'run'" class="px-3 py-2 bg-gray-700 text-white">Log</div>
|
<div v-if="step.type == 'run'" class="px-3 py-2 bg-gray-700 text-white">
|
||||||
|
Log
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
class="p-3 rounded-b bg-gray-900 text-white"
|
class="p-3 rounded-b bg-gray-900 text-white"
|
||||||
:class="{ 'rounded': step.type != 'run' }"
|
:class="{ rounded: step.type != 'run' }"
|
||||||
>
|
>
|
||||||
<Log
|
<Log
|
||||||
v-bind:runid="runid"
|
v-bind:runid="runid"
|
||||||
|
@ -72,22 +83,22 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as moment from "moment";
|
import * as moment from 'moment';
|
||||||
import momentDurationFormatSetup from "moment-duration-format";
|
import momentDurationFormatSetup from 'moment-duration-format';
|
||||||
import Log from "@/components/log.vue";
|
import Log from '@/components/log.vue';
|
||||||
|
|
||||||
momentDurationFormatSetup(moment);
|
momentDurationFormatSetup(moment);
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "step",
|
name: 'step',
|
||||||
components: {
|
components: {
|
||||||
Log
|
Log,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
active: false,
|
active: false,
|
||||||
commandActive: true,
|
commandActive: true,
|
||||||
now: moment()
|
now: moment(),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
@ -95,11 +106,11 @@ export default {
|
||||||
taskid: String,
|
taskid: String,
|
||||||
setup: Boolean,
|
setup: Boolean,
|
||||||
stepnum: Number,
|
stepnum: Number,
|
||||||
step: Object
|
step: Object,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
duration() {
|
duration() {
|
||||||
let formatString = "h:mm:ss[s]";
|
let formatString = 'h:mm:ss[s]';
|
||||||
let start = moment(this.step.start_time);
|
let start = moment(this.step.start_time);
|
||||||
let end = moment(this.step.end_time);
|
let end = moment(this.step.end_time);
|
||||||
|
|
||||||
|
@ -112,12 +123,12 @@ export default {
|
||||||
return moment.duration(end.diff(start)).format(formatString);
|
return moment.duration(end.diff(start)).format(formatString);
|
||||||
},
|
},
|
||||||
stepClass() {
|
stepClass() {
|
||||||
if (this.step.phase == "success") return "success";
|
if (this.step.phase == 'success') return 'success';
|
||||||
if (this.step.phase == "failed") return "failed";
|
if (this.step.phase == 'failed') return 'failed';
|
||||||
if (this.step.phase == "stopped") return "failed";
|
if (this.step.phase == 'stopped') return 'failed';
|
||||||
if (this.step.phase == "running") return "running";
|
if (this.step.phase == 'running') return 'running';
|
||||||
return "unknown";
|
return 'unknown';
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
toggle() {
|
toggle() {
|
||||||
|
@ -125,13 +136,13 @@ export default {
|
||||||
},
|
},
|
||||||
toggleCommand() {
|
toggleCommand() {
|
||||||
this.commandActive = !this.commandActive;
|
this.commandActive = !this.commandActive;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
window.setInterval(() => {
|
window.setInterval(() => {
|
||||||
this.now = moment();
|
this.now = moment();
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="arrow">
|
<div class="arrow">
|
||||||
<svg viewBox="0 0 15 15">
|
<svg viewBox="0 0 15 15">
|
||||||
<path fill="none" stroke="#9d9d9d" d="M4.32.5l6.247 6.942L4.32 14.5"></path>
|
<path
|
||||||
|
fill="none"
|
||||||
|
stroke="#9d9d9d"
|
||||||
|
d="M4.32.5l6.247 6.942L4.32 14.5"
|
||||||
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "tabarrow"
|
name: 'tabarrow',
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="task in sortedTasks" v-bind:key="task.id">
|
<li v-for="task in sortedTasks" v-bind:key="task.id">
|
||||||
<div class="mb-2 border-l-5 rounded-l" :class="taskClass(task)">
|
<div class="mb-2 border-l-5 rounded-l" :class="taskClass(task)">
|
||||||
<div class="px-4 py-4 flex justify-between items-center border border-l-0 rounded-r">
|
<div
|
||||||
|
class="px-4 py-4 flex justify-between items-center border border-l-0 rounded-r"
|
||||||
|
>
|
||||||
<router-link class="w-1/3 font-bold" tag="a" :to="task.link">
|
<router-link class="w-1/3 font-bold" tag="a" :to="task.link">
|
||||||
<span class="w-1/3 font-bold">{{ task.name }}</span>
|
<span class="w-1/3 font-bold">{{ task.name }}</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
@ -10,16 +12,21 @@
|
||||||
<span
|
<span
|
||||||
v-if="task.waiting_approval"
|
v-if="task.waiting_approval"
|
||||||
class="w-2/12 bg-gray-200 rounded-full px-3 py-1 text-sm text-center font-semibold mr-2"
|
class="w-2/12 bg-gray-200 rounded-full px-3 py-1 text-sm text-center font-semibold mr-2"
|
||||||
>Waiting Approval</span>
|
>Waiting Approval</span
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-1/4">
|
<div class="w-1/4">
|
||||||
<span class="block text-xs" v-if="task.parents.length > 0">depends on: </span>
|
<span class="block text-xs" v-if="task.parents.length > 0"
|
||||||
|
>depends on: </span
|
||||||
|
>
|
||||||
<ul>
|
<ul>
|
||||||
<li
|
<li
|
||||||
class="font-thin text-xs text-gray-600"
|
class="font-thin text-xs text-gray-600"
|
||||||
v-for="dep in task.parents"
|
v-for="dep in task.parents"
|
||||||
v-bind:key="dep"
|
v-bind:key="dep"
|
||||||
>{{dep}}</li>
|
>
|
||||||
|
{{ dep }}
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<span class="w-16 text-right">{{ task.duration }}</span>
|
<span class="w-16 text-right">{{ task.duration }}</span>
|
||||||
|
@ -30,21 +37,21 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as moment from "moment";
|
import * as moment from 'moment';
|
||||||
import momentDurationFormatSetup from "moment-duration-format";
|
import momentDurationFormatSetup from 'moment-duration-format';
|
||||||
|
|
||||||
momentDurationFormatSetup(moment);
|
momentDurationFormatSetup(moment);
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "tasks",
|
name: 'tasks',
|
||||||
components: {},
|
components: {},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
now: moment()
|
now: moment(),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
tasks: Object
|
tasks: Object,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
sortedTasks() {
|
sortedTasks() {
|
||||||
|
@ -59,18 +66,18 @@ export default {
|
||||||
? -1
|
? -1
|
||||||
: 0
|
: 0
|
||||||
)
|
)
|
||||||
.map(k => tasks[k]);
|
.map((k) => tasks[k]);
|
||||||
|
|
||||||
for (let task of sortedTasks) {
|
for (let task of sortedTasks) {
|
||||||
task.duration = this.duration(task);
|
task.duration = this.duration(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sortedTasks;
|
return sortedTasks;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
duration(task) {
|
duration(task) {
|
||||||
let formatString = "h:mm:ss[s]";
|
let formatString = 'h:mm:ss[s]';
|
||||||
let start = moment(task.start_time);
|
let start = moment(task.start_time);
|
||||||
let end = moment(task.end_time);
|
let end = moment(task.end_time);
|
||||||
|
|
||||||
|
@ -83,18 +90,18 @@ export default {
|
||||||
return moment.duration(end.diff(start)).format(formatString);
|
return moment.duration(end.diff(start)).format(formatString);
|
||||||
},
|
},
|
||||||
taskClass(task) {
|
taskClass(task) {
|
||||||
if (task.status == "success") return "success";
|
if (task.status == 'success') return 'success';
|
||||||
if (task.status == "failed") return "failed";
|
if (task.status == 'failed') return 'failed';
|
||||||
if (task.status == "stopped") return "failed";
|
if (task.status == 'stopped') return 'failed';
|
||||||
if (task.status == "running") return "running";
|
if (task.status == 'running') return 'running';
|
||||||
if (task.status == "skipped") return "skipped";
|
if (task.status == 'skipped') return 'skipped';
|
||||||
return "unknown";
|
return 'unknown';
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
window.setInterval(() => {
|
window.setInterval(() => {
|
||||||
this.now = moment();
|
this.now = moment();
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
|
@ -64,13 +64,13 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as moment from "moment";
|
import * as moment from 'moment';
|
||||||
import momentDurationFormatSetup from "moment-duration-format";
|
import momentDurationFormatSetup from 'moment-duration-format';
|
||||||
|
|
||||||
momentDurationFormatSetup(moment);
|
momentDurationFormatSetup(moment);
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "tasksgraph",
|
name: 'tasksgraph',
|
||||||
components: {},
|
components: {},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -85,11 +85,11 @@ export default {
|
||||||
taskYSpace: 20,
|
taskYSpace: 20,
|
||||||
hoverTask: null,
|
hoverTask: null,
|
||||||
|
|
||||||
height: "400px"
|
height: '400px',
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
tasks: Object
|
tasks: Object,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
segments: function () {
|
segments: function () {
|
||||||
|
@ -107,7 +107,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(sgotti) set different colors to edges based on source task status???
|
// TODO(sgotti) set different colors to edges based on source task status???
|
||||||
let stroke = "text-dark";
|
let stroke = 'text-dark';
|
||||||
segments.push({
|
segments.push({
|
||||||
edge: edge,
|
edge: edge,
|
||||||
x1: edge.edgePoints[i].x,
|
x1: edge.edgePoints[i].x,
|
||||||
|
@ -115,7 +115,7 @@ export default {
|
||||||
x2: edge.edgePoints[i + 1].x,
|
x2: edge.edgePoints[i + 1].x,
|
||||||
y2: edge.edgePoints[i + 1].y,
|
y2: edge.edgePoints[i + 1].y,
|
||||||
strokeWidth: strokeWidth,
|
strokeWidth: strokeWidth,
|
||||||
stroke: stroke
|
stroke: stroke,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,16 +130,16 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.graphTasks;
|
return this.graphTasks;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
tasks: function (tasks) {
|
tasks: function (tasks) {
|
||||||
this.update(tasks);
|
this.update(tasks);
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
duration(task) {
|
duration(task) {
|
||||||
let formatString = "h:mm:ss[s]";
|
let formatString = 'h:mm:ss[s]';
|
||||||
let start = moment(task.start_time);
|
let start = moment(task.start_time);
|
||||||
let end = moment(task.end_time);
|
let end = moment(task.end_time);
|
||||||
|
|
||||||
|
@ -152,12 +152,12 @@ export default {
|
||||||
return moment.duration(end.diff(start)).format(formatString);
|
return moment.duration(end.diff(start)).format(formatString);
|
||||||
},
|
},
|
||||||
taskClass(task) {
|
taskClass(task) {
|
||||||
if (task.status == "success") return "success";
|
if (task.status == 'success') return 'success';
|
||||||
if (task.status == "failed") return "failed";
|
if (task.status == 'failed') return 'failed';
|
||||||
if (task.status == "stopped") return "failed";
|
if (task.status == 'stopped') return 'failed';
|
||||||
if (task.status == "running") return "running";
|
if (task.status == 'running') return 'running';
|
||||||
if (task.status == "skipped") return "skipped";
|
if (task.status == 'skipped') return 'skipped';
|
||||||
return "unknown";
|
return 'unknown';
|
||||||
},
|
},
|
||||||
update(tasks) {
|
update(tasks) {
|
||||||
// sort tasks by level
|
// sort tasks by level
|
||||||
|
@ -169,7 +169,7 @@ export default {
|
||||||
? -1
|
? -1
|
||||||
: 0
|
: 0
|
||||||
)
|
)
|
||||||
.map(k => tasks[k]);
|
.map((k) => tasks[k]);
|
||||||
|
|
||||||
this.graphTasks = graphTasks;
|
this.graphTasks = graphTasks;
|
||||||
|
|
||||||
|
@ -344,7 +344,7 @@ export default {
|
||||||
sourceTask: pTask,
|
sourceTask: pTask,
|
||||||
targetTask: curTask,
|
targetTask: curTask,
|
||||||
source: { level: pTask.level, row: pTask.row },
|
source: { level: pTask.level, row: pTask.row },
|
||||||
target: { level: curTask.level, row: curTask.row }
|
target: { level: curTask.level, row: curTask.row },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -362,30 +362,30 @@ export default {
|
||||||
|
|
||||||
edge.edgePoints.push({
|
edge.edgePoints.push({
|
||||||
x: (taskWidth + taskXSpace) * edge.source.level + taskWidth,
|
x: (taskWidth + taskXSpace) * edge.source.level + taskWidth,
|
||||||
y: (taskHeight + taskYSpace) * edge.source.row + taskHeight / 2
|
y: (taskHeight + taskYSpace) * edge.source.row + taskHeight / 2,
|
||||||
});
|
});
|
||||||
edge.edgePoints.push({
|
edge.edgePoints.push({
|
||||||
x: (taskWidth + taskXSpace) * edge.target.level - taskXSpace / 2,
|
x: (taskWidth + taskXSpace) * edge.target.level - taskXSpace / 2,
|
||||||
y: (taskHeight + taskYSpace) * edge.source.row + taskHeight / 2
|
y: (taskHeight + taskYSpace) * edge.source.row + taskHeight / 2,
|
||||||
});
|
});
|
||||||
edge.edgePoints.push({
|
edge.edgePoints.push({
|
||||||
x: (taskWidth + taskXSpace) * edge.target.level - taskXSpace / 2,
|
x: (taskWidth + taskXSpace) * edge.target.level - taskXSpace / 2,
|
||||||
y: (taskHeight + taskYSpace) * edge.target.row + taskHeight / 2
|
y: (taskHeight + taskYSpace) * edge.target.row + taskHeight / 2,
|
||||||
});
|
});
|
||||||
edge.edgePoints.push({
|
edge.edgePoints.push({
|
||||||
x: (taskWidth + taskXSpace) * edge.target.level,
|
x: (taskWidth + taskXSpace) * edge.target.level,
|
||||||
y: (taskHeight + taskYSpace) * edge.target.row + taskHeight / 2
|
y: (taskHeight + taskYSpace) * edge.target.row + taskHeight / 2,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let width = (maxlevel + 1) * (this.taskWidth + this.taskXSpace);
|
let width = (maxlevel + 1) * (this.taskWidth + this.taskXSpace);
|
||||||
this.width = width + "px";
|
this.width = width + 'px';
|
||||||
|
|
||||||
let height =
|
let height =
|
||||||
(levelsMaxRow(graphTasks, -1) + 1) *
|
(levelsMaxRow(graphTasks, -1) + 1) *
|
||||||
(this.taskHeight + this.taskYSpace);
|
(this.taskHeight + this.taskYSpace);
|
||||||
this.height = height + "px";
|
this.height = height + 'px';
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.update(this.tasks);
|
this.update(this.tasks);
|
||||||
|
@ -393,6 +393,6 @@ export default {
|
||||||
window.setInterval(() => {
|
window.setInterval(() => {
|
||||||
this.now = moment();
|
this.now = moment();
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -8,7 +8,12 @@
|
||||||
<div>Error fetching Run: {{ fetchRunError }}</div>
|
<div>Error fetching Run: {{ fetchRunError }}</div>
|
||||||
<div>Error fetching Task: {{ fetchTaskError }}</div>
|
<div>Error fetching Task: {{ fetchTaskError }}</div>
|
||||||
</div>
|
</div>
|
||||||
<rundetail :run="run" :ownertype="ownertype" :ownername="ownername" :projectref="projectref" />
|
<rundetail
|
||||||
|
:run="run"
|
||||||
|
:ownertype="ownertype"
|
||||||
|
:ownername="ownername"
|
||||||
|
:projectref="projectref"
|
||||||
|
/>
|
||||||
<div v-if="task != null">
|
<div v-if="task != null">
|
||||||
<div class="mt-8 mb-4 flex justify-between items-center">
|
<div class="mt-8 mb-4 flex justify-between items-center">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
|
@ -17,13 +22,16 @@
|
||||||
<span
|
<span
|
||||||
class="mr-3 rounded px-2 py-1 text-xs"
|
class="mr-3 rounded px-2 py-1 text-xs"
|
||||||
:class="taskClass(task)"
|
:class="taskClass(task)"
|
||||||
>{{ task.status | capitalize }}</span>
|
>{{ task.status | capitalize }}</span
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
v-if="task.waiting_approval"
|
v-if="task.waiting_approval"
|
||||||
class="btn btn-blue"
|
class="btn btn-blue"
|
||||||
@click="approveTask(run.id, task.id)"
|
@click="approveTask(run.id, task.id)"
|
||||||
>Approve</button>
|
>
|
||||||
|
Approve
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<step
|
<step
|
||||||
v-bind:runid="runid"
|
v-bind:runid="runid"
|
||||||
|
@ -44,23 +52,23 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { fetchRun, fetchTask, approveTask } from "@/util/data.js";
|
import { fetchRun, fetchTask, approveTask } from '@/util/data.js';
|
||||||
|
|
||||||
import step from "@/components/step.vue";
|
import step from '@/components/step.vue';
|
||||||
import rundetail from "@/components/rundetail.vue";
|
import rundetail from '@/components/rundetail.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
step,
|
step,
|
||||||
rundetail
|
rundetail,
|
||||||
},
|
},
|
||||||
name: "tasksummary",
|
name: 'tasksummary',
|
||||||
props: {
|
props: {
|
||||||
ownertype: String,
|
ownertype: String,
|
||||||
ownername: String,
|
ownername: String,
|
||||||
projectref: Array,
|
projectref: Array,
|
||||||
runid: String,
|
runid: String,
|
||||||
taskid: String
|
taskid: String,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -70,7 +78,7 @@ export default {
|
||||||
fetchTaskError: null,
|
fetchTaskError: null,
|
||||||
|
|
||||||
run: null,
|
run: null,
|
||||||
task: null
|
task: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -85,16 +93,16 @@ export default {
|
||||||
|
|
||||||
this.fetchRun();
|
this.fetchRun();
|
||||||
this.fetchTask();
|
this.fetchTask();
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
taskClass(task) {
|
taskClass(task) {
|
||||||
if (task.status == "success") return "is-success";
|
if (task.status == 'success') return 'is-success';
|
||||||
if (task.status == "failed") return "is-failed";
|
if (task.status == 'failed') return 'is-failed';
|
||||||
if (task.status == "stopped") return "is-failed";
|
if (task.status == 'stopped') return 'is-failed';
|
||||||
if (task.status == "running") return "is-running";
|
if (task.status == 'running') return 'is-running';
|
||||||
if (task.status == "skipped") return "is-skipped";
|
if (task.status == 'skipped') return 'is-skipped';
|
||||||
return "unknown";
|
return 'unknown';
|
||||||
},
|
},
|
||||||
async fetchRun() {
|
async fetchRun() {
|
||||||
let { data, error, aborted } = await fetchRun(
|
let { data, error, aborted } = await fetchRun(
|
||||||
|
@ -143,7 +151,7 @@ export default {
|
||||||
this.fetchTask();
|
this.fetchTask();
|
||||||
}, 2000);
|
}, 2000);
|
||||||
},
|
},
|
||||||
approveTask: approveTask
|
approveTask: approveTask,
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
this.fetchAbort = new AbortController();
|
this.fetchAbort = new AbortController();
|
||||||
|
@ -157,9 +165,8 @@ export default {
|
||||||
}
|
}
|
||||||
clearTimeout(this.fetchRunSchedule);
|
clearTimeout(this.fetchRunSchedule);
|
||||||
clearTimeout(this.fetchTaskSchedule);
|
clearTimeout(this.fetchTaskSchedule);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
|
@ -7,7 +7,10 @@
|
||||||
class="mb-4 bg-red-100 border-l-4 border-red-500 text-red-700 p-4 rounded"
|
class="mb-4 bg-red-100 border-l-4 border-red-500 text-red-700 p-4 rounded"
|
||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
<p>Removing a Linked Account will also block all the projects that uses this Linked Account to access their remote repository</p>
|
<p>
|
||||||
|
Removing a Linked Account will also block all the projects that uses
|
||||||
|
this Linked Account to access their remote repository
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<ul v-if="user.linked_accounts">
|
<ul v-if="user.linked_accounts">
|
||||||
<li
|
<li
|
||||||
|
@ -17,9 +20,13 @@
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<span class="font-bold">{{ la.remote_user_name }}</span>
|
<span class="font-bold">{{ la.remote_user_name }}</span>
|
||||||
<span class="ml-1">(on remote source {{laRemoteSourceName(la)}})</span>
|
<span class="ml-1"
|
||||||
|
>(on remote source {{ laRemoteSourceName(la) }})</span
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-red" @click="deleteLinkedAccount(la)">Delete</button>
|
<button class="btn btn-red" @click="deleteLinkedAccount(la)">
|
||||||
|
Delete
|
||||||
|
</button>
|
||||||
</li>
|
</li>
|
||||||
<div
|
<div
|
||||||
v-if="deleteLinkedAccountError"
|
v-if="deleteLinkedAccountError"
|
||||||
|
@ -40,9 +47,13 @@
|
||||||
class="block appearance-none w-full bg-white border border-gray-400 hover:border-gray-500 px-4 py-2 pr-8 rounded shadow leading-tight focus:outline-none focus:shadow-outline"
|
class="block appearance-none w-full bg-white border border-gray-400 hover:border-gray-500 px-4 py-2 pr-8 rounded shadow leading-tight focus:outline-none focus:shadow-outline"
|
||||||
v-model="selectedRemoteSourceName"
|
v-model="selectedRemoteSourceName"
|
||||||
>
|
>
|
||||||
<option v-for="rs in remotesources" v-bind:key="rs.id">{{ rs.name }}</option>
|
<option v-for="rs in remotesources" v-bind:key="rs.id">
|
||||||
|
{{ rs.name }}
|
||||||
|
</option>
|
||||||
</select>
|
</select>
|
||||||
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2">
|
<div
|
||||||
|
class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2"
|
||||||
|
>
|
||||||
<svg
|
<svg
|
||||||
class="fill-current h-4 w-4"
|
class="fill-current h-4 w-4"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
@ -56,7 +67,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button class="ml-3 btn btn-blue" @click="addLinkedAccount()">Add Linked Account</button>
|
<button class="ml-3 btn btn-blue" @click="addLinkedAccount()">
|
||||||
|
Add Linked Account
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -70,7 +83,9 @@
|
||||||
v-bind:key="token"
|
v-bind:key="token"
|
||||||
>
|
>
|
||||||
<span class="font-bold">{{ token }}</span>
|
<span class="font-bold">{{ token }}</span>
|
||||||
<button class="btn btn-red" @click="deleteUserToken(token)">Delete</button>
|
<button class="btn btn-red" @click="deleteUserToken(token)">
|
||||||
|
Delete
|
||||||
|
</button>
|
||||||
</li>
|
</li>
|
||||||
<div
|
<div
|
||||||
v-if="deleteUserTokenError"
|
v-if="deleteUserTokenError"
|
||||||
|
@ -102,7 +117,9 @@
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p class="font-bold">User token created. Copy it now since it won't be showed again</p>
|
<p class="font-bold">
|
||||||
|
User token created. Copy it now since it won't be showed again
|
||||||
|
</p>
|
||||||
<p class="text-sm">{{ token }}</p>
|
<p class="text-sm">{{ token }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -130,8 +147,10 @@
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Token name"
|
placeholder="Token name"
|
||||||
v-model="newtokenname"
|
v-model="newtokenname"
|
||||||
>
|
/>
|
||||||
<button class="ml-3 btn btn-blue" @click="createUserToken()">Create Token</button>
|
<button class="ml-3 btn btn-blue" @click="createUserToken()">
|
||||||
|
Create Token
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="createUserTokenError"
|
v-if="createUserTokenError"
|
||||||
|
@ -151,14 +170,14 @@ import {
|
||||||
fetchRemoteSources,
|
fetchRemoteSources,
|
||||||
createUserToken,
|
createUserToken,
|
||||||
deleteUserToken,
|
deleteUserToken,
|
||||||
deleteLinkedAccount
|
deleteLinkedAccount,
|
||||||
} from "@/util/data.js";
|
} from '@/util/data.js';
|
||||||
|
|
||||||
import { userAddLinkedAccountLink } from "@/util/link.js";
|
import { userAddLinkedAccountLink } from '@/util/link.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: {},
|
||||||
name: "usersettings",
|
name: 'usersettings',
|
||||||
props: {},
|
props: {},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -169,7 +188,7 @@ export default {
|
||||||
remotesources: [],
|
remotesources: [],
|
||||||
token: null,
|
token: null,
|
||||||
newtokenname: null,
|
newtokenname: null,
|
||||||
selectedRemoteSourceName: null
|
selectedRemoteSourceName: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -181,7 +200,7 @@ export default {
|
||||||
async fetchCurrentUser() {
|
async fetchCurrentUser() {
|
||||||
let { data, error } = await fetchCurrentUser();
|
let { data, error } = await fetchCurrentUser();
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.user = data;
|
this.user = data;
|
||||||
|
@ -189,7 +208,7 @@ export default {
|
||||||
async fetchRemoteSources() {
|
async fetchRemoteSources() {
|
||||||
let { data, error } = await fetchRemoteSources();
|
let { data, error } = await fetchRemoteSources();
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.remotesources = data;
|
this.remotesources = data;
|
||||||
|
@ -249,15 +268,13 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.fetchCurrentUser();
|
this.fetchCurrentUser();
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
this.fetchCurrentUser();
|
this.fetchCurrentUser();
|
||||||
this.fetchRemoteSources();
|
this.fetchRemoteSources();
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
|
@ -19,16 +19,17 @@
|
||||||
<div class="flex" v-for="variable in variables" v-bind:key="variable.id">
|
<div class="flex" v-for="variable in variables" v-bind:key="variable.id">
|
||||||
<div class="w-2/12">
|
<div class="w-2/12">
|
||||||
<span class="name">{{ variable.name }}</span>
|
<span class="name">{{ variable.name }}</span>
|
||||||
<div v-if="showparentpath" class="text-sm font-light">from {{variable.parent_path}}</div>
|
<div v-if="showparentpath" class="text-sm font-light">
|
||||||
|
from {{ variable.parent_path }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-10/12">
|
<div class="w-10/12">
|
||||||
<div class="flex" v-for="val in variable.values" v-bind:key="val.id">
|
<div class="flex" v-for="val in variable.values" v-bind:key="val.id">
|
||||||
<div class="w-2/12">
|
<div class="w-2/12">
|
||||||
<span>{{ val.secret_name }}</span>
|
<span>{{ val.secret_name }}</span>
|
||||||
<div
|
<div v-if="val.matching_secret_parent_path" class="text-sm">
|
||||||
v-if="val.matching_secret_parent_path"
|
using secret from {{ val.matching_secret_parent_path }}
|
||||||
class="text-sm"
|
</div>
|
||||||
>using secret from {{val.matching_secret_parent_path}}</div>
|
|
||||||
<div v-else class="text-sm text-red-600">no matching secret</div>
|
<div v-else class="text-sm text-red-600">no matching secret</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-2/12">
|
<div class="w-2/12">
|
||||||
|
@ -43,12 +44,18 @@
|
||||||
<span>{{ type }}</span>
|
<span>{{ type }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-1/3">
|
<div class="w-1/3">
|
||||||
<div v-for="include in val.when[type].include" v-bind:key="include.match">
|
<div
|
||||||
|
v-for="include in val.when[type].include"
|
||||||
|
v-bind:key="include.match"
|
||||||
|
>
|
||||||
<div>{{ include.match }}</div>
|
<div>{{ include.match }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-1/3">
|
<div class="w-1/3">
|
||||||
<div v-for="exclude in val.when[type].exclude" v-bind:key="exclude.match">
|
<div
|
||||||
|
v-for="exclude in val.when[type].exclude"
|
||||||
|
v-bind:key="exclude.match"
|
||||||
|
>
|
||||||
<div>{{ exclude.match }}</div>
|
<div>{{ exclude.match }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -66,15 +73,12 @@
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: {},
|
||||||
name: "vars",
|
name: 'vars',
|
||||||
props: {
|
props: {
|
||||||
variables: Array,
|
variables: Array,
|
||||||
showparentpath: Boolean
|
showparentpath: Boolean,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
@tailwind base;
|
@tailwind base;
|
||||||
@tailwind components;
|
@tailwind components;
|
||||||
|
|
||||||
@import "@/css/_ansi.scss";
|
@import '@/css/_ansi.scss';
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
@apply font-bold py-2 px-4 rounded;
|
@apply font-bold py-2 px-4 rounded;
|
||||||
|
@ -119,7 +119,7 @@
|
||||||
border-radius: 290486px;
|
border-radius: 290486px;
|
||||||
border-right-color: transparent;
|
border-right-color: transparent;
|
||||||
border-top-color: transparent;
|
border-top-color: transparent;
|
||||||
content: "";
|
content: '';
|
||||||
display: block;
|
display: block;
|
||||||
width: 1em;
|
width: 1em;
|
||||||
height: 1em;
|
height: 1em;
|
||||||
|
|
24
src/main.js
24
src/main.js
|
@ -1,11 +1,11 @@
|
||||||
import "@/css/tailwind.scss";
|
import '@/css/tailwind.scss';
|
||||||
import { getUser } from "@/util/auth";
|
import { getUser } from '@/util/auth';
|
||||||
import "@mdi/font/css/materialdesignicons.css";
|
import '@mdi/font/css/materialdesignicons.css';
|
||||||
import Vue from "vue";
|
import Vue from 'vue';
|
||||||
import Vue2Filters from "vue2-filters";
|
import Vue2Filters from 'vue2-filters';
|
||||||
import App from "./App.vue";
|
import App from './App.vue';
|
||||||
import router from "./router";
|
import router from './router';
|
||||||
import store from "./store";
|
import store from './store';
|
||||||
|
|
||||||
Vue.use(Vue2Filters);
|
Vue.use(Vue2Filters);
|
||||||
|
|
||||||
|
@ -16,9 +16,9 @@ new Vue({
|
||||||
created: function () {
|
created: function () {
|
||||||
let user = getUser();
|
let user = getUser();
|
||||||
if (user) {
|
if (user) {
|
||||||
store.dispatch("setUser", user);
|
store.dispatch('setUser', user);
|
||||||
}
|
}
|
||||||
store.dispatch("setRegisterUser", null);
|
store.dispatch('setRegisterUser', null);
|
||||||
},
|
},
|
||||||
render: h => h(App)
|
render: (h) => h(App),
|
||||||
}).$mount("#app");
|
}).$mount('#app');
|
||||||
|
|
557
src/router.js
557
src/router.js
|
@ -1,249 +1,348 @@
|
||||||
import Vue from "vue";
|
import Vue from 'vue';
|
||||||
import VueRouter from "vue-router";
|
import VueRouter from 'vue-router';
|
||||||
import Home from "./views/Home.vue";
|
import Home from './views/Home.vue';
|
||||||
import User from "./views/User.vue";
|
import User from './views/User.vue';
|
||||||
import Org from "./views/Org.vue";
|
import Org from './views/Org.vue';
|
||||||
import Project from "./views/Project.vue";
|
import Project from './views/Project.vue';
|
||||||
import ProjectGroup from "./views/ProjectGroup.vue";
|
import ProjectGroup from './views/ProjectGroup.vue';
|
||||||
import AddLinkedAccount from "./views/AddLinkedAccount.vue";
|
import AddLinkedAccount from './views/AddLinkedAccount.vue';
|
||||||
import usersettings from "./components/usersettings.vue";
|
import usersettings from './components/usersettings.vue';
|
||||||
import projects from "./components/projects.vue";
|
import projects from './components/projects.vue';
|
||||||
import projectsettings from "./components/projectsettings.vue";
|
import projectsettings from './components/projectsettings.vue';
|
||||||
import projectgroupsettings from "./components/projectgroupsettings.vue";
|
import projectgroupsettings from './components/projectgroupsettings.vue';
|
||||||
import createproject from "./components/createproject.vue";
|
import createproject from './components/createproject.vue';
|
||||||
import createprojectgroup from "./components/createprojectgroup.vue";
|
import createprojectgroup from './components/createprojectgroup.vue';
|
||||||
import createorganization from "./components/createorganization.vue";
|
import createorganization from './components/createorganization.vue';
|
||||||
import orgmembers from "./components/orgmembers.vue";
|
import orgmembers from './components/orgmembers.vue';
|
||||||
import runs from "./components/runs.vue";
|
import runs from './components/runs.vue';
|
||||||
import runsummary from "./components/runsummary.vue";
|
import runsummary from './components/runsummary.vue';
|
||||||
import tasksummary from "./components/tasksummary.vue";
|
import tasksummary from './components/tasksummary.vue';
|
||||||
import Oauth2 from "./views/Oauth2.vue";
|
import Oauth2 from './views/Oauth2.vue';
|
||||||
import Register from "./views/Register.vue";
|
import Register from './views/Register.vue';
|
||||||
import Login from "./views/Login.vue";
|
import Login from './views/Login.vue';
|
||||||
import Logout from "./views/Logout.vue";
|
import Logout from './views/Logout.vue';
|
||||||
import CreateSource from "./views/CreateSource.vue";
|
import CreateSource from './views/CreateSource.vue';
|
||||||
|
|
||||||
import { parseRef, projectRunLink } from "@/util/link.js";
|
import { parseRef, projectRunLink } from '@/util/link.js';
|
||||||
import { fetchProject } from "@/util/data.js";
|
import { fetchProject } from '@/util/data.js';
|
||||||
|
|
||||||
import store from "./store";
|
import store from './store';
|
||||||
|
|
||||||
Vue.use(VueRouter);
|
Vue.use(VueRouter);
|
||||||
|
|
||||||
const router = new VueRouter({
|
const router = new VueRouter({
|
||||||
mode: "history",
|
mode: 'history',
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
path: "/register",
|
path: '/register',
|
||||||
name: "register",
|
name: 'register',
|
||||||
component: Register,
|
component: Register,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/newsource",
|
path: '/newsource',
|
||||||
name: "newsource",
|
name: 'newsource',
|
||||||
component: CreateSource,
|
component: CreateSource,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/login",
|
path: '/login',
|
||||||
name: "login",
|
name: 'login',
|
||||||
component: Login
|
component: Login,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/logout",
|
path: '/logout',
|
||||||
name: "logout",
|
name: 'logout',
|
||||||
component: Logout
|
component: Logout,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/oauth2/callback",
|
path: '/oauth2/callback',
|
||||||
name: "oauth2callback",
|
name: 'oauth2callback',
|
||||||
component: Oauth2
|
component: Oauth2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/",
|
path: '/',
|
||||||
name: "home",
|
name: 'home',
|
||||||
component: Home
|
component: Home,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/neworganization",
|
path: '/neworganization',
|
||||||
component: createorganization,
|
component: createorganization,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/user/:username",
|
path: '/user/:username',
|
||||||
component: User,
|
component: User,
|
||||||
props: (route) => ({ username: route.params.username }),
|
props: (route) => ({ username: route.params.username }),
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: "",
|
path: '',
|
||||||
name: "user",
|
name: 'user',
|
||||||
component: projects,
|
component: projects,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "projects",
|
path: 'projects',
|
||||||
name: "user projects",
|
name: 'user projects',
|
||||||
component: projects,
|
component: projects,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "runs",
|
path: 'runs',
|
||||||
name: "user direct runs",
|
name: 'user direct runs',
|
||||||
component: runs,
|
component: runs,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "runs/:runid",
|
path: 'runs/:runid',
|
||||||
name: "user direct run",
|
name: 'user direct run',
|
||||||
component: runsummary,
|
component: runsummary,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, runid: route.params.runid })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
runid: route.params.runid,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "runs/:runid/tasks/:taskid",
|
path: 'runs/:runid/tasks/:taskid',
|
||||||
name: "user direct run task",
|
name: 'user direct run task',
|
||||||
component: tasksummary,
|
component: tasksummary,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, runid: route.params.runid, taskid: route.params.taskid })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
runid: route.params.runid,
|
||||||
|
taskid: route.params.taskid,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "settings",
|
path: 'settings',
|
||||||
name: "user settings",
|
name: 'user settings',
|
||||||
component: usersettings,
|
component: usersettings,
|
||||||
props: (route) => ({ username: route.params.username }),
|
props: (route) => ({ username: route.params.username }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "linkedaccounts/add/:remotesource",
|
path: 'linkedaccounts/add/:remotesource',
|
||||||
name: "user add linked account",
|
name: 'user add linked account',
|
||||||
component: AddLinkedAccount,
|
component: AddLinkedAccount,
|
||||||
props: (route) => ({ username: route.params.username, remoteSourceName: route.params.remotesource })
|
props: (route) => ({
|
||||||
|
username: route.params.username,
|
||||||
|
remoteSourceName: route.params.remotesource,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "createprojectgroup",
|
path: 'createprojectgroup',
|
||||||
name: "user create project group",
|
name: 'user create project group',
|
||||||
component: createprojectgroup,
|
component: createprojectgroup,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "createproject",
|
path: 'createproject',
|
||||||
name: "user create project",
|
name: 'user create project',
|
||||||
component: createproject,
|
component: createproject,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/user/:username/projects/:projectref(.*\\.proj)",
|
path: '/user/:username/projects/:projectref(.*\\.proj)',
|
||||||
component: Project,
|
component: Project,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectref: parseRef(route.params.projectref) }),
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
}),
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: "",
|
path: '',
|
||||||
name: "user project",
|
name: 'user project',
|
||||||
component: runs,
|
component: runs,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectref: parseRef(route.params.projectref) })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "runs",
|
path: 'runs',
|
||||||
name: "user project runs",
|
name: 'user project runs',
|
||||||
component: runs,
|
component: runs,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectref: parseRef(route.params.projectref) })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "branches",
|
path: 'branches',
|
||||||
name: "user project branches runs",
|
name: 'user project branches runs',
|
||||||
component: runs,
|
component: runs,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectref: parseRef(route.params.projectref), query: "branches" })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
query: 'branches',
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "tags",
|
path: 'tags',
|
||||||
name: "user project tags runs",
|
name: 'user project tags runs',
|
||||||
component: runs,
|
component: runs,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectref: parseRef(route.params.projectref), query: "tags" })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
query: 'tags',
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "pullrequests",
|
path: 'pullrequests',
|
||||||
name: "user project pull requests runs",
|
name: 'user project pull requests runs',
|
||||||
component: runs,
|
component: runs,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectref: parseRef(route.params.projectref), query: "pullrequests" })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
query: 'pullrequests',
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "runs/:runid",
|
path: 'runs/:runid',
|
||||||
name: "user project run",
|
name: 'user project run',
|
||||||
component: runsummary,
|
component: runsummary,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectref: parseRef(route.params.projectref), runid: route.params.runid })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
runid: route.params.runid,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "runs/:runid/tasks/:taskid",
|
path: 'runs/:runid/tasks/:taskid',
|
||||||
name: "user project run task",
|
name: 'user project run task',
|
||||||
component: tasksummary,
|
component: tasksummary,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectref: parseRef(route.params.projectref), runid: route.params.runid, taskid: route.params.taskid })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
runid: route.params.runid,
|
||||||
|
taskid: route.params.taskid,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "settings",
|
path: 'settings',
|
||||||
name: "user project settings",
|
name: 'user project settings',
|
||||||
component: projectsettings,
|
component: projectsettings,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectref: parseRef(route.params.projectref) })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
path: "/user/:username/projectgroups/:projectgroupref(.*\\.proj)",
|
path: '/user/:username/projectgroups/:projectgroupref(.*\\.proj)',
|
||||||
component: ProjectGroup,
|
component: ProjectGroup,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectgroupref: parseRef(route.params.projectgroupref) }),
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectgroupref: parseRef(route.params.projectgroupref),
|
||||||
|
}),
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: "",
|
path: '',
|
||||||
name: "user project group",
|
name: 'user project group',
|
||||||
component: projects,
|
component: projects,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectgroupref: parseRef(route.params.projectgroupref) }),
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectgroupref: parseRef(route.params.projectgroupref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "projects",
|
path: 'projects',
|
||||||
name: "user project group projects",
|
name: 'user project group projects',
|
||||||
component: projects,
|
component: projects,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectgroupref: parseRef(route.params.projectgroupref) })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectgroupref: parseRef(route.params.projectgroupref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "settings",
|
path: 'settings',
|
||||||
name: "user project group settings",
|
name: 'user project group settings',
|
||||||
component: projectgroupsettings,
|
component: projectgroupsettings,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectgroupref: parseRef(route.params.projectgroupref) })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectgroupref: parseRef(route.params.projectgroupref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "createprojectgroup",
|
path: 'createprojectgroup',
|
||||||
name: "user project group create project group",
|
name: 'user project group create project group',
|
||||||
component: createprojectgroup,
|
component: createprojectgroup,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectgroupref: parseRef(route.params.projectgroupref) })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectgroupref: parseRef(route.params.projectgroupref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "createproject",
|
path: 'createproject',
|
||||||
name: "user project group create project",
|
name: 'user project group create project',
|
||||||
component: createproject,
|
component: createproject,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectgroupref: parseRef(route.params.projectgroupref) })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectgroupref: parseRef(route.params.projectgroupref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
path: "/org/:orgname",
|
path: '/org/:orgname',
|
||||||
component: Org,
|
component: Org,
|
||||||
props: (route) => ({ orgname: route.params.orgname }),
|
props: (route) => ({ orgname: route.params.orgname }),
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: "",
|
path: '',
|
||||||
name: "org",
|
name: 'org',
|
||||||
component: projects,
|
component: projects,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "projects",
|
path: 'projects',
|
||||||
name: "org projects",
|
name: 'org projects',
|
||||||
component: projects,
|
component: projects,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "members",
|
path: 'members',
|
||||||
name: "org members",
|
name: 'org members',
|
||||||
component: orgmembers,
|
component: orgmembers,
|
||||||
props: (route) => ({ orgname: route.params.orgname })
|
props: (route) => ({ orgname: route.params.orgname }),
|
||||||
},
|
},
|
||||||
/* {
|
/* {
|
||||||
path: "settings",
|
path: "settings",
|
||||||
|
@ -252,141 +351,213 @@ const router = new VueRouter({
|
||||||
props: (route) => ({ username: route.params.username }),
|
props: (route) => ({ username: route.params.username }),
|
||||||
}, */
|
}, */
|
||||||
{
|
{
|
||||||
path: "createprojectgroup",
|
path: 'createprojectgroup',
|
||||||
name: "org create project group",
|
name: 'org create project group',
|
||||||
component: createprojectgroup,
|
component: createprojectgroup,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "createproject",
|
path: 'createproject',
|
||||||
name: "org create project",
|
name: 'org create project',
|
||||||
component: createproject,
|
component: createproject,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
path: "/org/:orgname/projects/:projectref(.*\\.proj)",
|
path: '/org/:orgname/projects/:projectref(.*\\.proj)',
|
||||||
component: Project,
|
component: Project,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectref: parseRef(route.params.projectref) }),
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
}),
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: "",
|
path: '',
|
||||||
name: "org project",
|
name: 'org project',
|
||||||
component: runs,
|
component: runs,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectref: parseRef(route.params.projectref) })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "runs",
|
path: 'runs',
|
||||||
name: "org project runs",
|
name: 'org project runs',
|
||||||
component: runs,
|
component: runs,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectref: parseRef(route.params.projectref) })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "branches",
|
path: 'branches',
|
||||||
name: "org project branches runs",
|
name: 'org project branches runs',
|
||||||
component: runs,
|
component: runs,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectref: parseRef(route.params.projectref), query: "branches" })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
query: 'branches',
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "tags",
|
path: 'tags',
|
||||||
name: "org project tags runs",
|
name: 'org project tags runs',
|
||||||
component: runs,
|
component: runs,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectref: parseRef(route.params.projectref), query: "tags" })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
query: 'tags',
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "pullrequests",
|
path: 'pullrequests',
|
||||||
name: "org project pull requests runs",
|
name: 'org project pull requests runs',
|
||||||
component: runs,
|
component: runs,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectref: parseRef(route.params.projectref), query: "pullrequests" })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
query: 'pullrequests',
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "runs/:runid",
|
path: 'runs/:runid',
|
||||||
name: "org project run",
|
name: 'org project run',
|
||||||
component: runsummary,
|
component: runsummary,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectref: parseRef(route.params.projectref), runid: route.params.runid })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
runid: route.params.runid,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "runs/:runid/tasks/:taskid",
|
path: 'runs/:runid/tasks/:taskid',
|
||||||
name: "org project run task",
|
name: 'org project run task',
|
||||||
component: tasksummary,
|
component: tasksummary,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectref: parseRef(route.params.projectref), runid: route.params.runid, taskid: route.params.taskid })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
runid: route.params.runid,
|
||||||
|
taskid: route.params.taskid,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "settings",
|
path: 'settings',
|
||||||
name: "org project settings",
|
name: 'org project settings',
|
||||||
component: projectsettings,
|
component: projectsettings,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectref: parseRef(route.params.projectref) })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
path: "/org/:orgname/projectgroups/:projectgroupref(.*\\.proj)",
|
path: '/org/:orgname/projectgroups/:projectgroupref(.*\\.proj)',
|
||||||
component: ProjectGroup,
|
component: ProjectGroup,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectgroupref: parseRef(route.params.projectgroupref) }),
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectgroupref: parseRef(route.params.projectgroupref),
|
||||||
|
}),
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: "",
|
path: '',
|
||||||
name: "org project group",
|
name: 'org project group',
|
||||||
component: projects,
|
component: projects,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectgroupref: parseRef(route.params.projectgroupref) }),
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectgroupref: parseRef(route.params.projectgroupref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "projects",
|
path: 'projects',
|
||||||
name: "org project group projects",
|
name: 'org project group projects',
|
||||||
component: projects,
|
component: projects,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectgroupref: parseRef(route.params.projectgroupref) })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectgroupref: parseRef(route.params.projectgroupref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "settings",
|
path: 'settings',
|
||||||
name: "org project group settings",
|
name: 'org project group settings',
|
||||||
component: projectgroupsettings,
|
component: projectgroupsettings,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectgroupref: parseRef(route.params.projectgroupref) })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectgroupref: parseRef(route.params.projectgroupref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "createprojectgroup",
|
path: 'createprojectgroup',
|
||||||
name: "org project group create project group",
|
name: 'org project group create project group',
|
||||||
component: createprojectgroup,
|
component: createprojectgroup,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectgroupref: parseRef(route.params.projectgroupref) })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectgroupref: parseRef(route.params.projectgroupref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "createproject",
|
path: 'createproject',
|
||||||
name: "org project group create project",
|
name: 'org project group create project',
|
||||||
component: createproject,
|
component: createproject,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectgroupref: parseRef(route.params.projectgroupref) })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectgroupref: parseRef(route.params.projectgroupref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
router.beforeEach(async (to, from, next) => {
|
router.beforeEach(async (to, from, next) => {
|
||||||
store.dispatch("setError", null);
|
store.dispatch('setError', null);
|
||||||
|
|
||||||
const { path, query } = to
|
const { path, query } = to;
|
||||||
|
|
||||||
if (path == "/run") {
|
if (path == '/run') {
|
||||||
// generic run handler by projectref and runid
|
// generic run handler by projectref and runid
|
||||||
let projectref = query.projectref
|
let projectref = query.projectref;
|
||||||
let runid = query.runid
|
let runid = query.runid;
|
||||||
|
|
||||||
let { data, error } = await fetchProject(projectref);
|
let { data, error } = await fetchProject(projectref);
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let project = data;
|
let project = data;
|
||||||
|
|
||||||
let parts = project.path.split("/")
|
let parts = project.path.split('/');
|
||||||
let nextPath = projectRunLink(parts[0], parts[1], parts.slice(2), runid)
|
let nextPath = projectRunLink(parts[0], parts[1], parts.slice(2), runid);
|
||||||
|
|
||||||
next({ path: nextPath.path, replace: true })
|
next({ path: nextPath.path, replace: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
next()
|
next();
|
||||||
})
|
});
|
||||||
|
|
||||||
export default router
|
export default router;
|
||||||
|
|
47
src/store.js
47
src/store.js
|
@ -1,55 +1,54 @@
|
||||||
import Vue from 'vue'
|
import Vue from 'vue';
|
||||||
import Vuex from 'vuex'
|
import Vuex from 'vuex';
|
||||||
|
|
||||||
Vue.use(Vuex)
|
Vue.use(Vuex);
|
||||||
|
|
||||||
const state = {
|
const state = {
|
||||||
error: null,
|
error: null,
|
||||||
user: null,
|
user: null,
|
||||||
registeruser: null,
|
registeruser: null,
|
||||||
}
|
};
|
||||||
|
|
||||||
const getters = {
|
const getters = {
|
||||||
// global error
|
// global error
|
||||||
error: state => {
|
error: (state) => {
|
||||||
return state.error
|
return state.error;
|
||||||
},
|
},
|
||||||
user: state => {
|
user: (state) => {
|
||||||
return state.user
|
return state.user;
|
||||||
},
|
},
|
||||||
registeruser: state => {
|
registeruser: (state) => {
|
||||||
return state.registeruser
|
return state.registeruser;
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
const mutations = {
|
const mutations = {
|
||||||
setError(state, error) {
|
setError(state, error) {
|
||||||
state.error = error
|
state.error = error;
|
||||||
},
|
},
|
||||||
setUser(state, user) {
|
setUser(state, user) {
|
||||||
state.user = user
|
state.user = user;
|
||||||
},
|
},
|
||||||
setRegisterUser(state, user) {
|
setRegisterUser(state, user) {
|
||||||
state.registeruser = user
|
state.registeruser = user;
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
const actions = {
|
const actions = {
|
||||||
setError({ commit }, error) {
|
setError({ commit }, error) {
|
||||||
commit('setError', error)
|
commit('setError', error);
|
||||||
},
|
},
|
||||||
setUser({ commit }, user) {
|
setUser({ commit }, user) {
|
||||||
commit('setUser', user)
|
commit('setUser', user);
|
||||||
},
|
},
|
||||||
setRegisterUser({ commit }, user) {
|
setRegisterUser({ commit }, user) {
|
||||||
commit('setRegisterUser', user)
|
commit('setRegisterUser', user);
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
export default new Vuex.Store({
|
export default new Vuex.Store({
|
||||||
state,
|
state,
|
||||||
getters,
|
getters,
|
||||||
actions,
|
actions,
|
||||||
mutations,
|
mutations,
|
||||||
})
|
});
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import store from "@/store";
|
import store from '@/store';
|
||||||
|
|
||||||
const ID_TOKEN_KEY = "id_token";
|
const ID_TOKEN_KEY = 'id_token';
|
||||||
const USER_KEY = "user";
|
const USER_KEY = 'user';
|
||||||
const LOGIN_REDIRECT_KEY = "login_redirect";
|
const LOGIN_REDIRECT_KEY = 'login_redirect';
|
||||||
|
|
||||||
let API_URL = window.CONFIG.API_URL;
|
let API_URL = window.CONFIG.API_URL;
|
||||||
let API_BASE_PATH = window.CONFIG.API_BASE_PATH;
|
let API_BASE_PATH = window.CONFIG.API_BASE_PATH;
|
||||||
|
@ -10,20 +10,20 @@ let API_BASE_PATH = window.CONFIG.API_BASE_PATH;
|
||||||
export function setLoggedUser(token, user) {
|
export function setLoggedUser(token, user) {
|
||||||
setIdToken(token);
|
setIdToken(token);
|
||||||
setUser(user);
|
setUser(user);
|
||||||
store.dispatch("setUser", user);
|
store.dispatch('setUser', user);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function doLogout() {
|
export function doLogout() {
|
||||||
unsetIdToken();
|
unsetIdToken();
|
||||||
unsetUser();
|
unsetUser();
|
||||||
store.dispatch("setUser", null);
|
store.dispatch('setUser', null);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function apiurlwithtoken(path) {
|
export function apiurlwithtoken(path) {
|
||||||
let u = new URL(API_URL + API_BASE_PATH + path);
|
let u = new URL(API_URL + API_BASE_PATH + path);
|
||||||
let idToken = getIdToken();
|
let idToken = getIdToken();
|
||||||
if (idToken) {
|
if (idToken) {
|
||||||
u.searchParams.append("access_token", idToken);
|
u.searchParams.append('access_token', idToken);
|
||||||
}
|
}
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
|
@ -33,19 +33,19 @@ export function apiurl(path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function loginurl() {
|
export function loginurl() {
|
||||||
return apiurl("/auth/login");
|
return apiurl('/auth/login');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function authorizeurl() {
|
export function authorizeurl() {
|
||||||
return apiurl("/auth/authorize");
|
return apiurl('/auth/authorize');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function registerurl() {
|
export function registerurl() {
|
||||||
return new apiurl("/auth/register");
|
return new apiurl('/auth/register');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function oauth2callbackurl() {
|
export function oauth2callbackurl() {
|
||||||
return new apiurl("/auth/oauth2/callback");
|
return new apiurl('/auth/oauth2/callback');
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loginapi(init) {
|
export async function loginapi(init) {
|
||||||
|
@ -64,19 +64,19 @@ export async function registerapi(init) {
|
||||||
return await window.fetch(registerurl(), init);
|
return await window.fetch(registerurl(), init);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetch(url, init, signal, token, tokenType = "bearer") {
|
export async function fetch(url, init, signal, token, tokenType = 'bearer') {
|
||||||
if (!init) {
|
if (!init) {
|
||||||
init = {};
|
init = {};
|
||||||
}
|
}
|
||||||
if (init.headers === undefined) {
|
if (init.headers === undefined) {
|
||||||
init["headers"] = {};
|
init['headers'] = {};
|
||||||
}
|
}
|
||||||
if (signal) {
|
if (signal) {
|
||||||
init["signal"] = signal;
|
init['signal'] = signal;
|
||||||
}
|
}
|
||||||
let idToken = token || getIdToken();
|
let idToken = token || getIdToken();
|
||||||
if (idToken) {
|
if (idToken) {
|
||||||
init.headers["Authorization"] = tokenType + " " + idToken;
|
init.headers['Authorization'] = tokenType + ' ' + idToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await window.fetch(url, init);
|
return await window.fetch(url, init);
|
||||||
|
|
233
src/util/data.js
233
src/util/data.js
|
@ -1,8 +1,9 @@
|
||||||
import router from "@/router";
|
import router from '@/router';
|
||||||
import { apiurl, fetch as authfetch, loginapi, registerapi } from "@/util/auth";
|
import { apiurl, fetch as authfetch, loginapi, registerapi } from '@/util/auth';
|
||||||
|
|
||||||
export const GITHUB_API_URL = "https://api.github.com";
|
export const GITHUB_API_URL = 'https://api.github.com';
|
||||||
export const GITHUB_SSH_KEY = "github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==";
|
export const GITHUB_SSH_KEY =
|
||||||
|
'github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==';
|
||||||
|
|
||||||
export async function fetch(url, init, signal, token, tokenType) {
|
export async function fetch(url, init, signal, token, tokenType) {
|
||||||
try {
|
try {
|
||||||
|
@ -10,8 +11,8 @@ export async function fetch(url, init, signal, token, tokenType) {
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
if (res.status === 401) {
|
if (res.status === 401) {
|
||||||
router.push({
|
router.push({
|
||||||
name: "login",
|
name: 'login',
|
||||||
query: { redirect: router.currentRoute.fullPath }
|
query: { redirect: router.currentRoute.fullPath },
|
||||||
});
|
});
|
||||||
// if we return a response containing an error what happens is
|
// if we return a response containing an error what happens is
|
||||||
// that router.push mounts the login view before the calling
|
// that router.push mounts the login view before the calling
|
||||||
|
@ -36,21 +37,21 @@ export async function fetch(url, init, signal, token, tokenType) {
|
||||||
return { data: await res.json(), error: null };
|
return { data: await res.json(), error: null };
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.name == "AbortError") {
|
if (e.name == 'AbortError') {
|
||||||
return { data: null, error: null, aborted: true };
|
return { data: null, error: null, aborted: true };
|
||||||
}
|
}
|
||||||
return { data: null, error: "api call failed: " + e.message };
|
return { data: null, error: 'api call failed: ' + e.message };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function login(username, password, remotesourcename) {
|
export async function login(username, password, remotesourcename) {
|
||||||
let init = {
|
let init = {
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
remote_source_name: remotesourcename,
|
remote_source_name: remotesourcename,
|
||||||
login_name: username,
|
login_name: username,
|
||||||
password: password
|
password: password,
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -62,7 +63,7 @@ export async function login(username, password, remotesourcename) {
|
||||||
return { data: await res.json(), error: null };
|
return { data: await res.json(), error: null };
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return { data: null, error: "api call failed: " + e.message };
|
return { data: null, error: 'api call failed: ' + e.message };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,13 +74,13 @@ export async function register(
|
||||||
remotepassword
|
remotepassword
|
||||||
) {
|
) {
|
||||||
let init = {
|
let init = {
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
username: username,
|
username: username,
|
||||||
remote_source_name: remotesourcename,
|
remote_source_name: remotesourcename,
|
||||||
remote_source_login_name: remoteloginname,
|
remote_source_login_name: remoteloginname,
|
||||||
remote_source_login_password: remotepassword
|
remote_source_login_password: remotepassword,
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -91,111 +92,122 @@ export async function register(
|
||||||
return { data: await res.json(), error: null };
|
return { data: await res.json(), error: null };
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return { data: null, error: "api call failed: " + e.message };
|
return { data: null, error: 'api call failed: ' + e.message };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchCurrentUser(signal) {
|
export async function fetchCurrentUser(signal) {
|
||||||
let path = "/user";
|
let path = '/user';
|
||||||
return await fetch(apiurl(path), null, signal);
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchOrgMembers(orgref, signal) {
|
export async function fetchOrgMembers(orgref, signal) {
|
||||||
let path = "/orgs/" + orgref + "/members";
|
let path = '/orgs/' + orgref + '/members';
|
||||||
return await fetch(apiurl(path), null, signal);
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchRuns(group, startRunID, lastrun, signal) {
|
export async function fetchRuns(group, startRunID, lastrun, signal) {
|
||||||
let u = apiurl("/runs");
|
let u = apiurl('/runs');
|
||||||
if (group) {
|
if (group) {
|
||||||
u.searchParams.append("group", group);
|
u.searchParams.append('group', group);
|
||||||
}
|
}
|
||||||
if (lastrun) {
|
if (lastrun) {
|
||||||
u.searchParams.append("lastrun", true);
|
u.searchParams.append('lastrun', true);
|
||||||
}
|
}
|
||||||
if (startRunID) {
|
if (startRunID) {
|
||||||
u.searchParams.append("start", startRunID);
|
u.searchParams.append('start', startRunID);
|
||||||
}
|
}
|
||||||
|
|
||||||
return await fetch(u, null, signal);
|
return await fetch(u, null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchRun(runid, signal) {
|
export async function fetchRun(runid, signal) {
|
||||||
return await fetch(apiurl("/runs/" + runid), null, signal);
|
return await fetch(apiurl('/runs/' + runid), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchTask(runid, taskid, signal) {
|
export async function fetchTask(runid, taskid, signal) {
|
||||||
return await fetch(apiurl("/runs/" + runid + "/tasks/" + taskid), signal);
|
return await fetch(apiurl('/runs/' + runid + '/tasks/' + taskid), signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchUser(username, signal) {
|
export async function fetchUser(username, signal) {
|
||||||
let path = "/users/" + username;
|
let path = '/users/' + username;
|
||||||
return await fetch(apiurl(path), null, signal);
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchProjectGroup(projectgroupref, signal) {
|
export async function fetchProjectGroup(projectgroupref, signal) {
|
||||||
let path = "/projectgroups/" + encodeURIComponent(projectgroupref);
|
let path = '/projectgroups/' + encodeURIComponent(projectgroupref);
|
||||||
|
|
||||||
return await fetch(apiurl(path), null, signal);
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchProjectGroupSubgroups(projectgroupref, signal) {
|
export async function fetchProjectGroupSubgroups(projectgroupref, signal) {
|
||||||
let path = "/projectgroups/" + encodeURIComponent(projectgroupref);
|
let path = '/projectgroups/' + encodeURIComponent(projectgroupref);
|
||||||
path += "/subgroups";
|
path += '/subgroups';
|
||||||
|
|
||||||
return await fetch(apiurl(path), null, signal);
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchProjectGroupProjects(projectgroupref, signal) {
|
export async function fetchProjectGroupProjects(projectgroupref, signal) {
|
||||||
let path = "/projectgroups/" + encodeURIComponent(projectgroupref);
|
let path = '/projectgroups/' + encodeURIComponent(projectgroupref);
|
||||||
path += "/projects";
|
path += '/projects';
|
||||||
|
|
||||||
return await fetch(apiurl(path), null, signal);
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchProject(ref, signal) {
|
export async function fetchProject(ref, signal) {
|
||||||
let path = "/projects/" + encodeURIComponent(ref);
|
let path = '/projects/' + encodeURIComponent(ref);
|
||||||
|
|
||||||
return await fetch(apiurl(path), null, signal);
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchSecrets(ownertype, ref, all, signal) {
|
export async function fetchSecrets(ownertype, ref, all, signal) {
|
||||||
let path;
|
let path;
|
||||||
if (ownertype == "project") {
|
if (ownertype == 'project') {
|
||||||
path = "/projects/";
|
path = '/projects/';
|
||||||
} else if (ownertype == "projectgroup") {
|
} else if (ownertype == 'projectgroup') {
|
||||||
path = "/projectgroups/";
|
path = '/projectgroups/';
|
||||||
}
|
}
|
||||||
path += encodeURIComponent(ref);
|
path += encodeURIComponent(ref);
|
||||||
path += "/secrets";
|
path += '/secrets';
|
||||||
if (all) {
|
if (all) {
|
||||||
path += "?tree&removeoverridden";
|
path += '?tree&removeoverridden';
|
||||||
}
|
}
|
||||||
return await fetch(apiurl(path), null, signal);
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchVariables(ownertype, ref, all, signal) {
|
export async function fetchVariables(ownertype, ref, all, signal) {
|
||||||
let path;
|
let path;
|
||||||
if (ownertype == "project") {
|
if (ownertype == 'project') {
|
||||||
path = "/projects/";
|
path = '/projects/';
|
||||||
} else if (ownertype == "projectgroup") {
|
} else if (ownertype == 'projectgroup') {
|
||||||
path = "/projectgroups/";
|
path = '/projectgroups/';
|
||||||
}
|
}
|
||||||
path += encodeURIComponent(ref);
|
path += encodeURIComponent(ref);
|
||||||
path += "/variables";
|
path += '/variables';
|
||||||
if (all) {
|
if (all) {
|
||||||
path += "?tree&removeoverridden";
|
path += '?tree&removeoverridden';
|
||||||
}
|
}
|
||||||
return await fetch(apiurl(path), null, signal);
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createRemoteSource(
|
export async function createRemoteSource(
|
||||||
token, type, name, clientID, clientSecret, apiURL, authType, skipVerify,
|
token,
|
||||||
sshHostKey, skipSshHostKeyCheck, registrationEnabled, loginEnabled, signal,
|
type,
|
||||||
|
name,
|
||||||
|
clientID,
|
||||||
|
clientSecret,
|
||||||
|
apiURL,
|
||||||
|
authType,
|
||||||
|
skipVerify,
|
||||||
|
sshHostKey,
|
||||||
|
skipSshHostKeyCheck,
|
||||||
|
registrationEnabled,
|
||||||
|
loginEnabled,
|
||||||
|
signal
|
||||||
) {
|
) {
|
||||||
let path = "/remotesources";
|
let path = '/remotesources';
|
||||||
let init = {
|
let init = {
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
name,
|
name,
|
||||||
apiurl: apiURL,
|
apiurl: apiURL,
|
||||||
|
@ -208,38 +220,38 @@ export async function createRemoteSource(
|
||||||
oauth_2_client_secret: clientSecret,
|
oauth_2_client_secret: clientSecret,
|
||||||
registration_enabled: registrationEnabled,
|
registration_enabled: registrationEnabled,
|
||||||
login_enabled: loginEnabled,
|
login_enabled: loginEnabled,
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal, token, "token");
|
return await fetch(apiurl(path), init, signal, token, 'token');
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createOrganization(orgname, visibility, signal) {
|
export async function createOrganization(orgname, visibility, signal) {
|
||||||
let path = "/orgs";
|
let path = '/orgs';
|
||||||
let init = {
|
let init = {
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
name: orgname,
|
name: orgname,
|
||||||
visibility: visibility
|
visibility: visibility,
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createUserToken(username, tokenname, signal) {
|
export async function createUserToken(username, tokenname, signal) {
|
||||||
let path = "/users/" + username + "/tokens";
|
let path = '/users/' + username + '/tokens';
|
||||||
let init = {
|
let init = {
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
token_name: tokenname
|
token_name: tokenname,
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteUserToken(username, tokenname, signal) {
|
export async function deleteUserToken(username, tokenname, signal) {
|
||||||
let path = "/users/" + username + "/tokens/" + tokenname;
|
let path = '/users/' + username + '/tokens/' + tokenname;
|
||||||
let init = {
|
let init = {
|
||||||
method: "DELETE"
|
method: 'DELETE',
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
@ -251,90 +263,90 @@ export async function createUserLinkedAccount(
|
||||||
password,
|
password,
|
||||||
signal
|
signal
|
||||||
) {
|
) {
|
||||||
let path = "/users/" + username + "/linkedaccounts";
|
let path = '/users/' + username + '/linkedaccounts';
|
||||||
let init = {
|
let init = {
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
remote_source_name: remotesourcename,
|
remote_source_name: remotesourcename,
|
||||||
remote_source_login_name: loginname,
|
remote_source_login_name: loginname,
|
||||||
remote_source_login_password: password
|
remote_source_login_password: password,
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteLinkedAccount(username, laid, signal) {
|
export async function deleteLinkedAccount(username, laid, signal) {
|
||||||
let path = "/users/" + username + "/linkedaccounts/" + laid;
|
let path = '/users/' + username + '/linkedaccounts/' + laid;
|
||||||
let init = {
|
let init = {
|
||||||
method: "DELETE"
|
method: 'DELETE',
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function restartRun(runid, fromStart, signal) {
|
export async function restartRun(runid, fromStart, signal) {
|
||||||
let path = "/runs/" + runid + "/actions";
|
let path = '/runs/' + runid + '/actions';
|
||||||
let init = {
|
let init = {
|
||||||
method: "PUT",
|
method: 'PUT',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
action_type: "restart",
|
action_type: 'restart',
|
||||||
from_start: fromStart
|
from_start: fromStart,
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function cancelRun(runid, signal) {
|
export async function cancelRun(runid, signal) {
|
||||||
let path = "/runs/" + runid + "/actions";
|
let path = '/runs/' + runid + '/actions';
|
||||||
let init = {
|
let init = {
|
||||||
method: "PUT",
|
method: 'PUT',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
action_type: "cancel"
|
action_type: 'cancel',
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function stopRun(runid, signal) {
|
export async function stopRun(runid, signal) {
|
||||||
let path = "/runs/" + runid + "/actions";
|
let path = '/runs/' + runid + '/actions';
|
||||||
let init = {
|
let init = {
|
||||||
method: "PUT",
|
method: 'PUT',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
action_type: "stop"
|
action_type: 'stop',
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function approveTask(runid, taskid, signal) {
|
export async function approveTask(runid, taskid, signal) {
|
||||||
let path = "/runs/" + runid + "/tasks/" + taskid + "/actions";
|
let path = '/runs/' + runid + '/tasks/' + taskid + '/actions';
|
||||||
let init = {
|
let init = {
|
||||||
method: "PUT",
|
method: 'PUT',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
action_type: "approve"
|
action_type: 'approve',
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchRemoteSources(signal) {
|
export async function fetchRemoteSources(signal) {
|
||||||
let path = "/remotesources";
|
let path = '/remotesources';
|
||||||
return await fetch(apiurl(path), null, signal);
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function userRemoteRepos(remotesourceid, signal) {
|
export async function userRemoteRepos(remotesourceid, signal) {
|
||||||
let path = "/user/remoterepos/" + remotesourceid;
|
let path = '/user/remoterepos/' + remotesourceid;
|
||||||
return await fetch(apiurl(path, null, signal));
|
return await fetch(apiurl(path, null, signal));
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createProjectGroup(parentref, name, visibility, signal) {
|
export async function createProjectGroup(parentref, name, visibility, signal) {
|
||||||
let path = "/projectgroups";
|
let path = '/projectgroups';
|
||||||
let init = {
|
let init = {
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
name: name,
|
name: name,
|
||||||
parent_ref: parentref,
|
parent_ref: parentref,
|
||||||
visibility: visibility
|
visibility: visibility,
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
@ -345,13 +357,13 @@ export async function updateProjectGroup(
|
||||||
visibility,
|
visibility,
|
||||||
signal
|
signal
|
||||||
) {
|
) {
|
||||||
let path = "/projectgroups/" + encodeURIComponent(projectgroupref);
|
let path = '/projectgroups/' + encodeURIComponent(projectgroupref);
|
||||||
let init = {
|
let init = {
|
||||||
method: "PUT",
|
method: 'PUT',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
name: name,
|
name: name,
|
||||||
visibility: visibility
|
visibility: visibility,
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
@ -365,56 +377,61 @@ export async function createProject(
|
||||||
passvarstoforkedpr,
|
passvarstoforkedpr,
|
||||||
signal
|
signal
|
||||||
) {
|
) {
|
||||||
let path = "/projects";
|
let path = '/projects';
|
||||||
let init = {
|
let init = {
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
name: name,
|
name: name,
|
||||||
parent_ref: parentref,
|
parent_ref: parentref,
|
||||||
visibility: visibility,
|
visibility: visibility,
|
||||||
remote_source_name: remotesourcename,
|
remote_source_name: remotesourcename,
|
||||||
repo_path: remoterepopath,
|
repo_path: remoterepopath,
|
||||||
pass_vars_to_forked_pr: passvarstoforkedpr
|
pass_vars_to_forked_pr: passvarstoforkedpr,
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updateProject(projectref, name, visibility, passvarstoforkedpr, signal) {
|
export async function updateProject(
|
||||||
let path = "/projects/" + encodeURIComponent(projectref);
|
projectref,
|
||||||
|
name,
|
||||||
|
visibility,
|
||||||
|
passvarstoforkedpr,
|
||||||
|
signal
|
||||||
|
) {
|
||||||
|
let path = '/projects/' + encodeURIComponent(projectref);
|
||||||
let init = {
|
let init = {
|
||||||
method: "PUT",
|
method: 'PUT',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
name: name,
|
name: name,
|
||||||
visibility: visibility,
|
visibility: visibility,
|
||||||
pass_vars_to_forked_pr: passvarstoforkedpr
|
pass_vars_to_forked_pr: passvarstoforkedpr,
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteProject(projectref, signal) {
|
export async function deleteProject(projectref, signal) {
|
||||||
let path = "/projects/" + encodeURIComponent(projectref);
|
let path = '/projects/' + encodeURIComponent(projectref);
|
||||||
let init = {
|
let init = {
|
||||||
method: "DELETE"
|
method: 'DELETE',
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function projectUpdateRepoLinkedAccount(projectref, signal) {
|
export async function projectUpdateRepoLinkedAccount(projectref, signal) {
|
||||||
let path =
|
let path =
|
||||||
"/projects/" + encodeURIComponent(projectref) + "/updaterepolinkedaccount";
|
'/projects/' + encodeURIComponent(projectref) + '/updaterepolinkedaccount';
|
||||||
let init = {
|
let init = {
|
||||||
method: "PUT"
|
method: 'PUT',
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteProjectGroup(projectgroupref, signal) {
|
export async function deleteProjectGroup(projectgroupref, signal) {
|
||||||
let path = "/projectgroups/" + encodeURIComponent(projectgroupref);
|
let path = '/projectgroups/' + encodeURIComponent(projectgroupref);
|
||||||
let init = {
|
let init = {
|
||||||
method: "DELETE"
|
method: 'DELETE',
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
153
src/util/link.js
153
src/util/link.js
|
@ -1,130 +1,173 @@
|
||||||
export function parseRef(ref) {
|
export function parseRef(ref) {
|
||||||
ref = ref.replace(/\.proj/, "")
|
ref = ref.replace(/\.proj/, '');
|
||||||
// return empty array or split return an array with the empty element
|
// return empty array or split return an array with the empty element
|
||||||
if (!ref) {
|
if (!ref) {
|
||||||
return []
|
return [];
|
||||||
}
|
}
|
||||||
return ref.split("/")
|
return ref.split('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ownerLink(ownertype, ownername) {
|
export function ownerLink(ownertype, ownername) {
|
||||||
if (ownertype == "user") {
|
if (ownertype == 'user') {
|
||||||
return { name: ownertype, params: { username: ownername } }
|
return { name: ownertype, params: { username: ownername } };
|
||||||
} else if (ownertype == "org") {
|
} else if (ownertype == 'org') {
|
||||||
return { name: ownertype, params: { orgname: ownername } }
|
return { name: ownertype, params: { orgname: ownername } };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ownerProjectsLink(ownertype, ownername) {
|
export function ownerProjectsLink(ownertype, ownername) {
|
||||||
return { name: ownertype + " projects", params: { ownername: ownername } }
|
return { name: ownertype + ' projects', params: { ownername: ownername } };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ownerSettingsLink(ownertype, ownername) {
|
export function ownerSettingsLink(ownertype, ownername) {
|
||||||
if (ownertype == "user") {
|
if (ownertype == 'user') {
|
||||||
return { name: ownertype + " settings", params: { username: ownername } }
|
return { name: ownertype + ' settings', params: { username: ownername } };
|
||||||
} else if (ownertype == "org") {
|
} else if (ownertype == 'org') {
|
||||||
return { name: ownertype + " settings", params: { orgname: ownername } }
|
return { name: ownertype + ' settings', params: { orgname: ownername } };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function userDirectRunsLink(username) {
|
export function userDirectRunsLink(username) {
|
||||||
return { name: "user direct runs", params: { username: username } }
|
return { name: 'user direct runs', params: { username: username } };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function userDirectRunLink(username, runid) {
|
export function userDirectRunLink(username, runid) {
|
||||||
return { name: "user direct run", params: { username: username, runid: runid } }
|
return {
|
||||||
|
name: 'user direct run',
|
||||||
|
params: { username: username, runid: runid },
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function userDirectRunTaskLink(username, runid, taskid) {
|
export function userDirectRunTaskLink(username, runid, taskid) {
|
||||||
return { name: "user direct run task", params: { username: username, runid: runid, taskid: taskid } }
|
return {
|
||||||
|
name: 'user direct run task',
|
||||||
|
params: { username: username, runid: runid, taskid: taskid },
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function userAddLinkedAccountLink(username, remotesourcename) {
|
export function userAddLinkedAccountLink(username, remotesourcename) {
|
||||||
return { name: "user add linked account", params: { username: username, remotesource: remotesourcename } }
|
return {
|
||||||
|
name: 'user add linked account',
|
||||||
|
params: { username: username, remotesource: remotesourcename },
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function orgMembersLink(orgname) {
|
export function orgMembersLink(orgname) {
|
||||||
return { name: "org members", params: { orgname: orgname } }
|
return { name: 'org members', params: { orgname: orgname } };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note, when creating a router link containing a project/projectgroup ref (a
|
// Note, when creating a router link containing a project/projectgroup ref (a
|
||||||
// path), unfortunately, we cannot use route name and params since it will path
|
// path), unfortunately, we cannot use route name and params since it will path
|
||||||
// escape it
|
// escape it
|
||||||
export function projectGroupPath(ownertype, ownername, projectgroupref) {
|
export function projectGroupPath(ownertype, ownername, projectgroupref) {
|
||||||
let path = `/${ownertype}/${ownername}`
|
let path = `/${ownertype}/${ownername}`;
|
||||||
// root project group will have a .proj without a name
|
// root project group will have a .proj without a name
|
||||||
let projectgrouppath = (projectgroupref.join("/") + ".proj")
|
let projectgrouppath = projectgroupref.join('/') + '.proj';
|
||||||
path = `${path}/projectgroups/${projectgrouppath}`
|
path = `${path}/projectgroups/${projectgrouppath}`;
|
||||||
return path
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function projectPath(ownertype, ownername, projectref) {
|
export function projectPath(ownertype, ownername, projectref) {
|
||||||
let path = `/${ownertype}/${ownername}`
|
let path = `/${ownertype}/${ownername}`;
|
||||||
let projectpath = (projectref.join("/") + ".proj")
|
let projectpath = projectref.join('/') + '.proj';
|
||||||
path = `${path}/projects/${projectpath}`
|
path = `${path}/projects/${projectpath}`;
|
||||||
return path
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function projectGroupLink(ownertype, ownername, projectgroupref) {
|
export function projectGroupLink(ownertype, ownername, projectgroupref) {
|
||||||
return { path: projectGroupPath(ownertype, ownername, projectgroupref) }
|
return { path: projectGroupPath(ownertype, ownername, projectgroupref) };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function projectGroupProjectsLink(ownertype, ownername, projectgroupref) {
|
export function projectGroupProjectsLink(
|
||||||
let projectgrouppath = (projectgroupref.join("/") + ".proj")
|
ownertype,
|
||||||
return { path: `/${ownertype}/${ownername}/projectgroups/${projectgrouppath}/projects` }
|
ownername,
|
||||||
|
projectgroupref
|
||||||
|
) {
|
||||||
|
let projectgrouppath = projectgroupref.join('/') + '.proj';
|
||||||
|
return {
|
||||||
|
path: `/${ownertype}/${ownername}/projectgroups/${projectgrouppath}/projects`,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function projectLink(ownertype, ownername, projectref) {
|
export function projectLink(ownertype, ownername, projectref) {
|
||||||
let projectpath = (projectref.join("/") + ".proj")
|
let projectpath = projectref.join('/') + '.proj';
|
||||||
return { path: `/${ownertype}/${ownername}/projects/${projectpath}` }
|
return { path: `/${ownertype}/${ownername}/projects/${projectpath}` };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function projectRunsLink(ownertype, ownername, projectref) {
|
export function projectRunsLink(ownertype, ownername, projectref) {
|
||||||
let projectpath = (projectref.join("/") + ".proj")
|
let projectpath = projectref.join('/') + '.proj';
|
||||||
return { path: `/${ownertype}/${ownername}/projects/${projectpath}/runs` }
|
return { path: `/${ownertype}/${ownername}/projects/${projectpath}/runs` };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function projectBranchesRunsLink(ownertype, ownername, projectref) {
|
export function projectBranchesRunsLink(ownertype, ownername, projectref) {
|
||||||
let projectpath = (projectref.join("/") + ".proj")
|
let projectpath = projectref.join('/') + '.proj';
|
||||||
return { path: `/${ownertype}/${ownername}/projects/${projectpath}/branches` }
|
return {
|
||||||
|
path: `/${ownertype}/${ownername}/projects/${projectpath}/branches`,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function projectTagsRunsLink(ownertype, ownername, projectref) {
|
export function projectTagsRunsLink(ownertype, ownername, projectref) {
|
||||||
let projectpath = (projectref.join("/") + ".proj")
|
let projectpath = projectref.join('/') + '.proj';
|
||||||
return { path: `/${ownertype}/${ownername}/projects/${projectpath}/tags` }
|
return { path: `/${ownertype}/${ownername}/projects/${projectpath}/tags` };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function projectPRsRunsLink(ownertype, ownername, projectref) {
|
export function projectPRsRunsLink(ownertype, ownername, projectref) {
|
||||||
let projectpath = (projectref.join("/") + ".proj")
|
let projectpath = projectref.join('/') + '.proj';
|
||||||
return { path: `/${ownertype}/${ownername}/projects/${projectpath}/pullrequests` }
|
return {
|
||||||
|
path: `/${ownertype}/${ownername}/projects/${projectpath}/pullrequests`,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function projectRunLink(ownertype, ownername, projectref, runid) {
|
export function projectRunLink(ownertype, ownername, projectref, runid) {
|
||||||
let projectpath = (projectref.join("/") + ".proj")
|
let projectpath = projectref.join('/') + '.proj';
|
||||||
return { path: `/${ownertype}/${ownername}/projects/${projectpath}/runs/${runid}` }
|
return {
|
||||||
|
path: `/${ownertype}/${ownername}/projects/${projectpath}/runs/${runid}`,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function projectRunTaskLink(ownertype, ownername, projectref, runid, taskid) {
|
export function projectRunTaskLink(
|
||||||
let projectpath = (projectref.join("/") + ".proj")
|
ownertype,
|
||||||
return { path: `/${ownertype}/${ownername}/projects/${projectpath}/runs/${runid}/tasks/${taskid}` }
|
ownername,
|
||||||
|
projectref,
|
||||||
|
runid,
|
||||||
|
taskid
|
||||||
|
) {
|
||||||
|
let projectpath = projectref.join('/') + '.proj';
|
||||||
|
return {
|
||||||
|
path: `/${ownertype}/${ownername}/projects/${projectpath}/runs/${runid}/tasks/${taskid}`,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function projectGroupSettingsLink(ownertype, ownername, projectgroupref) {
|
export function projectGroupSettingsLink(
|
||||||
let path = projectGroupPath(ownertype, ownername, projectgroupref)
|
ownertype,
|
||||||
return { path: `${path}/settings` }
|
ownername,
|
||||||
|
projectgroupref
|
||||||
|
) {
|
||||||
|
let path = projectGroupPath(ownertype, ownername, projectgroupref);
|
||||||
|
return { path: `${path}/settings` };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function projectSettingsLink(ownertype, ownername, projectref) {
|
export function projectSettingsLink(ownertype, ownername, projectref) {
|
||||||
let projectpath = (projectref.join("/") + ".proj")
|
let projectpath = projectref.join('/') + '.proj';
|
||||||
return { path: `/${ownertype}/${ownername}/projects/${projectpath}/settings` }
|
return {
|
||||||
|
path: `/${ownertype}/${ownername}/projects/${projectpath}/settings`,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function projectGroupCreateProjectGroupLink(ownertype, ownername, projectgroupref) {
|
export function projectGroupCreateProjectGroupLink(
|
||||||
let path = projectGroupPath(ownertype, ownername, projectgroupref)
|
ownertype,
|
||||||
return { path: `${path}/createprojectgroup` }
|
ownername,
|
||||||
|
projectgroupref
|
||||||
|
) {
|
||||||
|
let path = projectGroupPath(ownertype, ownername, projectgroupref);
|
||||||
|
return { path: `${path}/createprojectgroup` };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function projectGroupCreateProjectLink(ownertype, ownername, projectgroupref) {
|
export function projectGroupCreateProjectLink(
|
||||||
let path = projectGroupPath(ownertype, ownername, projectgroupref)
|
ownertype,
|
||||||
return { path: `${path}/createproject` }
|
ownername,
|
||||||
|
projectgroupref
|
||||||
|
) {
|
||||||
|
let path = projectGroupPath(ownertype, ownername, projectgroupref);
|
||||||
|
return { path: `${path}/createproject` };
|
||||||
}
|
}
|
|
@ -1,11 +1,10 @@
|
||||||
|
|
||||||
export function runStatus(run) {
|
export function runStatus(run) {
|
||||||
// * if the run has a result then return the result
|
// * if the run has a result then return the result
|
||||||
// * if stopping return "stopping"
|
// * if stopping return "stopping"
|
||||||
// * return the phase
|
// * return the phase
|
||||||
if (run.result != "unknown") return run.result;
|
if (run.result != 'unknown') return run.result;
|
||||||
if (run.stopping) return "stopping";
|
if (run.stopping) return 'stopping';
|
||||||
if (run.phase != "finished") return run.phase;
|
if (run.phase != 'finished') return run.phase;
|
||||||
|
|
||||||
return run.result;
|
return run.result;
|
||||||
}
|
}
|
||||||
|
@ -13,13 +12,13 @@ export function runStatus(run) {
|
||||||
export function runResultClass(run) {
|
export function runResultClass(run) {
|
||||||
let status = runStatus(run);
|
let status = runStatus(run);
|
||||||
|
|
||||||
if (status == "setuperror") return "setuperror";
|
if (status == 'setuperror') return 'setuperror';
|
||||||
if (status == "queued") return "unknown";
|
if (status == 'queued') return 'unknown';
|
||||||
if (status == "cancelled") return "failed";
|
if (status == 'cancelled') return 'failed';
|
||||||
if (status == "running") return "running";
|
if (status == 'running') return 'running';
|
||||||
if (status == "stopping") return "failed";
|
if (status == 'stopping') return 'failed';
|
||||||
if (status == "stopped") return "failed";
|
if (status == 'stopped') return 'failed';
|
||||||
if (status == "success") return "success";
|
if (status == 'success') return 'success';
|
||||||
if (status == "failed") return "failed";
|
if (status == 'failed') return 'failed';
|
||||||
return "unknown";
|
return 'unknown';
|
||||||
}
|
}
|
|
@ -13,36 +13,44 @@
|
||||||
v-if="remotesource.auth_type == 'password'"
|
v-if="remotesource.auth_type == 'password'"
|
||||||
action="Add Linked Account"
|
action="Add Linked Account"
|
||||||
:name="remotesource.name"
|
:name="remotesource.name"
|
||||||
v-on:login="doAddLinkedAccount(remotesource.name, $event.username, $event.password)"
|
v-on:login="
|
||||||
|
doAddLinkedAccount(
|
||||||
|
remotesource.name,
|
||||||
|
$event.username,
|
||||||
|
$event.password
|
||||||
|
)
|
||||||
|
"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
v-else
|
v-else
|
||||||
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
|
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
|
||||||
@click="doAddLinkedAccount(remotesource.name)"
|
@click="doAddLinkedAccount(remotesource.name)"
|
||||||
>Add Linked Account with {{remotesource.name}}</button>
|
>
|
||||||
|
Add Linked Account with {{ remotesource.name }}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import LoginForm from "@/components/loginform";
|
import LoginForm from '@/components/loginform';
|
||||||
|
|
||||||
import { fetchRemoteSources, createUserLinkedAccount } from "@/util/data";
|
import { fetchRemoteSources, createUserLinkedAccount } from '@/util/data';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "AddLinkedAccount",
|
name: 'AddLinkedAccount',
|
||||||
props: {
|
props: {
|
||||||
username: String,
|
username: String,
|
||||||
remoteSourceName: String
|
remoteSourceName: String,
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
LoginForm
|
LoginForm,
|
||||||
},
|
},
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
addLinkedAccountError: null,
|
addLinkedAccountError: null,
|
||||||
remotesource: null
|
remotesource: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -52,7 +60,7 @@ export default {
|
||||||
async fetchRemoteSources() {
|
async fetchRemoteSources() {
|
||||||
let { data, error } = await fetchRemoteSources();
|
let { data, error } = await fetchRemoteSources();
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (var i = 0; i < data.length; i++) {
|
for (var i = 0; i < data.length; i++) {
|
||||||
|
@ -79,17 +87,13 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
name: "user settings",
|
name: 'user settings',
|
||||||
params: { username: this.username }
|
params: { username: this.username },
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
this.fetchRemoteSources();
|
this.fetchRemoteSources();
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,12 +9,8 @@
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div class="flex justify-center items-center w-max">
|
||||||
class="flex justify-center items-center w-max"
|
<CreateSourceForm v-on:createSource="createSource($event)" />
|
||||||
>
|
|
||||||
<CreateSourceForm
|
|
||||||
v-on:createSource="createSource($event)"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -22,15 +18,14 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import CreateSourceForm from '@/components/createsourceform';
|
||||||
import CreateSourceForm from "@/components/createsourceform";
|
import { createRemoteSource } from '@/util/data.js';
|
||||||
import { createRemoteSource } from "@/util/data.js";
|
import router from '@/router';
|
||||||
import router from "@/router";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "CreateSource",
|
name: 'CreateSource',
|
||||||
components: {
|
components: {
|
||||||
CreateSourceForm
|
CreateSourceForm,
|
||||||
},
|
},
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
|
@ -39,23 +34,37 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async createSource({
|
async createSource({
|
||||||
token, name, type, clientId, clientSecret, url, skipVerify, sshHostKey,
|
token,
|
||||||
|
name,
|
||||||
|
type,
|
||||||
|
clientId,
|
||||||
|
clientSecret,
|
||||||
|
url,
|
||||||
|
skipVerify,
|
||||||
|
sshHostKey,
|
||||||
skipSshHostKeyCheck,
|
skipSshHostKeyCheck,
|
||||||
}) {
|
}) {
|
||||||
const res = await createRemoteSource(
|
const res = await createRemoteSource(
|
||||||
token, type, name, clientId, clientSecret, url, "oauth2", skipVerify,
|
token,
|
||||||
sshHostKey, skipSshHostKeyCheck, true, true, undefined,
|
type,
|
||||||
|
name,
|
||||||
|
clientId,
|
||||||
|
clientSecret,
|
||||||
|
url,
|
||||||
|
'oauth2',
|
||||||
|
skipVerify,
|
||||||
|
sshHostKey,
|
||||||
|
skipSshHostKeyCheck,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
undefined
|
||||||
);
|
);
|
||||||
if (res.error)
|
if (res.error) this.$store.dispatch('setError', res.error);
|
||||||
this.$store.dispatch("setError", res.error);
|
else router.push({ name: 'login' });
|
||||||
else
|
},
|
||||||
router.push({name: "login"});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
mounted: function () {
|
mounted: function () {
|
||||||
this.$store.dispatch("setError", null);
|
this.$store.dispatch('setError', null);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,25 +1,15 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="home flex flex-col items-center">
|
<div class="home flex flex-col items-center">
|
||||||
<img
|
<img class="w-64 h-64" src="/img/agola-logo-name.svg" alt="agola logo" />
|
||||||
class="w-64 h-64"
|
|
||||||
src="/img/agola-logo-name.svg" alt="agola logo"
|
|
||||||
/>
|
|
||||||
<h1 class="text-2xl">CI/CD redefined</h1>
|
<h1 class="text-2xl">CI/CD redefined</h1>
|
||||||
<div class="m-8">
|
<div class="m-8">
|
||||||
<h1 class="text-lg">
|
<h1 class="text-lg">
|
||||||
Hi, you are almost ready to go! Just
|
Hi, you are almost ready to go! Just
|
||||||
<router-link
|
<router-link class="underline text-blue-600" to="/login">
|
||||||
class="underline text-blue-600"
|
|
||||||
to="/login"
|
|
||||||
>
|
|
||||||
login
|
login
|
||||||
</router-link>
|
</router-link>
|
||||||
into your account
|
into your account or create a
|
||||||
or create a
|
<router-link class="underline text-blue-600" to="/register">
|
||||||
<router-link
|
|
||||||
class="underline text-blue-600"
|
|
||||||
to="/register"
|
|
||||||
>
|
|
||||||
new one
|
new one
|
||||||
</router-link>
|
</router-link>
|
||||||
</h1>
|
</h1>
|
||||||
|
@ -28,22 +18,22 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters } from "vuex";
|
import { mapGetters } from 'vuex';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Home",
|
name: 'Home',
|
||||||
components: {},
|
components: {},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(["user"])
|
...mapGetters(['user']),
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
let user = this.$store.getters.user;
|
let user = this.$store.getters.user;
|
||||||
if (user) {
|
if (user) {
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
name: "user",
|
name: 'user',
|
||||||
params: { username: this.user.username }
|
params: { username: this.user.username },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -13,13 +13,8 @@
|
||||||
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
||||||
>
|
>
|
||||||
No remote sources defined
|
No remote sources defined
|
||||||
<router-link
|
<router-link class="underline text-blue-600 block" to="/newsource">
|
||||||
class="underline text-blue-600 block"
|
<button class="btn btn-blue">Create one</button>
|
||||||
to="/newsource"
|
|
||||||
>
|
|
||||||
<button class="btn btn-blue">
|
|
||||||
Create one
|
|
||||||
</button>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -61,25 +56,25 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { fetchRemoteSources, login } from "@/util/data";
|
import { fetchRemoteSources, login } from '@/util/data';
|
||||||
import {
|
import {
|
||||||
setLoggedUser,
|
setLoggedUser,
|
||||||
unsetLoginRedirect,
|
unsetLoginRedirect,
|
||||||
setLoginRedirect,
|
setLoginRedirect,
|
||||||
doLogout
|
doLogout,
|
||||||
} from "@/util/auth";
|
} from '@/util/auth';
|
||||||
|
|
||||||
import LoginForm from "@/components/loginform";
|
import LoginForm from '@/components/loginform';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Login",
|
name: 'Login',
|
||||||
components: {
|
components: {
|
||||||
LoginForm
|
LoginForm,
|
||||||
},
|
},
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
error: null,
|
error: null,
|
||||||
remotesources: null
|
remotesources: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -96,20 +91,20 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async fetchRemoteSources() {
|
async fetchRemoteSources() {
|
||||||
let { data, error } = await fetchRemoteSources();
|
let { data, error } = await fetchRemoteSources();
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.remotesources = data;
|
this.remotesources = data;
|
||||||
},
|
},
|
||||||
async doLogin(username, password, remotesourcename) {
|
async doLogin(username, password, remotesourcename) {
|
||||||
unsetLoginRedirect();
|
unsetLoginRedirect();
|
||||||
let redirect = this.$route.query["redirect"];
|
let redirect = this.$route.query['redirect'];
|
||||||
|
|
||||||
this.error = null;
|
this.error = null;
|
||||||
|
|
||||||
|
@ -131,18 +126,16 @@ export default {
|
||||||
unsetLoginRedirect();
|
unsetLoginRedirect();
|
||||||
this.$router.push(redirect);
|
this.$router.push(redirect);
|
||||||
} else {
|
} else {
|
||||||
this.$router.push({ name: "home" });
|
this.$router.push({ name: 'home' });
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
},
|
||||||
mounted: function () {
|
mounted: function () {
|
||||||
this.$store.dispatch("setError", null);
|
this.$store.dispatch('setError', null);
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
doLogout();
|
doLogout();
|
||||||
this.fetchRemoteSources();
|
this.fetchRemoteSources();
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
<script>
|
<script>
|
||||||
import { doLogout } from "@/util/auth";
|
import { doLogout } from '@/util/auth';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Logout",
|
name: 'Logout',
|
||||||
created: function () {
|
created: function () {
|
||||||
doLogout();
|
doLogout();
|
||||||
this.$router.push("/");
|
this.$router.push('/');
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,32 +11,32 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { fetch } from "@/util/data";
|
import { fetch } from '@/util/data';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
oauth2callbackurl,
|
oauth2callbackurl,
|
||||||
setLoggedUser,
|
setLoggedUser,
|
||||||
unsetLoginRedirect,
|
unsetLoginRedirect,
|
||||||
getLoginRedirect
|
getLoginRedirect,
|
||||||
} from "@/util/auth";
|
} from '@/util/auth';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: {},
|
||||||
name: "Oauth2",
|
name: 'Oauth2',
|
||||||
props: {},
|
props: {},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
error: null,
|
error: null,
|
||||||
run: null,
|
run: null,
|
||||||
code: this.$route.query.code,
|
code: this.$route.query.code,
|
||||||
username: null
|
username: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async doOauth2() {
|
async doOauth2() {
|
||||||
let u = oauth2callbackurl();
|
let u = oauth2callbackurl();
|
||||||
u.searchParams.append("code", this.$route.query.code);
|
u.searchParams.append('code', this.$route.query.code);
|
||||||
u.searchParams.append("state", this.$route.query.state);
|
u.searchParams.append('state', this.$route.query.state);
|
||||||
let { data, error } = await fetch(u);
|
let { data, error } = await fetch(u);
|
||||||
if (error) {
|
if (error) {
|
||||||
// set local login error on failed oauth2.
|
// set local login error on failed oauth2.
|
||||||
|
@ -44,29 +44,28 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.request_type === "loginuser") {
|
if (data.request_type === 'loginuser') {
|
||||||
setLoggedUser(data.response.token, data.response.user);
|
setLoggedUser(data.response.token, data.response.user);
|
||||||
let redirect = getLoginRedirect(redirect);
|
let redirect = getLoginRedirect(redirect);
|
||||||
if (redirect) {
|
if (redirect) {
|
||||||
unsetLoginRedirect();
|
unsetLoginRedirect();
|
||||||
this.$router.push(redirect);
|
this.$router.push(redirect);
|
||||||
} else {
|
} else {
|
||||||
this.$router.push({ name: "home" });
|
this.$router.push({ name: 'home' });
|
||||||
}
|
}
|
||||||
} else if (data.request_type === "authorize") {
|
} else if (data.request_type === 'authorize') {
|
||||||
this.$store.dispatch("setRegisterUser", data.response);
|
this.$store.dispatch('setRegisterUser', data.response);
|
||||||
this.$router.push("/register");
|
this.$router.push('/register');
|
||||||
} else if (data.request_type === "createuserla") {
|
} else if (data.request_type === 'createuserla') {
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
name: "user settings",
|
name: 'user settings',
|
||||||
params: { username: this.username }
|
params: { username: this.username },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
this.doOauth2();
|
this.doOauth2();
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,9 @@
|
||||||
<span class="mx-2">/</span>
|
<span class="mx-2">/</span>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<router-link :to="ownerLink('org', orgname)">{{orgname}}</router-link>
|
<router-link :to="ownerLink('org', orgname)">{{
|
||||||
|
orgname
|
||||||
|
}}</router-link>
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
</nav>
|
</nav>
|
||||||
|
@ -23,7 +25,12 @@
|
||||||
<ul class="flex-grow tab">
|
<ul class="flex-grow tab">
|
||||||
<li
|
<li
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
:class="[{ 'tab-element-selected': $route.name === 'org projects' || $route.name === 'org' }]"
|
:class="[
|
||||||
|
{
|
||||||
|
'tab-element-selected':
|
||||||
|
$route.name === 'org projects' || $route.name === 'org',
|
||||||
|
},
|
||||||
|
]"
|
||||||
>
|
>
|
||||||
<router-link :to="ownerProjectsLink('org', orgname)">
|
<router-link :to="ownerProjectsLink('org', orgname)">
|
||||||
<i class="mr-1 mdi mdi-home" />
|
<i class="mr-1 mdi mdi-home" />
|
||||||
|
@ -42,7 +49,13 @@
|
||||||
<li
|
<li
|
||||||
v-if="$route.name.endsWith('org project group settings')"
|
v-if="$route.name.endsWith('org project group settings')"
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
:class="[{ 'tab-element-selected': $route.name.endsWith('org project group settings') }]"
|
:class="[
|
||||||
|
{
|
||||||
|
'tab-element-selected': $route.name.endsWith(
|
||||||
|
'org project group settings'
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]"
|
||||||
>
|
>
|
||||||
<router-link :to="projectGroupSettingsLink('org', orgname, [])">
|
<router-link :to="projectGroupSettingsLink('org', orgname, [])">
|
||||||
<i class="mr-1 mdi mdi-settings" />
|
<i class="mr-1 mdi mdi-settings" />
|
||||||
|
@ -52,7 +65,9 @@
|
||||||
<li
|
<li
|
||||||
v-if="$route.name.endsWith('org settings')"
|
v-if="$route.name.endsWith('org settings')"
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
:class="[{ 'tab-element-selected': $route.name.endsWith('org settings') }]"
|
:class="[
|
||||||
|
{ 'tab-element-selected': $route.name.endsWith('org settings') },
|
||||||
|
]"
|
||||||
>
|
>
|
||||||
<router-link :to="ownerSettingsLink('org', orgname)">
|
<router-link :to="ownerSettingsLink('org', orgname)">
|
||||||
<i class="mr-1 mdi mdi-settings" />
|
<i class="mr-1 mdi mdi-settings" />
|
||||||
|
@ -65,7 +80,7 @@
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<div
|
<div
|
||||||
class="flex -mt-3"
|
class="flex -mt-3"
|
||||||
v-click-outside="() => dropdownActive = false"
|
v-click-outside="() => (dropdownActive = false)"
|
||||||
@click="dropdownActive = !dropdownActive"
|
@click="dropdownActive = !dropdownActive"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
|
@ -108,9 +123,8 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as vClickOutside from "v-click-outside-x";
|
import * as vClickOutside from 'v-click-outside-x';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ownerLink,
|
ownerLink,
|
||||||
|
@ -119,23 +133,23 @@ import {
|
||||||
orgMembersLink,
|
orgMembersLink,
|
||||||
projectGroupCreateProjectGroupLink,
|
projectGroupCreateProjectGroupLink,
|
||||||
projectGroupCreateProjectLink,
|
projectGroupCreateProjectLink,
|
||||||
projectGroupSettingsLink
|
projectGroupSettingsLink,
|
||||||
} from "@/util/link.js";
|
} from '@/util/link.js';
|
||||||
|
|
||||||
import createprojectbutton from "@/components/createprojectbutton.vue";
|
import createprojectbutton from '@/components/createprojectbutton.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Org",
|
name: 'Org',
|
||||||
components: { createprojectbutton },
|
components: { createprojectbutton },
|
||||||
directives: {
|
directives: {
|
||||||
clickOutside: vClickOutside.directive
|
clickOutside: vClickOutside.directive,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
orgname: String
|
orgname: String,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
dropdownActive: false
|
dropdownActive: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -147,19 +161,18 @@ export default {
|
||||||
projectGroupCreateProjectLink: projectGroupCreateProjectLink,
|
projectGroupCreateProjectLink: projectGroupCreateProjectLink,
|
||||||
projectGroupSettingsLink: projectGroupSettingsLink,
|
projectGroupSettingsLink: projectGroupSettingsLink,
|
||||||
goToCreate(type) {
|
goToCreate(type) {
|
||||||
if (type == "project") {
|
if (type == 'project') {
|
||||||
this.$router.push(
|
this.$router.push(
|
||||||
projectGroupCreateProjectLink("org", this.orgname, [])
|
projectGroupCreateProjectLink('org', this.orgname, [])
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.$router.push(
|
this.$router.push(
|
||||||
projectGroupCreateProjectGroupLink("org", this.orgname, [])
|
projectGroupCreateProjectGroupLink('org', this.orgname, [])
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<projbreadcrumbs :ownertype="ownertype" :ownername="ownername" :projectref="projectref" />
|
<projbreadcrumbs
|
||||||
|
:ownertype="ownertype"
|
||||||
|
:ownername="ownername"
|
||||||
|
:projectref="projectref"
|
||||||
|
/>
|
||||||
|
|
||||||
<div class="mb-8">
|
<div class="mb-8">
|
||||||
<span class="text-3xl">{{ projectName() }}</span>
|
<span class="text-3xl">{{ projectName() }}</span>
|
||||||
|
@ -17,7 +21,13 @@
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
:class="[{ 'tab-element-selected': $route.name.match('project runs') || $route.name.endsWith('project') }]"
|
:class="[
|
||||||
|
{
|
||||||
|
'tab-element-selected':
|
||||||
|
$route.name.match('project runs') ||
|
||||||
|
$route.name.endsWith('project'),
|
||||||
|
},
|
||||||
|
]"
|
||||||
>
|
>
|
||||||
<router-link :to="projectRunsLink(ownertype, ownername, projectref)">
|
<router-link :to="projectRunsLink(ownertype, ownername, projectref)">
|
||||||
<i class="mr-1 mdi mdi-asterisk" />
|
<i class="mr-1 mdi mdi-asterisk" />
|
||||||
|
@ -26,42 +36,81 @@
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
:class="[{ 'tab-element-selected': $route.name.match('project branches runs') }]"
|
:class="[
|
||||||
|
{
|
||||||
|
'tab-element-selected': $route.name.match(
|
||||||
|
'project branches runs'
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
:to="projectBranchesRunsLink(ownertype, ownername, projectref)"
|
||||||
>
|
>
|
||||||
<router-link :to="projectBranchesRunsLink(ownertype, ownername, projectref)">
|
|
||||||
<i class="mr-1 mdi mdi-source-branch" />
|
<i class="mr-1 mdi mdi-source-branch" />
|
||||||
<span>Branches</span>
|
<span>Branches</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
:class="[{ 'tab-element-selected': $route.name.match('project tags runs') }]"
|
:class="[
|
||||||
|
{ 'tab-element-selected': $route.name.match('project tags runs') },
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
:to="projectTagsRunsLink(ownertype, ownername, projectref)"
|
||||||
>
|
>
|
||||||
<router-link :to="projectTagsRunsLink(ownertype, ownername, projectref)">
|
|
||||||
<i class="mr-1 mdi mdi-tag" />
|
<i class="mr-1 mdi mdi-tag" />
|
||||||
<span>Tags</span>
|
<span>Tags</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
:class="[{ 'tab-element-selected': $route.name.match('project pull requests runs') }]"
|
:class="[
|
||||||
|
{
|
||||||
|
'tab-element-selected': $route.name.match(
|
||||||
|
'project pull requests runs'
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
:to="projectPRsRunsLink(ownertype, ownername, projectref)"
|
||||||
>
|
>
|
||||||
<router-link :to="projectPRsRunsLink(ownertype, ownername, projectref)">
|
|
||||||
<i class="mr-1 mdi mdi-source-pull" />
|
<i class="mr-1 mdi mdi-source-pull" />
|
||||||
<span>Pull Requests</span>
|
<span>Pull Requests</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
v-if="run && ($route.name.endsWith('project run') || $route.name.endsWith('project run task'))"
|
v-if="
|
||||||
|
run &&
|
||||||
|
($route.name.endsWith('project run') ||
|
||||||
|
$route.name.endsWith('project run task'))
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<tabarrow />
|
<tabarrow />
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
v-if="run && ($route.name.endsWith('project run') || $route.name.endsWith('project run task'))"
|
v-if="
|
||||||
:class="[{ 'tab-element-selected': $route.name.endsWith('project run') }]"
|
run &&
|
||||||
|
($route.name.endsWith('project run') ||
|
||||||
|
$route.name.endsWith('project run task'))
|
||||||
|
"
|
||||||
|
:class="[
|
||||||
|
{ 'tab-element-selected': $route.name.endsWith('project run') },
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
:to="
|
||||||
|
projectRunLink(
|
||||||
|
ownertype,
|
||||||
|
ownername,
|
||||||
|
projectref,
|
||||||
|
$route.params.runid
|
||||||
|
)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<router-link :to="projectRunLink(ownertype, ownername, projectref, $route.params.runid)">
|
|
||||||
<p>
|
<p>
|
||||||
Run
|
Run
|
||||||
<strong>#{{ run.counter }}</strong>
|
<strong>#{{ run.counter }}</strong>
|
||||||
|
@ -74,10 +123,22 @@
|
||||||
<li
|
<li
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
v-if="run && $route.name.endsWith('project run task')"
|
v-if="run && $route.name.endsWith('project run task')"
|
||||||
:class="[{ 'tab-element-selected': $route.name.endsWith('project run task') }]"
|
:class="[
|
||||||
|
{
|
||||||
|
'tab-element-selected': $route.name.endsWith('project run task'),
|
||||||
|
},
|
||||||
|
]"
|
||||||
>
|
>
|
||||||
<router-link
|
<router-link
|
||||||
:to="projectRunTaskLink(ownertype, ownername, projectref, $route.params.runid, $route.params.taskid)"
|
:to="
|
||||||
|
projectRunTaskLink(
|
||||||
|
ownertype,
|
||||||
|
ownername,
|
||||||
|
projectref,
|
||||||
|
$route.params.runid,
|
||||||
|
$route.params.taskid
|
||||||
|
)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<p>
|
<p>
|
||||||
Task
|
Task
|
||||||
|
@ -88,9 +149,15 @@
|
||||||
<li
|
<li
|
||||||
v-if="$route.name.endsWith('project settings')"
|
v-if="$route.name.endsWith('project settings')"
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
:class="[{ 'tab-element-selected': $route.name.endsWith('project settings') }]"
|
:class="[
|
||||||
|
{
|
||||||
|
'tab-element-selected': $route.name.endsWith('project settings'),
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
:to="projectSettingsLink(ownertype, ownername, projectref)"
|
||||||
>
|
>
|
||||||
<router-link :to="projectSettingsLink(ownertype, ownername, projectref)">
|
|
||||||
<i class="mr-1 mdi mdi-settings" />
|
<i class="mr-1 mdi mdi-settings" />
|
||||||
<span>Project Settings</span>
|
<span>Project Settings</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
@ -101,7 +168,7 @@
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<div
|
<div
|
||||||
class="flex -mt-3"
|
class="flex -mt-3"
|
||||||
v-click-outside="() => dropdownActive = false"
|
v-click-outside="() => (dropdownActive = false)"
|
||||||
@click="dropdownActive = !dropdownActive"
|
@click="dropdownActive = !dropdownActive"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
|
@ -135,9 +202,8 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as vClickOutside from "v-click-outside-x";
|
import * as vClickOutside from 'v-click-outside-x';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
projectLink,
|
projectLink,
|
||||||
|
@ -147,31 +213,31 @@ import {
|
||||||
projectPRsRunsLink,
|
projectPRsRunsLink,
|
||||||
projectRunLink,
|
projectRunLink,
|
||||||
projectRunTaskLink,
|
projectRunTaskLink,
|
||||||
projectSettingsLink
|
projectSettingsLink,
|
||||||
} from "@/util/link.js";
|
} from '@/util/link.js';
|
||||||
|
|
||||||
import { fetchRun } from "@/util/data.js";
|
import { fetchRun } from '@/util/data.js';
|
||||||
|
|
||||||
import projbreadcrumbs from "@/components/projbreadcrumbs.vue";
|
import projbreadcrumbs from '@/components/projbreadcrumbs.vue';
|
||||||
import tabarrow from "@/components/tabarrow.vue";
|
import tabarrow from '@/components/tabarrow.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Project",
|
name: 'Project',
|
||||||
components: { projbreadcrumbs, tabarrow },
|
components: { projbreadcrumbs, tabarrow },
|
||||||
directives: {
|
directives: {
|
||||||
clickOutside: vClickOutside.directive
|
clickOutside: vClickOutside.directive,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
ownertype: String,
|
ownertype: String,
|
||||||
ownername: String,
|
ownername: String,
|
||||||
projectref: Array
|
projectref: Array,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
fetchAbort: null,
|
fetchAbort: null,
|
||||||
|
|
||||||
dropdownActive: false,
|
dropdownActive: false,
|
||||||
run: null
|
run: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -191,12 +257,12 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.run = data;
|
this.run = data;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
projectLink: projectLink,
|
projectLink: projectLink,
|
||||||
|
@ -209,7 +275,7 @@ export default {
|
||||||
projectSettingsLink: projectSettingsLink,
|
projectSettingsLink: projectSettingsLink,
|
||||||
projectName() {
|
projectName() {
|
||||||
return this.projectref[this.projectref.length - 1];
|
return this.projectref[this.projectref.length - 1];
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created: async function () {
|
created: async function () {
|
||||||
this.fetchAbort = new AbortController();
|
this.fetchAbort = new AbortController();
|
||||||
|
@ -223,7 +289,7 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.run = data;
|
this.run = data;
|
||||||
|
@ -233,9 +299,8 @@ export default {
|
||||||
if (this.fetchAbort) {
|
if (this.fetchAbort) {
|
||||||
this.fetchAbort.abort();
|
this.fetchAbort.abort();
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<projbreadcrumbs
|
<projbreadcrumbs
|
||||||
|
@ -16,9 +15,19 @@
|
||||||
<ul class="flex-grow tab">
|
<ul class="flex-grow tab">
|
||||||
<li
|
<li
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
:class="[{ 'tab-element-selected': $route.name.match('project group project') || $route.name.endsWith('project group') }]"
|
:class="[
|
||||||
|
{
|
||||||
|
'tab-element-selected':
|
||||||
|
$route.name.match('project group project') ||
|
||||||
|
$route.name.endsWith('project group'),
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
:to="
|
||||||
|
projectGroupProjectsLink(ownertype, ownername, projectgroupref)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<router-link :to="projectGroupProjectsLink(ownertype, ownername, projectgroupref)">
|
|
||||||
<i class="mdi mdi-home" />
|
<i class="mdi mdi-home" />
|
||||||
<span>Projects</span>
|
<span>Projects</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
@ -26,9 +35,19 @@
|
||||||
<li
|
<li
|
||||||
v-if="$route.name.endsWith('project group settings')"
|
v-if="$route.name.endsWith('project group settings')"
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
:class="[{ 'tab-element-selected': $route.name.endsWith('project group settings') }]"
|
:class="[
|
||||||
|
{
|
||||||
|
'tab-element-selected': $route.name.endsWith(
|
||||||
|
'project group settings'
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
:to="
|
||||||
|
projectGroupSettingsLink(ownertype, ownername, projectgroupref)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<router-link :to="projectGroupSettingsLink(ownertype, ownername, projectgroupref)">
|
|
||||||
<i class="mdi mdi-settings" />
|
<i class="mdi mdi-settings" />
|
||||||
<span>Project Group Settings</span>
|
<span>Project Group Settings</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
@ -39,7 +58,7 @@
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<div
|
<div
|
||||||
class="flex -mt-3"
|
class="flex -mt-3"
|
||||||
v-click-outside="() => dropdownActive = false"
|
v-click-outside="() => (dropdownActive = false)"
|
||||||
@click="dropdownActive = !dropdownActive"
|
@click="dropdownActive = !dropdownActive"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
|
@ -57,7 +76,13 @@
|
||||||
<li>
|
<li>
|
||||||
<router-link
|
<router-link
|
||||||
class="block px-4 py-2 hover:bg-blue-500 hover:text-white"
|
class="block px-4 py-2 hover:bg-blue-500 hover:text-white"
|
||||||
:to="projectGroupSettingsLink(ownertype, ownername, projectgroupref)"
|
:to="
|
||||||
|
projectGroupSettingsLink(
|
||||||
|
ownertype,
|
||||||
|
ownername,
|
||||||
|
projectgroupref
|
||||||
|
)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<i class="mdi mdi-settings" />
|
<i class="mdi mdi-settings" />
|
||||||
<span>Project Group Settings</span>
|
<span>Project Group Settings</span>
|
||||||
|
@ -73,34 +98,33 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as vClickOutside from "v-click-outside-x";
|
import * as vClickOutside from 'v-click-outside-x';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
projectGroupProjectsLink,
|
projectGroupProjectsLink,
|
||||||
projectGroupSettingsLink,
|
projectGroupSettingsLink,
|
||||||
projectGroupCreateProjectGroupLink,
|
projectGroupCreateProjectGroupLink,
|
||||||
projectGroupCreateProjectLink
|
projectGroupCreateProjectLink,
|
||||||
} from "@/util/link.js";
|
} from '@/util/link.js';
|
||||||
|
|
||||||
import projbreadcrumbs from "@/components/projbreadcrumbs.vue";
|
import projbreadcrumbs from '@/components/projbreadcrumbs.vue';
|
||||||
import createprojectbutton from "@/components/createprojectbutton.vue";
|
import createprojectbutton from '@/components/createprojectbutton.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ProjectGroup",
|
name: 'ProjectGroup',
|
||||||
components: { projbreadcrumbs, createprojectbutton },
|
components: { projbreadcrumbs, createprojectbutton },
|
||||||
directives: {
|
directives: {
|
||||||
clickOutside: vClickOutside.directive
|
clickOutside: vClickOutside.directive,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
ownertype: String,
|
ownertype: String,
|
||||||
ownername: String,
|
ownername: String,
|
||||||
projectgroupref: Array
|
projectgroupref: Array,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
dropdownActive: false
|
dropdownActive: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -110,12 +134,12 @@ export default {
|
||||||
projectGroupCreateProjectLink: projectGroupCreateProjectLink,
|
projectGroupCreateProjectLink: projectGroupCreateProjectLink,
|
||||||
projectGroupName() {
|
projectGroupName() {
|
||||||
if (!this.projectgroupref.length) {
|
if (!this.projectgroupref.length) {
|
||||||
return "Root Project Group";
|
return 'Root Project Group';
|
||||||
}
|
}
|
||||||
return this.projectgroupref[this.projectgroupref.length - 1];
|
return this.projectgroupref[this.projectgroupref.length - 1];
|
||||||
},
|
},
|
||||||
goToCreate(type) {
|
goToCreate(type) {
|
||||||
if (type == "project") {
|
if (type == 'project') {
|
||||||
this.$router.push(
|
this.$router.push(
|
||||||
projectGroupCreateProjectLink(
|
projectGroupCreateProjectLink(
|
||||||
this.ownertype,
|
this.ownertype,
|
||||||
|
@ -132,10 +156,9 @@ export default {
|
||||||
this.projectgroupref
|
this.projectgroupref
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
|
@ -28,13 +28,8 @@
|
||||||
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
||||||
>
|
>
|
||||||
No remote sources defined
|
No remote sources defined
|
||||||
<router-link
|
<router-link class="underline text-blue-600 block" to="/newsource">
|
||||||
class="underline text-blue-600 block"
|
<button class="btn btn-blue">Create one</button>
|
||||||
to="/newsource"
|
|
||||||
>
|
|
||||||
<button class="btn btn-blue">
|
|
||||||
Create one
|
|
||||||
</button>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -75,29 +70,29 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters } from "vuex";
|
import { mapGetters } from 'vuex';
|
||||||
|
|
||||||
import LoginForm from "@/components/loginform";
|
import LoginForm from '@/components/loginform';
|
||||||
import RegisterForm from "@/components/registerform";
|
import RegisterForm from '@/components/registerform';
|
||||||
|
|
||||||
import { fetchRemoteSources, register } from "@/util/data";
|
import { fetchRemoteSources, register } from '@/util/data';
|
||||||
|
|
||||||
import { authorizeurl, fetch, doLogout } from "@/util/auth";
|
import { authorizeurl, fetch, doLogout } from '@/util/auth';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Register",
|
name: 'Register',
|
||||||
components: {
|
components: {
|
||||||
LoginForm,
|
LoginForm,
|
||||||
RegisterForm
|
RegisterForm,
|
||||||
},
|
},
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
error: null,
|
error: null,
|
||||||
remotesources: null
|
remotesources: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(["registeruser"]),
|
...mapGetters(['registeruser']),
|
||||||
|
|
||||||
hasRemoteSources() {
|
hasRemoteSources() {
|
||||||
if (this.remotesources) {
|
if (this.remotesources) {
|
||||||
|
@ -112,13 +107,13 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async fetchRemoteSources() {
|
async fetchRemoteSources() {
|
||||||
let { data, error } = await fetchRemoteSources();
|
let { data, error } = await fetchRemoteSources();
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.remotesources = data;
|
this.remotesources = data;
|
||||||
|
@ -127,12 +122,12 @@ export default {
|
||||||
let u = authorizeurl();
|
let u = authorizeurl();
|
||||||
let res = await (
|
let res = await (
|
||||||
await fetch(u, {
|
await fetch(u, {
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
remote_source_name: remotesourcename,
|
remote_source_name: remotesourcename,
|
||||||
login_name: username,
|
login_name: username,
|
||||||
password: password
|
password: password,
|
||||||
})
|
}),
|
||||||
})
|
})
|
||||||
).json();
|
).json();
|
||||||
|
|
||||||
|
@ -140,11 +135,11 @@ export default {
|
||||||
window.location = res.oauth2_redirect;
|
window.location = res.oauth2_redirect;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.$store.dispatch("setRegisterUser", {
|
this.$store.dispatch('setRegisterUser', {
|
||||||
remote_user_info: res.remote_user_info,
|
remote_user_info: res.remote_user_info,
|
||||||
remote_source_name: res.remote_source_name,
|
remote_source_name: res.remote_source_name,
|
||||||
remote_source_login_name: username,
|
remote_source_login_name: username,
|
||||||
remote_source_login_password: password
|
remote_source_login_password: password,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
async doRegister(
|
async doRegister(
|
||||||
|
@ -170,18 +165,15 @@ export default {
|
||||||
window.location = data.oauth2_redirect;
|
window.location = data.oauth2_redirect;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.$router.push({ name: "home" });
|
this.$router.push({ name: 'home' });
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
mounted: function () {
|
mounted: function () {
|
||||||
this.$store.dispatch("setError", null);
|
this.$store.dispatch('setError', null);
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
doLogout();
|
doLogout();
|
||||||
this.fetchRemoteSources();
|
this.fetchRemoteSources();
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,9 @@
|
||||||
<span class="mx-2">/</span>
|
<span class="mx-2">/</span>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<router-link :to="ownerLink('user', username)">{{username}}</router-link>
|
<router-link :to="ownerLink('user', username)">{{
|
||||||
|
username
|
||||||
|
}}</router-link>
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
</nav>
|
</nav>
|
||||||
|
@ -23,7 +25,12 @@
|
||||||
<ul class="flex-grow tab">
|
<ul class="flex-grow tab">
|
||||||
<li
|
<li
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
:class="[{ 'tab-element-selected': $route.name === 'user projects' || $route.name === 'user' }]"
|
:class="[
|
||||||
|
{
|
||||||
|
'tab-element-selected':
|
||||||
|
$route.name === 'user projects' || $route.name === 'user',
|
||||||
|
},
|
||||||
|
]"
|
||||||
>
|
>
|
||||||
<router-link :to="ownerProjectsLink('user', username)">
|
<router-link :to="ownerProjectsLink('user', username)">
|
||||||
<i class="mr-1 mdi mdi-home" />
|
<i class="mr-1 mdi mdi-home" />
|
||||||
|
@ -32,7 +39,9 @@
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
:class="[{ 'tab-element-selected': $route.name === 'user direct runs' }]"
|
:class="[
|
||||||
|
{ 'tab-element-selected': $route.name === 'user direct runs' },
|
||||||
|
]"
|
||||||
>
|
>
|
||||||
<router-link :to="userDirectRunsLink(username)">
|
<router-link :to="userDirectRunsLink(username)">
|
||||||
<i class="mr-1 mdi mdi-run-fast" />
|
<i class="mr-1 mdi mdi-run-fast" />
|
||||||
|
@ -40,14 +49,24 @@
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
v-if="run && ($route.name === 'user direct run' || $route.name == 'user direct run task')"
|
v-if="
|
||||||
|
run &&
|
||||||
|
($route.name === 'user direct run' ||
|
||||||
|
$route.name == 'user direct run task')
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<tabarrow />
|
<tabarrow />
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
v-if="run && ($route.name === 'user direct run' || $route.name == 'user direct run task')"
|
v-if="
|
||||||
:class="[{ 'tab-element-selected': $route.name === 'user direct run' }]"
|
run &&
|
||||||
|
($route.name === 'user direct run' ||
|
||||||
|
$route.name == 'user direct run task')
|
||||||
|
"
|
||||||
|
:class="[
|
||||||
|
{ 'tab-element-selected': $route.name === 'user direct run' },
|
||||||
|
]"
|
||||||
>
|
>
|
||||||
<router-link :to="userDirectRunLink(username, $route.params.runid)">
|
<router-link :to="userDirectRunLink(username, $route.params.runid)">
|
||||||
<span>
|
<span>
|
||||||
|
@ -62,10 +81,18 @@
|
||||||
<li
|
<li
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
v-if="run && $route.name == 'user direct run task'"
|
v-if="run && $route.name == 'user direct run task'"
|
||||||
:class="[{ 'tab-element-selected': $route.name === 'user direct run task' }]"
|
:class="[
|
||||||
|
{ 'tab-element-selected': $route.name === 'user direct run task' },
|
||||||
|
]"
|
||||||
>
|
>
|
||||||
<router-link
|
<router-link
|
||||||
:to="userDirectRunTaskLink(username, $route.params.runid, $route.params.taskid)"
|
:to="
|
||||||
|
userDirectRunTaskLink(
|
||||||
|
username,
|
||||||
|
$route.params.runid,
|
||||||
|
$route.params.taskid
|
||||||
|
)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
Task
|
Task
|
||||||
|
@ -76,7 +103,13 @@
|
||||||
<li
|
<li
|
||||||
v-if="$route.name.endsWith('user project group settings')"
|
v-if="$route.name.endsWith('user project group settings')"
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
:class="[{ 'tab-element-selected': $route.name.endsWith('user project group settings') }]"
|
:class="[
|
||||||
|
{
|
||||||
|
'tab-element-selected': $route.name.endsWith(
|
||||||
|
'user project group settings'
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]"
|
||||||
>
|
>
|
||||||
<router-link :to="projectGroupSettingsLink('user', username, [])">
|
<router-link :to="projectGroupSettingsLink('user', username, [])">
|
||||||
<i class="mr-1 mdi mdi-settings" />
|
<i class="mr-1 mdi mdi-settings" />
|
||||||
|
@ -86,7 +119,9 @@
|
||||||
<li
|
<li
|
||||||
v-if="$route.name.endsWith('user settings')"
|
v-if="$route.name.endsWith('user settings')"
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
:class="[{ 'tab-element-selected': $route.name.endsWith('user settings') }]"
|
:class="[
|
||||||
|
{ 'tab-element-selected': $route.name.endsWith('user settings') },
|
||||||
|
]"
|
||||||
>
|
>
|
||||||
<router-link :to="ownerSettingsLink('user', username)">
|
<router-link :to="ownerSettingsLink('user', username)">
|
||||||
<i class="mr-1 mdi mdi-settings" />
|
<i class="mr-1 mdi mdi-settings" />
|
||||||
|
@ -99,7 +134,7 @@
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<div
|
<div
|
||||||
class="flex -mt-3"
|
class="flex -mt-3"
|
||||||
v-click-outside="() => dropdownActive = false"
|
v-click-outside="() => (dropdownActive = false)"
|
||||||
@click="dropdownActive = !dropdownActive"
|
@click="dropdownActive = !dropdownActive"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
|
@ -134,7 +169,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as vClickOutside from "v-click-outside-x";
|
import * as vClickOutside from 'v-click-outside-x';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ownerLink,
|
ownerLink,
|
||||||
|
@ -145,29 +180,29 @@ import {
|
||||||
ownerSettingsLink,
|
ownerSettingsLink,
|
||||||
projectGroupCreateProjectGroupLink,
|
projectGroupCreateProjectGroupLink,
|
||||||
projectGroupCreateProjectLink,
|
projectGroupCreateProjectLink,
|
||||||
projectGroupSettingsLink
|
projectGroupSettingsLink,
|
||||||
} from "@/util/link.js";
|
} from '@/util/link.js';
|
||||||
|
|
||||||
import { fetchRun } from "@/util/data.js";
|
import { fetchRun } from '@/util/data.js';
|
||||||
|
|
||||||
import createprojectbutton from "@/components/createprojectbutton.vue";
|
import createprojectbutton from '@/components/createprojectbutton.vue';
|
||||||
import tabarrow from "@/components/tabarrow.vue";
|
import tabarrow from '@/components/tabarrow.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "User",
|
name: 'User',
|
||||||
components: { createprojectbutton, tabarrow },
|
components: { createprojectbutton, tabarrow },
|
||||||
directives: {
|
directives: {
|
||||||
clickOutside: vClickOutside.directive
|
clickOutside: vClickOutside.directive,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
username: String
|
username: String,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
fetchAbort: null,
|
fetchAbort: null,
|
||||||
|
|
||||||
dropdownActive: false,
|
dropdownActive: false,
|
||||||
run: null
|
run: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -187,12 +222,12 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.run = data;
|
this.run = data;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
ownerLink: ownerLink,
|
ownerLink: ownerLink,
|
||||||
|
@ -205,16 +240,16 @@ export default {
|
||||||
projectGroupCreateProjectLink: projectGroupCreateProjectLink,
|
projectGroupCreateProjectLink: projectGroupCreateProjectLink,
|
||||||
projectGroupSettingsLink: projectGroupSettingsLink,
|
projectGroupSettingsLink: projectGroupSettingsLink,
|
||||||
goToCreate(type) {
|
goToCreate(type) {
|
||||||
if (type == "project") {
|
if (type == 'project') {
|
||||||
this.$router.push(
|
this.$router.push(
|
||||||
projectGroupCreateProjectLink("user", this.username, [])
|
projectGroupCreateProjectLink('user', this.username, [])
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.$router.push(
|
this.$router.push(
|
||||||
projectGroupCreateProjectGroupLink("user", this.username, [])
|
projectGroupCreateProjectGroupLink('user', this.username, [])
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created: async function () {
|
created: async function () {
|
||||||
this.fetchAbort = new AbortController();
|
this.fetchAbort = new AbortController();
|
||||||
|
@ -228,7 +263,7 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.run = data;
|
this.run = data;
|
||||||
|
@ -238,9 +273,8 @@ export default {
|
||||||
if (this.fetchAbort) {
|
if (this.fetchAbort) {
|
||||||
this.fetchAbort.abort();
|
this.fetchAbort.abort();
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
75
tailwind.js
75
tailwind.js
|
@ -6,43 +6,54 @@ module.exports = {
|
||||||
padding: '2rem',
|
padding: '2rem',
|
||||||
},
|
},
|
||||||
fontFamily: {
|
fontFamily: {
|
||||||
'sans': ['Segoe UI', 'Roboto', 'Helvetica Neue', 'Arial', 'Noto Sans', 'sans-serif', 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji']
|
sans: [
|
||||||
|
'Segoe UI',
|
||||||
|
'Roboto',
|
||||||
|
'Helvetica Neue',
|
||||||
|
'Arial',
|
||||||
|
'Noto Sans',
|
||||||
|
'sans-serif',
|
||||||
|
'Apple Color Emoji',
|
||||||
|
'Segoe UI Emoji',
|
||||||
|
'Segoe UI Symbol',
|
||||||
|
'Noto Color Emoji',
|
||||||
|
],
|
||||||
},
|
},
|
||||||
borderWidth: {
|
borderWidth: {
|
||||||
default: '1px',
|
default: '1px',
|
||||||
'0': '0',
|
0: '0',
|
||||||
'2': '2px',
|
2: '2px',
|
||||||
'4': '4px',
|
4: '4px',
|
||||||
'5': '5px',
|
5: '5px',
|
||||||
'6': '6px',
|
6: '6px',
|
||||||
},
|
},
|
||||||
spacing: {
|
spacing: {
|
||||||
px: '1px',
|
px: '1px',
|
||||||
'2px': '2px',
|
'2px': '2px',
|
||||||
'3px': '3px',
|
'3px': '3px',
|
||||||
'0': '0',
|
0: '0',
|
||||||
'1': '0.25rem',
|
1: '0.25rem',
|
||||||
'2': '0.5rem',
|
2: '0.5rem',
|
||||||
'3': '0.75rem',
|
3: '0.75rem',
|
||||||
'4': '1rem',
|
4: '1rem',
|
||||||
'5': '1.25rem',
|
5: '1.25rem',
|
||||||
'6': '1.5rem',
|
6: '1.5rem',
|
||||||
'8': '2rem',
|
8: '2rem',
|
||||||
'10': '2.5rem',
|
10: '2.5rem',
|
||||||
'12': '3rem',
|
12: '3rem',
|
||||||
'16': '4rem',
|
16: '4rem',
|
||||||
'20': '5rem',
|
20: '5rem',
|
||||||
'24': '6rem',
|
24: '6rem',
|
||||||
'32': '8rem',
|
32: '8rem',
|
||||||
'40': '10rem',
|
40: '10rem',
|
||||||
'48': '12rem',
|
48: '12rem',
|
||||||
'56': '14rem',
|
56: '14rem',
|
||||||
'64': '16rem',
|
64: '16rem',
|
||||||
},
|
},
|
||||||
colors: {
|
colors: {
|
||||||
dark: '#4a4a4a',
|
dark: '#4a4a4a',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
variants: {
|
variants: {
|
||||||
backgroundColor: ['responsive', 'hover', 'focus', 'disabled'],
|
backgroundColor: ['responsive', 'hover', 'focus', 'disabled'],
|
||||||
|
@ -56,9 +67,9 @@ module.exports = {
|
||||||
function ({ addVariant, e }) {
|
function ({ addVariant, e }) {
|
||||||
addVariant('disabled', ({ modifySelectors, separator }) => {
|
addVariant('disabled', ({ modifySelectors, separator }) => {
|
||||||
modifySelectors(({ className }) => {
|
modifySelectors(({ className }) => {
|
||||||
return `.${e(`disabled${separator}${className}`)}:disabled`
|
return `.${e(`disabled${separator}${className}`)}:disabled`;
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const path = require("path");
|
const path = require('path');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
css: {
|
css: {
|
||||||
sourceMap: true
|
sourceMap: true,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue