*: Format with prettier
Use latest prettier as devDependency so tools will use (or can be configured to use) the npm provided version. The unique config change is to use single quotes instead of double quotes.
This commit is contained in:
parent
ca0c494425
commit
3f2c57394a
|
@ -0,0 +1,3 @@
|
|||
module.exports = {
|
||||
singleQuote: true,
|
||||
};
|
|
@ -1,5 +1,3 @@
|
|||
module.exports = {
|
||||
presets: [
|
||||
'@vue/cli-plugin-babel/preset'
|
||||
]
|
||||
}
|
||||
presets: ['@vue/cli-plugin-babel/preset'],
|
||||
};
|
||||
|
|
|
@ -2,12 +2,8 @@
|
|||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"*": [
|
||||
"types/*"
|
||||
]
|
||||
"*": ["types/*"]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"./src/**/*"
|
||||
]
|
||||
"include": ["./src/**/*"]
|
||||
}
|
|
@ -1977,6 +1977,13 @@
|
|||
"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": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
|
@ -9849,11 +9856,10 @@
|
|||
"dev": true
|
||||
},
|
||||
"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
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz",
|
||||
"integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==",
|
||||
"dev": true
|
||||
},
|
||||
"pretty-error": {
|
||||
"version": "2.1.2",
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
"eslint": "^6.7.2",
|
||||
"eslint-plugin-vue": "^6.2.2",
|
||||
"node-sass": "^4.14.1",
|
||||
"prettier": "2.5.1",
|
||||
"sass-loader": "^8.0.2",
|
||||
"tailwindcss": "^1.9.6",
|
||||
"vue-template-compiler": "^2.6.12"
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
module.exports = {
|
||||
"plugins": [
|
||||
require('tailwindcss')('tailwind.js'),
|
||||
require('autoprefixer')(),
|
||||
]
|
||||
}
|
||||
plugins: [require('tailwindcss')('tailwind.js'), require('autoprefixer')()],
|
||||
};
|
||||
|
|
67
src/App.vue
67
src/App.vue
|
@ -1,7 +1,9 @@
|
|||
<template>
|
||||
<div id="app">
|
||||
<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">
|
||||
<router-link
|
||||
class="font-semibold flex items-center flex-shrink-0 text-xl tracking-tight"
|
||||
|
@ -28,12 +30,12 @@
|
|||
</div>
|
||||
<div
|
||||
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 v-if="user" class="relative mr-3">
|
||||
<button
|
||||
v-click-outside="() => createDropdownActive = false"
|
||||
v-click-outside="() => (createDropdownActive = false)"
|
||||
@click="createDropdownActive = !createDropdownActive"
|
||||
class="relative flex items-center focus:outline-none"
|
||||
>
|
||||
|
@ -49,7 +51,8 @@
|
|||
<router-link
|
||||
class="block px-4 py-2 hover:bg-blue-500 hover:text-white"
|
||||
to="/neworganization"
|
||||
>New Organization</router-link>
|
||||
>New Organization</router-link
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -57,11 +60,11 @@
|
|||
<div v-if="user" class="relative">
|
||||
<div class="flex">
|
||||
<button
|
||||
v-click-outside="() => userDropdownActive = false"
|
||||
v-click-outside="() => (userDropdownActive = false)"
|
||||
@click="userDropdownActive = !userDropdownActive"
|
||||
class="relative flex items-center focus:outline-none"
|
||||
>
|
||||
{{user.username}}
|
||||
{{ user.username }}
|
||||
<i class="mdi mdi-chevron-down"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -72,7 +75,7 @@
|
|||
<ul>
|
||||
<li class="block px-4 py-2 border-b">
|
||||
Logged as
|
||||
<b>{{user.username}}</b>
|
||||
<b>{{ user.username }}</b>
|
||||
</li>
|
||||
<li>
|
||||
<hr class="navbar-divider" />
|
||||
|
@ -98,18 +101,30 @@
|
|||
</div>
|
||||
</div>
|
||||
<div v-else class="navbar-item">
|
||||
<router-link class="btn btn-blue" to="/register">Sign up</router-link>
|
||||
<router-link class="ml-2 btn btn-blue" to="/login">Login</router-link>
|
||||
<router-link class="btn btn-blue" to="/register"
|
||||
>Sign up</router-link
|
||||
>
|
||||
<router-link class="ml-2 btn btn-blue" to="/login"
|
||||
>Login</router-link
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<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 class="bg-red-500 text-white font-bold rounded-t px-4 py-2">Error</div>
|
||||
<div class="border border-t-0 border-red-400 rounded-b bg-red-100 px-4 py-3 text-red-700">
|
||||
<div class="bg-red-500 text-white font-bold rounded-t px-4 py-2">
|
||||
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>
|
||||
<button class="btn btn-red" @click="reload()">Retry</button>
|
||||
</div>
|
||||
|
@ -123,48 +138,46 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<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 {
|
||||
name: "App",
|
||||
name: 'App',
|
||||
directives: {
|
||||
clickOutside: vClickOutside.directive
|
||||
clickOutside: vClickOutside.directive,
|
||||
},
|
||||
components: {},
|
||||
computed: {
|
||||
...mapGetters(["error", "user"])
|
||||
...mapGetters(['error', 'user']),
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
routerActive: true,
|
||||
navActive: false,
|
||||
userDropdownActive: false,
|
||||
createDropdownActive: false
|
||||
createDropdownActive: false,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
$route: function() {
|
||||
$route: function () {
|
||||
this.userDropdownActive = false;
|
||||
this.createDropdownActive = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
// method to reload current view from https://github.com/vuejs/vue-router/issues/296#issuecomment-356530037
|
||||
methods: {
|
||||
ownerSettingsLink: ownerSettingsLink,
|
||||
reload() {
|
||||
this.$store.dispatch("setError", null);
|
||||
this.$store.dispatch('setError', null);
|
||||
this.routerActive = false;
|
||||
this.$nextTick(() => (this.routerActive = true));
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
||||
<style lang="scss"></style>
|
||||
|
|
|
@ -8,19 +8,21 @@
|
|||
type="text"
|
||||
placeholder="Organization name"
|
||||
v-model="orgName"
|
||||
>
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label>
|
||||
<input type="checkbox" v-model="orgIsPrivate">
|
||||
<input type="checkbox" v-model="orgIsPrivate" />
|
||||
Private
|
||||
</label>
|
||||
</div>
|
||||
<button
|
||||
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
|
||||
@click="createOrg()"
|
||||
>Create Organization</button>
|
||||
>
|
||||
Create Organization
|
||||
</button>
|
||||
<div
|
||||
v-if="createOrgError"
|
||||
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
||||
|
@ -32,19 +34,19 @@
|
|||
</template>
|
||||
|
||||
<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 {
|
||||
components: {},
|
||||
name: "createorganization",
|
||||
name: 'createorganization',
|
||||
props: {},
|
||||
data() {
|
||||
return {
|
||||
createOrgError: null,
|
||||
orgIsPrivate: false,
|
||||
orgName: null
|
||||
orgName: null,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
|
@ -54,9 +56,9 @@ export default {
|
|||
async createOrg() {
|
||||
this.resetErrors();
|
||||
|
||||
let visibility = "public";
|
||||
let visibility = 'public';
|
||||
if (this.orgIsPrivate) {
|
||||
visibility = "private";
|
||||
visibility = 'private';
|
||||
}
|
||||
|
||||
let { error } = await createOrganization(this.orgName, visibility);
|
||||
|
@ -65,14 +67,11 @@ export default {
|
|||
return;
|
||||
}
|
||||
|
||||
this.$router.push(ownerLink("org", this.orgName));
|
||||
}
|
||||
this.$router.push(ownerLink('org', this.orgName));
|
||||
},
|
||||
created: async function() {}
|
||||
},
|
||||
created: async function () {},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
|
@ -7,17 +7,18 @@
|
|||
type="text"
|
||||
placeholder="Project Name"
|
||||
v-model="projectName"
|
||||
>
|
||||
/>
|
||||
<div class="mb-4">
|
||||
<label>
|
||||
<input type="checkbox" v-model="projectIsPrivate">
|
||||
<input type="checkbox" v-model="projectIsPrivate" />
|
||||
Private
|
||||
</label>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label class="checkbox">
|
||||
<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>
|
||||
</div>
|
||||
<div class="mb-3 flex items-center">
|
||||
|
@ -31,31 +32,48 @@
|
|||
v-for="(rs, index) in remoteSources"
|
||||
v-bind:key="rs.id"
|
||||
:value="index"
|
||||
>{{ rs.name }}</option>
|
||||
>
|
||||
{{ rs.name }}
|
||||
</option>
|
||||
</select>
|
||||
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2">
|
||||
<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>
|
||||
<div
|
||||
class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2"
|
||||
>
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="ml-3 btn btn-blue"
|
||||
v-bind:class="{ 'spinner': fetchRemoteReposLoading }"
|
||||
v-bind:class="{ spinner: fetchRemoteReposLoading }"
|
||||
:disabled="selectedRemoteSourceIndex == null"
|
||||
@click="fetchRemoteRepos()"
|
||||
>Fetch remote repositories</button>
|
||||
>
|
||||
Fetch remote repositories
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div v-if="remoteRepos.length">
|
||||
<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
|
||||
class="btn btn-blue"
|
||||
v-bind:class="{ 'spinner': createProjectLoading }"
|
||||
v-bind:class="{ spinner: createProjectLoading }"
|
||||
:disabled="!createProjectButtonEnabled"
|
||||
@click="createProject()"
|
||||
>Create Project</button>
|
||||
>
|
||||
Create Project
|
||||
</button>
|
||||
<div
|
||||
v-if="createProjectError"
|
||||
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,
|
||||
fetchRemoteSources,
|
||||
createProject,
|
||||
userRemoteRepos
|
||||
} from "@/util/data.js";
|
||||
userRemoteRepos,
|
||||
} 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 {
|
||||
components: { remoterepos },
|
||||
name: "createproject",
|
||||
name: 'createproject',
|
||||
props: {
|
||||
ownertype: String,
|
||||
ownername: String,
|
||||
projectgroupref: Array
|
||||
projectgroupref: Array,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -98,15 +116,15 @@ export default {
|
|||
remoteSources: null,
|
||||
remoteRepos: [],
|
||||
selectedRemoteSourceIndex: null,
|
||||
projectName: "",
|
||||
projectName: '',
|
||||
projectIsPrivate: false,
|
||||
remoteRepoPath: null
|
||||
remoteRepoPath: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
createProjectButtonEnabled: function() {
|
||||
createProjectButtonEnabled: function () {
|
||||
return this.projectName.length && this.remoteRepoPath;
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {},
|
||||
methods: {
|
||||
|
@ -143,7 +161,7 @@ export default {
|
|||
let { data, error } = await userRemoteRepos(remoteSource.id);
|
||||
this.stopFetchRemoteReposLoading();
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
this.$store.dispatch('setError', error);
|
||||
return;
|
||||
}
|
||||
this.remoteRepos = data;
|
||||
|
@ -155,11 +173,11 @@ export default {
|
|||
if (this.projectgroupref) {
|
||||
refArray = [...refArray, ...this.projectgroupref];
|
||||
}
|
||||
let parentref = refArray.join("/");
|
||||
let parentref = refArray.join('/');
|
||||
|
||||
let visibility = "public";
|
||||
let visibility = 'public';
|
||||
if (this.projectIsPrivate) {
|
||||
visibility = "private";
|
||||
visibility = 'private';
|
||||
}
|
||||
|
||||
let remoteSource = this.remoteSources[this.selectedRemoteSourceIndex];
|
||||
|
@ -186,12 +204,12 @@ export default {
|
|||
this.$router.push(
|
||||
projectLink(this.ownertype, this.ownername, projectref)
|
||||
);
|
||||
}
|
||||
},
|
||||
created: async function() {
|
||||
},
|
||||
created: async function () {
|
||||
let { data, error } = await fetchCurrentUser();
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
this.$store.dispatch('setError', error);
|
||||
return;
|
||||
}
|
||||
this.user = data;
|
||||
|
@ -199,7 +217,7 @@ export default {
|
|||
// TODO(sgotti) filter only remote source where the user has a linked account
|
||||
({ data, error } = await fetchRemoteSources());
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
this.$store.dispatch('setError', error);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -215,10 +233,8 @@ export default {
|
|||
}
|
||||
this.remoteSources = remoteSources;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
|
@ -5,9 +5,11 @@
|
|||
<button
|
||||
@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"
|
||||
>{{ buttonValue }}</button>
|
||||
>
|
||||
{{ buttonValue }}
|
||||
</button>
|
||||
<button
|
||||
v-click-outside="() => dropdownActive = false"
|
||||
v-click-outside="() => (dropdownActive = false)"
|
||||
@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"
|
||||
>
|
||||
|
@ -24,14 +26,16 @@
|
|||
href="#"
|
||||
class="block px-4 py-2 hover:bg-blue-500 hover:text-white"
|
||||
@click="setButton('project')"
|
||||
>New Project</a>
|
||||
>New Project</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="#"
|
||||
class="block px-4 py-2 hover:bg-blue-500 hover:text-white"
|
||||
@click="setButton('projectgroup')"
|
||||
>New Project Group</a>
|
||||
>New Project Group</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -40,28 +44,28 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import * as vClickOutside from "v-click-outside-x";
|
||||
import * as vClickOutside from 'v-click-outside-x';
|
||||
|
||||
export default {
|
||||
components: {},
|
||||
directives: {
|
||||
clickOutside: vClickOutside.directive
|
||||
clickOutside: vClickOutside.directive,
|
||||
},
|
||||
name: "createprojectbutton",
|
||||
name: 'createprojectbutton',
|
||||
props: {},
|
||||
data() {
|
||||
return {
|
||||
dropdownActive: false,
|
||||
type: "project"
|
||||
type: 'project',
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
buttonValue: function() {
|
||||
if (this.type == "project") {
|
||||
return "New Project";
|
||||
}
|
||||
return "New Project Group";
|
||||
buttonValue: function () {
|
||||
if (this.type == 'project') {
|
||||
return 'New Project';
|
||||
}
|
||||
return 'New Project Group';
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
setButton(type) {
|
||||
|
@ -69,12 +73,10 @@ export default {
|
|||
this.dropdownActive = false;
|
||||
},
|
||||
clicked() {
|
||||
this.$emit("click", this.type);
|
||||
}
|
||||
}
|
||||
this.$emit('click', this.type);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
|
@ -7,20 +7,22 @@
|
|||
type="text"
|
||||
placeholder="Project Group Name"
|
||||
v-model="projectGroupName"
|
||||
>
|
||||
/>
|
||||
<div class="mb-4">
|
||||
<label>
|
||||
<input type="checkbox" v-model="projectGroupIsPrivate">
|
||||
<input type="checkbox" v-model="projectGroupIsPrivate" />
|
||||
Private
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<button
|
||||
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"
|
||||
@click="createProjectGroup()"
|
||||
>Create ProjectGroup</button>
|
||||
>
|
||||
Create ProjectGroup
|
||||
</button>
|
||||
<div
|
||||
v-if="createProjectGroupError"
|
||||
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
||||
|
@ -32,31 +34,31 @@
|
|||
</template>
|
||||
|
||||
<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 {
|
||||
components: {},
|
||||
name: "createprojectgroup",
|
||||
name: 'createprojectgroup',
|
||||
props: {
|
||||
ownertype: String,
|
||||
ownername: String,
|
||||
projectgroupref: Array
|
||||
projectgroupref: Array,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
createProjectGroupError: null,
|
||||
createProjectGroupLoading: false,
|
||||
createProjectGroupLoadingTimeout: null,
|
||||
projectGroupName: "",
|
||||
projectGroupIsPrivate: false
|
||||
projectGroupName: '',
|
||||
projectGroupIsPrivate: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
createProjectGroupButtonEnabled: function() {
|
||||
createProjectGroupButtonEnabled: function () {
|
||||
return this.projectGroupName.length;
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
resetErrors() {
|
||||
|
@ -78,11 +80,11 @@ export default {
|
|||
if (this.projectgroupref) {
|
||||
refArray = [...refArray, ...this.projectgroupref];
|
||||
}
|
||||
let parentref = refArray.join("/");
|
||||
let parentref = refArray.join('/');
|
||||
|
||||
let visibility = "public";
|
||||
let visibility = 'public';
|
||||
if (this.projectGroupIsPrivate) {
|
||||
visibility = "private";
|
||||
visibility = 'private';
|
||||
}
|
||||
|
||||
this.startProjectGroupLoading();
|
||||
|
@ -104,12 +106,9 @@ export default {
|
|||
this.$router.push(
|
||||
projectGroupLink(this.ownertype, this.ownername, projectgroupref)
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
|
@ -12,17 +12,31 @@
|
|||
</h1>
|
||||
<form
|
||||
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">
|
||||
<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
|
||||
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||
id="token"
|
||||
type="password"
|
||||
placeholder="Agola Admin token"
|
||||
v-model="token"
|
||||
>
|
||||
/>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label class="block text-sm font-bold mb-2" for="type">Type</label>
|
||||
|
@ -37,7 +51,9 @@
|
|||
</select>
|
||||
</div>
|
||||
<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
|
||||
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||
id="name"
|
||||
|
@ -45,17 +61,19 @@
|
|||
type="text"
|
||||
placeholder="Source name (only numbers, letters and -)"
|
||||
v-model="name"
|
||||
>
|
||||
/>
|
||||
</div>
|
||||
<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
|
||||
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||
id="url"
|
||||
type="text"
|
||||
placeholder="API URL"
|
||||
v-model="url"
|
||||
>
|
||||
/>
|
||||
</div>
|
||||
<div class="mb-4 flex flex-row">
|
||||
<input
|
||||
|
@ -63,11 +81,15 @@
|
|||
type="checkbox"
|
||||
class="h-6 w-6 border border-gray-300 rounded-md checked:bg-blue-600 checked:border-transparent focus:outline-none"
|
||||
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 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
|
||||
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||
id="ssh_key"
|
||||
|
@ -75,7 +97,7 @@
|
|||
autocomplete="off"
|
||||
placeholder="Public SSH key"
|
||||
v-model="sshHostKey"
|
||||
>
|
||||
/>
|
||||
</div>
|
||||
<div class="mb-4 flex flex-row">
|
||||
<input
|
||||
|
@ -83,46 +105,53 @@
|
|||
type="checkbox"
|
||||
class="h-6 w-6 border border-gray-300 rounded-md checked:bg-blue-600 checked:border-transparent focus:outline-none"
|
||||
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 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
|
||||
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||
id="client_id"
|
||||
type="text"
|
||||
placeholder="Client ID"
|
||||
v-model="clientId"
|
||||
>
|
||||
/>
|
||||
</div>
|
||||
<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
|
||||
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||
id="client_secret"
|
||||
type="password"
|
||||
placeholder="Client secret"
|
||||
v-model="clientSecret"
|
||||
>
|
||||
/>
|
||||
</div>
|
||||
<div class="flex justify-center">
|
||||
<button
|
||||
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"
|
||||
>Create</button>
|
||||
>
|
||||
Create
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import { GITHUB_SSH_KEY, GITHUB_API_URL } from "@/util/data"
|
||||
import { GITHUB_SSH_KEY, GITHUB_API_URL } from '@/util/data';
|
||||
|
||||
export default {
|
||||
name: "CreateSourceForm",
|
||||
data: function() {
|
||||
name: 'CreateSourceForm',
|
||||
data: function () {
|
||||
return {
|
||||
name: null,
|
||||
token: null,
|
||||
|
@ -136,8 +165,8 @@ export default {
|
|||
};
|
||||
},
|
||||
watch: {
|
||||
type: function(value) {
|
||||
if (value === "github") {
|
||||
type: function (value) {
|
||||
if (value === 'github') {
|
||||
this.url = GITHUB_API_URL;
|
||||
this.sshHostKey = GITHUB_SSH_KEY;
|
||||
this.skipVerify = false;
|
||||
|
@ -147,5 +176,3 @@ export default {
|
|||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
|
|
|
@ -43,18 +43,18 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { apiurl, fetch } from "@/util/auth";
|
||||
import AnsiUp from "ansi_up";
|
||||
import { apiurl, fetch } from '@/util/auth';
|
||||
import AnsiUp from 'ansi_up';
|
||||
|
||||
export default {
|
||||
name: "Log",
|
||||
name: 'Log',
|
||||
props: {
|
||||
show: Boolean,
|
||||
runid: String,
|
||||
taskid: String,
|
||||
setup: Boolean,
|
||||
step: Number,
|
||||
stepphase: String
|
||||
stepphase: String,
|
||||
},
|
||||
computed: {},
|
||||
data() {
|
||||
|
@ -65,7 +65,7 @@ export default {
|
|||
fetchAbort: null,
|
||||
|
||||
items: [],
|
||||
lastitem: "",
|
||||
lastitem: '',
|
||||
lines: [],
|
||||
formatter: formatter,
|
||||
es: null,
|
||||
|
@ -73,7 +73,7 @@ export default {
|
|||
streaming: false,
|
||||
done: false,
|
||||
logExists: null,
|
||||
error: null
|
||||
error: null,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
|
@ -83,7 +83,7 @@ export default {
|
|||
}
|
||||
|
||||
let follow = false;
|
||||
if (this.stepphase == "running") {
|
||||
if (this.stepphase == 'running') {
|
||||
follow = true;
|
||||
}
|
||||
|
||||
|
@ -94,14 +94,14 @@ export default {
|
|||
this.logExists = 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) {
|
||||
path += "&setup";
|
||||
path += '&setup';
|
||||
} else {
|
||||
path += "&step=" + this.step;
|
||||
path += '&step=' + this.step;
|
||||
}
|
||||
if (follow) {
|
||||
path += "&follow";
|
||||
path += '&follow';
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -111,7 +111,7 @@ export default {
|
|||
this.streaming = true;
|
||||
const reader = res.body.getReader();
|
||||
|
||||
let lastline = "";
|
||||
let lastline = '';
|
||||
let j = 0;
|
||||
for (;;) {
|
||||
let { done, value } = await reader.read();
|
||||
|
@ -122,12 +122,12 @@ export default {
|
|||
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++) {
|
||||
let c = data.charAt(i);
|
||||
if (c == "\r") {
|
||||
if (c == '\r') {
|
||||
// replace lastline from start, simulating line feed (go to start of line)
|
||||
// this isn't perfect since the previous line contents could have
|
||||
// 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);
|
||||
j = 0;
|
||||
this.lastitem = this.formatter.ansi_to_html(lastline);
|
||||
part = "";
|
||||
} else if (c == "\n") {
|
||||
part = '';
|
||||
} else if (c == '\n') {
|
||||
lastline =
|
||||
lastline.slice(0, j) + part + lastline.slice(j + part.length);
|
||||
j += part.length;
|
||||
this.lastitem = this.formatter.ansi_to_html(lastline);
|
||||
this.items.push(this.lastitem);
|
||||
this.lastitem = "";
|
||||
lastline = "";
|
||||
this.lastitem = '';
|
||||
lastline = '';
|
||||
j = 0;
|
||||
part = "";
|
||||
part = '';
|
||||
} else {
|
||||
part += c;
|
||||
}
|
||||
|
@ -174,10 +174,10 @@ export default {
|
|||
this.fetchAbort.abort();
|
||||
}
|
||||
this.fetchAbort = new AbortController();
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
show: function(post, pre) {
|
||||
show: function (post, pre) {
|
||||
if (pre == false && post == true) {
|
||||
this.abortFetch();
|
||||
this.fetch();
|
||||
|
@ -186,23 +186,23 @@ export default {
|
|||
this.abortFetch();
|
||||
}
|
||||
},
|
||||
stepphase: function(post) {
|
||||
stepphase: function (post) {
|
||||
if (!this.show) {
|
||||
return;
|
||||
}
|
||||
if (this.fetching) {
|
||||
return;
|
||||
}
|
||||
if (post == "running") {
|
||||
if (post == 'running') {
|
||||
this.abortFetch();
|
||||
this.getLogs(true);
|
||||
} else {
|
||||
this.abortFetch();
|
||||
this.getLogs(false);
|
||||
}
|
||||
}
|
||||
},
|
||||
created: function() {
|
||||
},
|
||||
created: function () {
|
||||
this.fetchAbort = new AbortController();
|
||||
|
||||
if (this.show) {
|
||||
|
@ -217,6 +217,6 @@ export default {
|
|||
if (this.es !== null) {
|
||||
this.es.close();
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -5,50 +5,53 @@
|
|||
@submit.prevent="$emit('login', { username, password })"
|
||||
>
|
||||
<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
|
||||
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||
id="username"
|
||||
type="text"
|
||||
placeholder="Username"
|
||||
v-model="username"
|
||||
>
|
||||
/>
|
||||
</div>
|
||||
<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
|
||||
class="appearance-none border rounded w-full py-2 px-3 mb-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||
id="password"
|
||||
type="password"
|
||||
placeholder="******************"
|
||||
v-model="password"
|
||||
>
|
||||
/>
|
||||
</div>
|
||||
<div class="flex justify-center">
|
||||
<button
|
||||
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"
|
||||
>{{action}} with {{name}}</button>
|
||||
>
|
||||
{{ action }} with {{ name }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "LoginForm",
|
||||
name: 'LoginForm',
|
||||
props: {
|
||||
action: String,
|
||||
name: String
|
||||
name: String,
|
||||
},
|
||||
data: function() {
|
||||
data: function () {
|
||||
return {
|
||||
username: null,
|
||||
password: null
|
||||
password: null,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
<h4 class="mb-3 text-xl">Organization Members</h4>
|
||||
<ul v-if="members.length">
|
||||
<li class="flex" v-for="member in members" v-bind:key="member.user.id">
|
||||
<span class="w-1/2 font-bold">{{member.user.username}}</span>
|
||||
<span class="w-1/2">{{member.role}}</span>
|
||||
<span class="w-1/2 font-bold">{{ member.user.username }}</span>
|
||||
<span class="w-1/2">{{ member.role }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div v-else>No Members</div>
|
||||
|
@ -12,39 +12,38 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchOrgMembers } from "@/util/data.js";
|
||||
import { fetchOrgMembers } from '@/util/data.js';
|
||||
|
||||
export default {
|
||||
components: {},
|
||||
name: "orgmembers",
|
||||
name: 'orgmembers',
|
||||
props: {
|
||||
orgname: String
|
||||
orgname: String,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
members: []
|
||||
members: [],
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
$route: async function() {
|
||||
$route: async function () {
|
||||
this.fetchOrgMembers(this.orgname);
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async fetchOrgMembers(orgname) {
|
||||
let { data, error } = await fetchOrgMembers(orgname);
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
this.$store.dispatch('setError', error);
|
||||
return;
|
||||
}
|
||||
this.members = data.members;
|
||||
}
|
||||
},
|
||||
created: function() {
|
||||
},
|
||||
created: function () {
|
||||
this.fetchOrgMembers(this.orgname);
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
|
@ -2,57 +2,67 @@
|
|||
<nav class="mb-4 bg-grey-light rounded font-sans w-full">
|
||||
<ol class="list-reset flex text-grey-dark">
|
||||
<li>
|
||||
<a>{{ownertype}}</a>
|
||||
<a>{{ ownertype }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<span class="mx-2">/</span>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="ownerLink(ownertype, ownername)">{{ownername}}</router-link>
|
||||
<router-link :to="ownerLink(ownertype, ownername)">{{
|
||||
ownername
|
||||
}}</router-link>
|
||||
</li>
|
||||
<li v-for="(ref, i) in projectref" v-bind:key="i">
|
||||
<span class="mx-2">/</span>
|
||||
<router-link
|
||||
v-if="i+1 < projectref.length"
|
||||
:to="projectGroupLink(ownertype, ownername, projectref.slice(0, i+1))"
|
||||
>{{ref}}</router-link>
|
||||
v-if="i + 1 < projectref.length"
|
||||
:to="
|
||||
projectGroupLink(ownertype, ownername, projectref.slice(0, i + 1))
|
||||
"
|
||||
>{{ ref }}</router-link
|
||||
>
|
||||
<router-link
|
||||
v-else
|
||||
:to="projectLink(ownertype, ownername, projectref.slice(0, i+1))"
|
||||
>{{ref}}</router-link>
|
||||
:to="projectLink(ownertype, ownername, projectref.slice(0, i + 1))"
|
||||
>{{ ref }}</router-link
|
||||
>
|
||||
</li>
|
||||
|
||||
<li v-for="(ref, i) in projectgroupref" v-bind:key="i">
|
||||
<span class="mx-2">/</span>
|
||||
<router-link
|
||||
:to="projectGroupLink(ownertype, ownername, projectgroupref.slice(0, i+1))"
|
||||
>{{ref}}</router-link>
|
||||
:to="
|
||||
projectGroupLink(
|
||||
ownertype,
|
||||
ownername,
|
||||
projectgroupref.slice(0, i + 1)
|
||||
)
|
||||
"
|
||||
>{{ ref }}</router-link
|
||||
>
|
||||
</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import { ownerLink, projectLink, projectGroupLink } from "@/util/link.js";
|
||||
import { ownerLink, projectLink, projectGroupLink } from '@/util/link.js';
|
||||
|
||||
export default {
|
||||
name: "projbreadcrumbs",
|
||||
name: 'projbreadcrumbs',
|
||||
components: {},
|
||||
props: {
|
||||
ownertype: String,
|
||||
ownername: String,
|
||||
projectref: Array,
|
||||
projectgroupref: Array
|
||||
projectgroupref: Array,
|
||||
},
|
||||
methods: {
|
||||
ownerLink: ownerLink,
|
||||
projectLink: projectLink,
|
||||
projectGroupLink: projectGroupLink
|
||||
}
|
||||
projectGroupLink: projectGroupLink,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
|
@ -20,7 +20,9 @@
|
|||
Private
|
||||
</label>
|
||||
</div>
|
||||
<button class="btn btn-blue" @click="updateProjectGroup()">Update</button>
|
||||
<button class="btn btn-blue" @click="updateProjectGroup()">
|
||||
Update
|
||||
</button>
|
||||
|
||||
<div
|
||||
v-if="updateProjectGroupError"
|
||||
|
@ -35,14 +37,22 @@
|
|||
<div class="panel">
|
||||
<p class="panel-title">Secrets</p>
|
||||
<div class="p-4">
|
||||
<projectsecrets :secrets="secrets" :allsecrets="allsecrets" type="projectgroup" />
|
||||
<projectsecrets
|
||||
:secrets="secrets"
|
||||
:allsecrets="allsecrets"
|
||||
type="projectgroup"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<p class="panel-title">Variables</p>
|
||||
<div class="p-4">
|
||||
<projectvars :variables="variables" :allvariables="allvariables" type="projectgroup" />
|
||||
<projectvars
|
||||
:variables="variables"
|
||||
:allvariables="allvariables"
|
||||
type="projectgroup"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -56,16 +66,13 @@
|
|||
>
|
||||
<p>
|
||||
This operation
|
||||
<strong>CANNOT</strong> be undone.
|
||||
This operation will remove
|
||||
<strong>{{projectGroupPath}}</strong>
|
||||
<strong>CANNOT</strong> be undone. This operation will remove
|
||||
<strong>{{ projectGroupPath }}</strong>
|
||||
</p>
|
||||
</div>
|
||||
<label class="block mb-2">
|
||||
Please type the project group name for confirmation:
|
||||
<span
|
||||
class="text-red-500 font-bold"
|
||||
>{{ projectGroupName }}</span>
|
||||
<span class="text-red-500 font-bold">{{ projectGroupName }}</span>
|
||||
</label>
|
||||
<div class="mb-4">
|
||||
<input
|
||||
|
@ -79,7 +86,9 @@
|
|||
class="btn btn-red"
|
||||
@click="deleteProjectGroup()"
|
||||
:disabled="!deleteButtonEnabled"
|
||||
>Delete Project Group</button>
|
||||
>
|
||||
Delete Project Group
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
|
@ -98,21 +107,21 @@ import {
|
|||
fetchSecrets,
|
||||
fetchVariables,
|
||||
updateProjectGroup,
|
||||
deleteProjectGroup
|
||||
} from "@/util/data.js";
|
||||
deleteProjectGroup,
|
||||
} from '@/util/data.js';
|
||||
|
||||
import { projectGroupLink } from "@/util/link.js";
|
||||
import { projectGroupLink } from '@/util/link.js';
|
||||
|
||||
import projectsecrets from "@/components/projectsecrets";
|
||||
import projectvars from "@/components/projectvars";
|
||||
import projectsecrets from '@/components/projectsecrets';
|
||||
import projectvars from '@/components/projectvars';
|
||||
|
||||
export default {
|
||||
components: { projectsecrets, projectvars },
|
||||
name: "projectgroupsettings",
|
||||
name: 'projectgroupsettings',
|
||||
props: {
|
||||
ownertype: String,
|
||||
ownername: String,
|
||||
projectgroupref: Array
|
||||
projectgroupref: Array,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -124,24 +133,24 @@ export default {
|
|||
allsecrets: [],
|
||||
variables: [],
|
||||
allvariables: [],
|
||||
projectGroupNameToDelete: ""
|
||||
projectGroupNameToDelete: '',
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
projectGroupName: function() {
|
||||
projectGroupName: function () {
|
||||
return this.projectgroupref[this.projectgroupref.length - 1];
|
||||
},
|
||||
projectGroupPath: function() {
|
||||
return ["", this.ownertype, this.ownername, ...this.projectgroupref].join(
|
||||
"/"
|
||||
projectGroupPath: function () {
|
||||
return ['', this.ownertype, this.ownername, ...this.projectgroupref].join(
|
||||
'/'
|
||||
);
|
||||
},
|
||||
deleteButtonEnabled: function() {
|
||||
deleteButtonEnabled: function () {
|
||||
return this.projectGroupNameToDelete == this.projectGroupName;
|
||||
},
|
||||
isRootProjectGroup() {
|
||||
return this.projectgroupref.length == 0;
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
resetErrors() {
|
||||
|
@ -154,12 +163,12 @@ export default {
|
|||
let projectgroupref = [
|
||||
this.ownertype,
|
||||
this.ownername,
|
||||
...this.projectgroupref
|
||||
].join("/");
|
||||
...this.projectgroupref,
|
||||
].join('/');
|
||||
|
||||
let visibility = "public";
|
||||
let visibility = 'public';
|
||||
if (this.projectGroupIsPrivate) {
|
||||
visibility = "private";
|
||||
visibility = 'private';
|
||||
}
|
||||
let { error } = await updateProjectGroup(
|
||||
projectgroupref,
|
||||
|
@ -175,8 +184,8 @@ export default {
|
|||
let projectgroupref = [
|
||||
this.ownertype,
|
||||
this.ownername,
|
||||
...this.projectgroupref
|
||||
].join("/");
|
||||
...this.projectgroupref,
|
||||
].join('/');
|
||||
|
||||
if (this.projectGroupNameToDelete == this.projectGroupName) {
|
||||
let { error } = await deleteProjectGroup(projectgroupref);
|
||||
|
@ -192,70 +201,68 @@ export default {
|
|||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
created: async function() {
|
||||
},
|
||||
created: async function () {
|
||||
let projectgroupref = [
|
||||
this.ownertype,
|
||||
this.ownername,
|
||||
...this.projectgroupref
|
||||
].join("/");
|
||||
...this.projectgroupref,
|
||||
].join('/');
|
||||
|
||||
let { data, error } = await fetchProjectGroup(projectgroupref);
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
this.$store.dispatch('setError', error);
|
||||
return;
|
||||
}
|
||||
this.projectGroup = data;
|
||||
this.projectGroupIsPrivate = this.projectGroup.visibility == "private";
|
||||
this.projectGroupIsPrivate = this.projectGroup.visibility == 'private';
|
||||
|
||||
({ data, error } = await fetchSecrets(
|
||||
"projectgroup",
|
||||
'projectgroup',
|
||||
projectgroupref,
|
||||
false
|
||||
));
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
this.$store.dispatch('setError', error);
|
||||
return;
|
||||
}
|
||||
this.secrets = data;
|
||||
|
||||
({ data, error } = await fetchSecrets(
|
||||
"projectgroup",
|
||||
'projectgroup',
|
||||
projectgroupref,
|
||||
true
|
||||
));
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
this.$store.dispatch('setError', error);
|
||||
return;
|
||||
}
|
||||
this.allsecrets = data;
|
||||
|
||||
({ data, error } = await fetchVariables(
|
||||
"projectgroup",
|
||||
'projectgroup',
|
||||
projectgroupref,
|
||||
false
|
||||
));
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
this.$store.dispatch('setError', error);
|
||||
return;
|
||||
}
|
||||
this.variables = data;
|
||||
|
||||
({ data, error } = await fetchVariables(
|
||||
"projectgroup",
|
||||
'projectgroup',
|
||||
projectgroupref,
|
||||
true
|
||||
));
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
this.$store.dispatch('setError', error);
|
||||
return;
|
||||
}
|
||||
this.allvariables = data;
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
|
@ -2,13 +2,20 @@
|
|||
<div>
|
||||
<h4 class="text-xl my-3">Projects</h4>
|
||||
<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>
|
||||
<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">
|
||||
<router-link class="item" :to="projectLink(ownertype, ownername, ref(project.name))">
|
||||
<span class="font-bold">{{project.name}}</span>
|
||||
<router-link
|
||||
class="item"
|
||||
:to="projectLink(ownertype, ownername, ref(project.name))"
|
||||
>
|
||||
<span class="font-bold">{{ project.name }}</span>
|
||||
</router-link>
|
||||
</div>
|
||||
</li>
|
||||
|
@ -19,7 +26,7 @@
|
|||
|
||||
<h4 class="text-xl my-3">Project Groups</h4>
|
||||
<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>
|
||||
<ul v-else-if="projectgroups.length > 0">
|
||||
<li
|
||||
|
@ -32,7 +39,7 @@
|
|||
class="item"
|
||||
:to="projectGroupLink(ownertype, ownername, ref(projectgroup.name))"
|
||||
>
|
||||
<span class="font-bold">{{projectgroup.name}}</span>
|
||||
<span class="font-bold">{{ projectgroup.name }}</span>
|
||||
</router-link>
|
||||
</div>
|
||||
</li>
|
||||
|
@ -44,18 +51,18 @@
|
|||
<script>
|
||||
import {
|
||||
fetchProjectGroupProjects,
|
||||
fetchProjectGroupSubgroups
|
||||
} from "@/util/data.js";
|
||||
fetchProjectGroupSubgroups,
|
||||
} from '@/util/data.js';
|
||||
|
||||
import { projectLink, projectGroupLink } from "@/util/link.js";
|
||||
import { projectLink, projectGroupLink } from '@/util/link.js';
|
||||
|
||||
export default {
|
||||
components: {},
|
||||
name: "Projects",
|
||||
name: 'Projects',
|
||||
props: {
|
||||
ownertype: String,
|
||||
ownername: String,
|
||||
projectgroupref: Array
|
||||
projectgroupref: Array,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -65,18 +72,18 @@ export default {
|
|||
fetchProjectsLoading: false,
|
||||
|
||||
projects: [],
|
||||
projectgroups: []
|
||||
projectgroups: [],
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
$route: async function() {
|
||||
$route: async function () {
|
||||
if (this.fetchAbort) {
|
||||
this.fetchAbort.abort();
|
||||
}
|
||||
this.fetchAbort = new AbortController();
|
||||
this.fetchProjects(this.ownertype, this.ownername);
|
||||
this.fetchProjectGroups(this.ownertype, this.ownername);
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
startFetchProjectsLoading() {
|
||||
|
@ -107,7 +114,7 @@ export default {
|
|||
|
||||
this.startFetchProjectsLoading();
|
||||
let { data, error, aborted } = await fetchProjectGroupProjects(
|
||||
projectgroupref.join("/"),
|
||||
projectgroupref.join('/'),
|
||||
this.fetchAbort.signal
|
||||
);
|
||||
this.stopFetchProjectsLoading();
|
||||
|
@ -115,7 +122,7 @@ export default {
|
|||
return;
|
||||
}
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
this.$store.dispatch('setError', error);
|
||||
return;
|
||||
}
|
||||
this.projects = data;
|
||||
|
@ -127,7 +134,7 @@ export default {
|
|||
}
|
||||
this.startFetchProjectGroupsLoading();
|
||||
let { data, error, aborted } = await fetchProjectGroupSubgroups(
|
||||
projectgroupref.join("/"),
|
||||
projectgroupref.join('/'),
|
||||
this.fetchAbort.signal
|
||||
);
|
||||
this.stopFetchProjectGroupsLoading();
|
||||
|
@ -135,15 +142,15 @@ export default {
|
|||
return;
|
||||
}
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
this.$store.dispatch('setError', error);
|
||||
return;
|
||||
}
|
||||
this.projectgroups = data;
|
||||
},
|
||||
projectLink: projectLink,
|
||||
projectGroupLink: projectGroupLink
|
||||
projectGroupLink: projectGroupLink,
|
||||
},
|
||||
created: function() {
|
||||
created: function () {
|
||||
this.fetchAbort = new AbortController();
|
||||
this.fetchProjects(this.ownertype, this.ownername);
|
||||
this.fetchProjectGroups(this.ownertype, this.ownername);
|
||||
|
@ -152,9 +159,8 @@ export default {
|
|||
if (this.fetchAbort) {
|
||||
this.fetchAbort.abort();
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
|
@ -7,33 +7,34 @@
|
|||
<hr class="my-6 border-t" />
|
||||
|
||||
<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>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import secrets from "@/components/secrets";
|
||||
import secrets from '@/components/secrets';
|
||||
|
||||
export default {
|
||||
components: { secrets },
|
||||
name: "projectsecrets",
|
||||
name: 'projectsecrets',
|
||||
props: {
|
||||
secrets: Array,
|
||||
allsecrets: Array,
|
||||
type: String
|
||||
type: String,
|
||||
},
|
||||
computed: {
|
||||
typetitle() {
|
||||
if (this.type == "project") return "Project";
|
||||
if (this.type == "projectgroup") return "Project group";
|
||||
return "";
|
||||
}
|
||||
}
|
||||
if (this.type == 'project') return 'Project';
|
||||
if (this.type == 'projectgroup') return 'Project group';
|
||||
return '';
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
|
@ -21,7 +21,8 @@
|
|||
<div class="mb-4">
|
||||
<label class="checkbox">
|
||||
<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>
|
||||
</div>
|
||||
<button class="btn btn-blue" @click="updateProject()">Update</button>
|
||||
|
@ -38,14 +39,22 @@
|
|||
<div class="panel">
|
||||
<p class="panel-title">Secrets</p>
|
||||
<div class="p-4">
|
||||
<projectsecrets :secrets="secrets" :allsecrets="allsecrets" type="project" />
|
||||
<projectsecrets
|
||||
:secrets="secrets"
|
||||
:allsecrets="allsecrets"
|
||||
type="project"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<p class="panel-title">Variables</p>
|
||||
<div class="p-4">
|
||||
<projectvars :variables="variables" :allvariables="allvariables" type="project" />
|
||||
<projectvars
|
||||
:variables="variables"
|
||||
:allvariables="allvariables"
|
||||
type="project"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -59,16 +68,13 @@
|
|||
>
|
||||
<p>
|
||||
This operation
|
||||
<strong>CANNOT</strong> be undone.
|
||||
This operation will remove
|
||||
<strong>{{projectPath}}</strong>
|
||||
<strong>CANNOT</strong> be undone. This operation will remove
|
||||
<strong>{{ projectPath }}</strong>
|
||||
</p>
|
||||
</div>
|
||||
<label class="block mb-2">
|
||||
Please type the project name for confirmation:
|
||||
<span
|
||||
class="text-red-500 font-bold"
|
||||
>{{ projectName }}</span>
|
||||
<span class="text-red-500 font-bold">{{ projectName }}</span>
|
||||
</label>
|
||||
<div class="mb-4">
|
||||
<input
|
||||
|
@ -82,7 +88,9 @@
|
|||
class="btn btn-red"
|
||||
@click="deleteProject()"
|
||||
:disabled="!deleteButtonEnabled"
|
||||
>Delete Project</button>
|
||||
>
|
||||
Delete Project
|
||||
</button>
|
||||
|
||||
<div
|
||||
v-if="deleteProjectError"
|
||||
|
@ -93,21 +101,30 @@
|
|||
</div>
|
||||
</div>
|
||||
<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
|
||||
class="mb-4 bg-red-100 border-l-4 border-red-500 text-red-700 p-4 rounded"
|
||||
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>
|
||||
<button class="btn btn-red" @click="updateRepoLinkedAccount()">Change</button>
|
||||
<button class="btn btn-red" @click="updateRepoLinkedAccount()">
|
||||
Change
|
||||
</button>
|
||||
|
||||
<div
|
||||
v-if="updateRepoLinkedAccountError"
|
||||
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
||||
role="alert"
|
||||
>
|
||||
<span class="block sm:inline">{{ updateRepoLinkedAccountError }}</span>
|
||||
<span class="block sm:inline">{{
|
||||
updateRepoLinkedAccountError
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -121,21 +138,21 @@ import {
|
|||
fetchVariables,
|
||||
updateProject,
|
||||
deleteProject,
|
||||
projectUpdateRepoLinkedAccount
|
||||
} from "@/util/data.js";
|
||||
projectUpdateRepoLinkedAccount,
|
||||
} from '@/util/data.js';
|
||||
|
||||
import { projectGroupLink } from "@/util/link.js";
|
||||
import { projectGroupLink } from '@/util/link.js';
|
||||
|
||||
import projectsecrets from "@/components/projectsecrets";
|
||||
import projectvars from "@/components/projectvars";
|
||||
import projectsecrets from '@/components/projectsecrets';
|
||||
import projectvars from '@/components/projectvars';
|
||||
|
||||
export default {
|
||||
components: { projectsecrets, projectvars },
|
||||
name: "projectsettings",
|
||||
name: 'projectsettings',
|
||||
props: {
|
||||
ownertype: String,
|
||||
ownername: String,
|
||||
projectref: Array
|
||||
projectref: Array,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -148,19 +165,19 @@ export default {
|
|||
allsecrets: [],
|
||||
variables: [],
|
||||
allvariables: [],
|
||||
projectNameToDelete: ""
|
||||
projectNameToDelete: '',
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
projectName: function() {
|
||||
projectName: function () {
|
||||
return this.projectref[this.projectref.length - 1];
|
||||
},
|
||||
projectPath: function() {
|
||||
return ["", this.ownertype, this.ownername, ...this.projectref].join("/");
|
||||
projectPath: function () {
|
||||
return ['', this.ownertype, this.ownername, ...this.projectref].join('/');
|
||||
},
|
||||
deleteButtonEnabled: function() {
|
||||
deleteButtonEnabled: function () {
|
||||
return this.projectNameToDelete == this.projectName;
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
resetErrors() {
|
||||
|
@ -174,12 +191,12 @@ export default {
|
|||
let projectref = [
|
||||
this.ownertype,
|
||||
this.ownername,
|
||||
...this.projectref
|
||||
].join("/");
|
||||
...this.projectref,
|
||||
].join('/');
|
||||
|
||||
let visibility = "public";
|
||||
let visibility = 'public';
|
||||
if (this.projectIsPrivate) {
|
||||
visibility = "private";
|
||||
visibility = 'private';
|
||||
}
|
||||
let { error } = await updateProject(
|
||||
projectref,
|
||||
|
@ -198,8 +215,8 @@ export default {
|
|||
let projectref = [
|
||||
this.ownertype,
|
||||
this.ownername,
|
||||
...this.projectref
|
||||
].join("/");
|
||||
...this.projectref,
|
||||
].join('/');
|
||||
|
||||
if (this.projectNameToDelete == this.projectName) {
|
||||
let { error } = await deleteProject(projectref);
|
||||
|
@ -222,60 +239,59 @@ export default {
|
|||
let projectref = [
|
||||
this.ownertype,
|
||||
this.ownername,
|
||||
...this.projectref
|
||||
].join("/");
|
||||
...this.projectref,
|
||||
].join('/');
|
||||
|
||||
let { error } = await projectUpdateRepoLinkedAccount(projectref);
|
||||
if (error) {
|
||||
this.updateRepoLinkedAccountError = error;
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
created: async function() {
|
||||
},
|
||||
created: async function () {
|
||||
let projectref = [this.ownertype, this.ownername, ...this.projectref].join(
|
||||
"/"
|
||||
'/'
|
||||
);
|
||||
|
||||
let { data, error } = await fetchProject(projectref);
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
this.$store.dispatch('setError', error);
|
||||
return;
|
||||
}
|
||||
|
||||
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) {
|
||||
this.$store.dispatch("setError", error);
|
||||
this.$store.dispatch('setError', error);
|
||||
return;
|
||||
}
|
||||
this.secrets = data;
|
||||
|
||||
({ data, error } = await fetchSecrets("project", projectref, true));
|
||||
({ data, error } = await fetchSecrets('project', projectref, true));
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
this.$store.dispatch('setError', error);
|
||||
return;
|
||||
}
|
||||
this.allsecrets = data;
|
||||
|
||||
({ data, error } = await fetchVariables("project", projectref, false));
|
||||
({ data, error } = await fetchVariables('project', projectref, false));
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
this.$store.dispatch('setError', error);
|
||||
return;
|
||||
}
|
||||
this.variables = data;
|
||||
|
||||
({ data, error } = await fetchVariables("project", projectref, true));
|
||||
({ data, error } = await fetchVariables('project', projectref, true));
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
this.$store.dispatch('setError', error);
|
||||
return;
|
||||
}
|
||||
this.allvariables = data;
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
|
@ -7,32 +7,34 @@
|
|||
<hr class="my-6 border-t" />
|
||||
|
||||
<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>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import vars from "@/components/vars";
|
||||
import vars from '@/components/vars';
|
||||
|
||||
export default {
|
||||
components: { vars },
|
||||
name: "projectvars",
|
||||
name: 'projectvars',
|
||||
props: {
|
||||
variables: Array,
|
||||
allvariables: Array,
|
||||
type: String
|
||||
type: String,
|
||||
},
|
||||
computed: {
|
||||
typetitle() {
|
||||
if (this.type == "project") return "Project";
|
||||
if (this.type == "projectgroup") return "Project group";
|
||||
return "";
|
||||
}
|
||||
}
|
||||
if (this.type == 'project') return 'Project';
|
||||
if (this.type == 'projectgroup') return 'Project group';
|
||||
return '';
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
@submit.prevent="$emit('login', { username })"
|
||||
>
|
||||
<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
|
||||
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||
id="username"
|
||||
|
@ -13,38 +15,38 @@
|
|||
placeholder="Username"
|
||||
:disabled="true"
|
||||
v-model="remoteUsername"
|
||||
>
|
||||
/>
|
||||
</div>
|
||||
<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
|
||||
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||
id="username"
|
||||
type="text"
|
||||
placeholder="Username"
|
||||
v-model="username"
|
||||
>
|
||||
/>
|
||||
</div>
|
||||
<div class="flex justify-center">
|
||||
<button
|
||||
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"
|
||||
>Register</button>
|
||||
>
|
||||
Register
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "RegisterForm",
|
||||
name: 'RegisterForm',
|
||||
props: {
|
||||
remoteUsername: String,
|
||||
username: String
|
||||
}
|
||||
username: String,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
v-bind:key="repo.id"
|
||||
@click="select(index)"
|
||||
>
|
||||
<input type="radio" :checked="selectedrepo == index">
|
||||
{{repo.path}}
|
||||
<input type="radio" :checked="selectedrepo == index" />
|
||||
{{ repo.path }}
|
||||
</label>
|
||||
</div>
|
||||
<div v-else class="block px-4 py-2 border-b">No remote repositories</div>
|
||||
|
@ -18,23 +18,22 @@
|
|||
<script>
|
||||
export default {
|
||||
components: {},
|
||||
name: "remoterepos",
|
||||
name: 'remoterepos',
|
||||
props: {
|
||||
remoterepos: Array
|
||||
remoterepos: Array,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectedrepo: null
|
||||
selectedrepo: null,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
select(index) {
|
||||
this.selectedrepo = index;
|
||||
this.$emit("reposelected", this.remoterepos[index].path);
|
||||
}
|
||||
}
|
||||
this.$emit('reposelected', this.remoterepos[index].path);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
|
@ -27,21 +27,29 @@
|
|||
<div class="p-4 border border-l-0 rounded-r flex">
|
||||
<div class="w-4/6 items-start justify-between">
|
||||
<div class="flex items-center mb-1">
|
||||
<h2 class="text-2xl mr-3">{{run.name}}</h2>
|
||||
<h2 class="text-2xl mr-3">{{ run.name }}</h2>
|
||||
<span
|
||||
class="mr-3 rounded px-2 py-1 text-xs"
|
||||
:class="'is-' + runResultClass(run)"
|
||||
>{{ runStatus(run) | capitalize }}</span>
|
||||
>{{ runStatus(run) | capitalize }}</span
|
||||
>
|
||||
<span
|
||||
v-if="stillRunning(run)"
|
||||
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 class="mb-6">{{run.annotations.message.split(/\r?\n/)[0]}}</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>
|
||||
<span>{{run.annotations.commit_sha.substring(0,8)}}</span>
|
||||
<span>{{ run.annotations.commit_sha.substring(0, 8) }}</span>
|
||||
</a>
|
||||
<a
|
||||
v-if="run.annotations.ref_type == 'branch'"
|
||||
|
@ -50,7 +58,7 @@
|
|||
target="_blank"
|
||||
>
|
||||
<i class="mdi mdi-source-branch"></i>
|
||||
<span>{{run.annotations.branch}}</span>
|
||||
<span>{{ run.annotations.branch }}</span>
|
||||
</a>
|
||||
<a
|
||||
v-else-if="run.annotations.ref_type == 'tag'"
|
||||
|
@ -59,7 +67,7 @@
|
|||
target="_blank"
|
||||
>
|
||||
<i class="mdi mdi-tag"></i>
|
||||
<span>{{run.annotations.tag}}</span>
|
||||
<span>{{ run.annotations.tag }}</span>
|
||||
</a>
|
||||
<a
|
||||
v-else-if="run.annotations.ref_type == 'pull_request'"
|
||||
|
@ -68,7 +76,7 @@
|
|||
target="_blank"
|
||||
>
|
||||
<i class="mdi mdi-source-pull"></i>
|
||||
<span>PR #{{run.annotations.pull_request_id}}</span>
|
||||
<span>PR #{{ run.annotations.pull_request_id }}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -85,12 +93,18 @@
|
|||
<div class="w-1/6 flex items-start justify-between">
|
||||
<div class="relative ml-auto mr-3">
|
||||
<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"
|
||||
v-click-outside="() => dropdownActive = false"
|
||||
v-click-outside="() => (dropdownActive = false)"
|
||||
>
|
||||
<div class="flex items-center">
|
||||
<button class="btn btn-blue" @click="dropdownActive = !dropdownActive">
|
||||
<button
|
||||
class="btn btn-blue"
|
||||
@click="dropdownActive = !dropdownActive"
|
||||
>
|
||||
<span>Restart</span>
|
||||
<i class="ml-3 mdi mdi-restart" aria-hidden="true"></i>
|
||||
</button>
|
||||
|
@ -107,14 +121,16 @@
|
|||
v-if="run.can_restart_from_scratch"
|
||||
class="block px-4 py-2 hover:bg-blue-500 hover:text-white cursor-pointer"
|
||||
@click="restartRun(run.id, true)"
|
||||
>From start</a>
|
||||
>From start</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
v-if="run.can_restart_from_failed_tasks"
|
||||
class="block px-4 py-2 hover:bg-blue-500 hover:text-white cursor-pointer"
|
||||
@click="restartRun(run.id)"
|
||||
>From failed tasks</a>
|
||||
>From failed tasks</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -122,13 +138,17 @@
|
|||
class="btn btn-red"
|
||||
v-if="run.phase == 'queued'"
|
||||
@click="cancelRun(run.id)"
|
||||
>Cancel</button>
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-red"
|
||||
v-if="run.phase == 'running'"
|
||||
:disabled="run.stopping"
|
||||
@click="stopRun(run.id)"
|
||||
>Stop</button>
|
||||
>
|
||||
Stop
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -138,27 +158,27 @@
|
|||
</template>
|
||||
|
||||
<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 { userDirectRunLink, projectRunLink } from "@/util/link.js";
|
||||
import { runStatus, runResultClass } from "@/util/run.js";
|
||||
import { cancelRun, stopRun, restartRun } from '@/util/data.js';
|
||||
import { userDirectRunLink, projectRunLink } from '@/util/link.js';
|
||||
import { runStatus, runResultClass } from '@/util/run.js';
|
||||
|
||||
import * as moment from "moment";
|
||||
import momentDurationFormatSetup from "moment-duration-format";
|
||||
import * as moment from 'moment';
|
||||
import momentDurationFormatSetup from 'moment-duration-format';
|
||||
|
||||
momentDurationFormatSetup(moment);
|
||||
|
||||
export default {
|
||||
name: "rundetail",
|
||||
name: 'rundetail',
|
||||
directives: {
|
||||
clickOutside: vClickOutside.directive
|
||||
clickOutside: vClickOutside.directive,
|
||||
},
|
||||
props: {
|
||||
ownertype: String,
|
||||
ownername: String,
|
||||
projectref: Array,
|
||||
run: Object
|
||||
run: Object,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -166,7 +186,7 @@ export default {
|
|||
stopRunError: null,
|
||||
cancelRunError: null,
|
||||
restartRunError: null,
|
||||
dropdownActive: false
|
||||
dropdownActive: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
|
@ -178,14 +198,14 @@ export default {
|
|||
this.restartRunError = null;
|
||||
},
|
||||
stillRunning(run) {
|
||||
return run.result != "unknown" && run.phase == "running";
|
||||
return run.result != 'unknown' && run.phase == 'running';
|
||||
},
|
||||
taskClass(task) {
|
||||
if (task.status == "success") return "success";
|
||||
if (task.status == "failed") return "failed";
|
||||
if (task.status == "stopped") return "failed";
|
||||
if (task.status == "running") return "running";
|
||||
return "unknown";
|
||||
if (task.status == 'success') return 'success';
|
||||
if (task.status == 'failed') return 'failed';
|
||||
if (task.status == 'stopped') return 'failed';
|
||||
if (task.status == 'running') return 'running';
|
||||
return 'unknown';
|
||||
},
|
||||
async stopRun(runid) {
|
||||
this.resetErrors();
|
||||
|
@ -207,7 +227,7 @@ export default {
|
|||
return;
|
||||
}
|
||||
|
||||
this.run.phase = "cancelled";
|
||||
this.run.phase = 'cancelled';
|
||||
},
|
||||
async restartRun(runid, fromStart) {
|
||||
this.dropdownActive = false;
|
||||
|
@ -231,7 +251,7 @@ export default {
|
|||
this.$router.push(runLink);
|
||||
},
|
||||
duration(run) {
|
||||
let formatString = "h:mm:ss[s]";
|
||||
let formatString = 'h:mm:ss[s]';
|
||||
let start = moment(run.start_time);
|
||||
let end = moment(run.end_time);
|
||||
|
||||
|
@ -244,30 +264,29 @@ export default {
|
|||
return moment.duration(end.diff(start)).format(formatString);
|
||||
},
|
||||
endTime(run) {
|
||||
let formatString = "lll";
|
||||
let formatString = 'lll';
|
||||
let end = moment(run.end_time);
|
||||
|
||||
if (run.end_time === null) {
|
||||
return "";
|
||||
return '';
|
||||
}
|
||||
return "Finished " + end.format(formatString);
|
||||
return 'Finished ' + end.format(formatString);
|
||||
},
|
||||
endTimeHuman(run) {
|
||||
let end = moment(run.end_time);
|
||||
|
||||
if (run.end_time === null) {
|
||||
return "";
|
||||
return '';
|
||||
}
|
||||
return end.fromNow();
|
||||
}
|
||||
},
|
||||
created: function() {
|
||||
},
|
||||
created: function () {
|
||||
window.setInterval(() => {
|
||||
this.now = moment();
|
||||
}, 500);
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
</div>
|
||||
|
||||
<div class="ml-6 flex w-48">
|
||||
<div v-bind:class="{ 'spinner': fetchRunsLoading }"></div>
|
||||
<div v-bind:class="{ spinner: fetchRunsLoading }"></div>
|
||||
</div>
|
||||
<div v-if="runs">
|
||||
<ul>
|
||||
|
@ -27,21 +27,21 @@
|
|||
class="whitespace-no-wrap overflow-x-hidden"
|
||||
>
|
||||
<i class="mdi mdi-source-branch mr-1"></i>
|
||||
<span>{{run.annotations.branch}}</span>
|
||||
<span>{{ run.annotations.branch }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-else-if="run.annotations.ref_type == 'tag'"
|
||||
class="whitespace-no-wrap overflow-x-hidden"
|
||||
>
|
||||
<i class="mdi mdi-tag mr-1"></i>
|
||||
<span>{{run.annotations.tag}}</span>
|
||||
<span>{{ run.annotations.tag }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-else-if="run.annotations.ref_type == 'pull_request'"
|
||||
class="whitespace-no-wrap overflow-x-hidden"
|
||||
>
|
||||
<i class="mdi mdi-source-pull mr-1"></i>
|
||||
<span>PR #{{run.annotations.pull_request_id}}</span>
|
||||
<span>PR #{{ run.annotations.pull_request_id }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="w-2/12">
|
||||
|
@ -53,30 +53,36 @@
|
|||
class="w-5/12 pl-3 mr-auto whitespace-no-wrap overflow-hidden"
|
||||
:to="projectRunLink(ownertype, ownername, projectref, run.id)"
|
||||
>
|
||||
<span class="font-bold">{{run.name}}</span>
|
||||
<div>{{run.annotations.message.split(/\r?\n/)[0]}}</div>
|
||||
<span class="font-bold">{{ run.name }}</span>
|
||||
<div>{{ run.annotations.message.split(/\r?\n/)[0] }}</div>
|
||||
</router-link>
|
||||
<router-link
|
||||
v-else
|
||||
class="w-5/12 pl-3 mr-auto whitespace-no-wrap overflow-hidden"
|
||||
:to="userDirectRunLink(ownername, run.id)"
|
||||
>
|
||||
<span class="font-bold">{{run.name}}</span>
|
||||
<div>{{run.annotations.message.split(/\r?\n/)[0]}}</div>
|
||||
<span class="font-bold">{{ run.name }}</span>
|
||||
<div>{{ run.annotations.message.split(/\r?\n/)[0] }}</div>
|
||||
</router-link>
|
||||
<span
|
||||
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"
|
||||
>Waiting Approval</span>
|
||||
>Waiting Approval</span
|
||||
>
|
||||
<span
|
||||
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"
|
||||
>Still running</span>
|
||||
>Still running</span
|
||||
>
|
||||
<div class="w-32">
|
||||
<span>#{{run.counter}}</span>
|
||||
<a :href="run.annotations.commit_link" class="block" target="_blank">
|
||||
<span>#{{ run.counter }}</span>
|
||||
<a
|
||||
:href="run.annotations.commit_link"
|
||||
class="block"
|
||||
target="_blank"
|
||||
>
|
||||
<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>
|
||||
</div>
|
||||
<div class="w-32">
|
||||
|
@ -97,7 +103,9 @@
|
|||
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"
|
||||
@click="loadMoreRuns()"
|
||||
>Load more...</button>
|
||||
>
|
||||
Load more...
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="runs && runs.length == 0" class>No runs</div>
|
||||
|
@ -105,22 +113,22 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchUser, fetchProject, fetchRuns } from "@/util/data.js";
|
||||
import { userDirectRunLink, projectRunLink } from "@/util/link.js";
|
||||
import { runResultClass } from "@/util/run.js";
|
||||
import * as moment from "moment";
|
||||
import momentDurationFormatSetup from "moment-duration-format";
|
||||
import { fetchUser, fetchProject, fetchRuns } from '@/util/data.js';
|
||||
import { userDirectRunLink, projectRunLink } from '@/util/link.js';
|
||||
import { runResultClass } from '@/util/run.js';
|
||||
import * as moment from 'moment';
|
||||
import momentDurationFormatSetup from 'moment-duration-format';
|
||||
|
||||
momentDurationFormatSetup(moment);
|
||||
|
||||
export default {
|
||||
components: {},
|
||||
name: "runs",
|
||||
name: 'runs',
|
||||
props: {
|
||||
ownertype: String,
|
||||
ownername: String,
|
||||
projectref: Array,
|
||||
query: String
|
||||
query: String,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -137,15 +145,15 @@ export default {
|
|||
wantedRunsNumber: 25,
|
||||
hasMoreRuns: false,
|
||||
project: null,
|
||||
user: null
|
||||
user: null,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
$route: function() {
|
||||
$route: function () {
|
||||
this.runs = null;
|
||||
this.hasMoreRuns = false;
|
||||
this.update();
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
projectRunLink: projectRunLink,
|
||||
|
@ -161,7 +169,7 @@ export default {
|
|||
this.fetchRunsLoading = false;
|
||||
},
|
||||
stillRunning(run) {
|
||||
return run.result != "unknown" && run.phase == "running";
|
||||
return run.result != 'unknown' && run.phase == 'running';
|
||||
},
|
||||
waitingApproval(run) {
|
||||
return run.tasks_waiting_approval.length > 0;
|
||||
|
@ -183,8 +191,8 @@ export default {
|
|||
let projectref = [
|
||||
this.ownertype,
|
||||
this.ownername,
|
||||
...this.projectref
|
||||
].join("/");
|
||||
...this.projectref,
|
||||
].join('/');
|
||||
|
||||
let { data, error, aborted } = await fetchProject(
|
||||
projectref,
|
||||
|
@ -194,7 +202,7 @@ export default {
|
|||
return;
|
||||
}
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
this.$store.dispatch('setError', error);
|
||||
return;
|
||||
}
|
||||
this.project = data;
|
||||
|
@ -212,7 +220,7 @@ export default {
|
|||
return;
|
||||
}
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
this.$store.dispatch('setError', error);
|
||||
return;
|
||||
}
|
||||
this.user = data;
|
||||
|
@ -228,17 +236,17 @@ export default {
|
|||
let group;
|
||||
let lastrun = false;
|
||||
if (this.project !== null) {
|
||||
if (this.query == "branches") {
|
||||
group = "/project/" + this.project.id + "/branch";
|
||||
} else if (this.query == "tags") {
|
||||
group = "/project/" + this.project.id + "/tag";
|
||||
} else if (this.query == "pullrequests") {
|
||||
group = "/project/" + this.project.id + "/pr";
|
||||
if (this.query == 'branches') {
|
||||
group = '/project/' + this.project.id + '/branch';
|
||||
} else if (this.query == 'tags') {
|
||||
group = '/project/' + this.project.id + '/tag';
|
||||
} else if (this.query == 'pullrequests') {
|
||||
group = '/project/' + this.project.id + '/pr';
|
||||
} else {
|
||||
group = "/project/" + this.project.id;
|
||||
group = '/project/' + this.project.id;
|
||||
}
|
||||
} else if (this.user !== null) {
|
||||
group = "/user/" + this.user.id;
|
||||
group = '/user/' + this.user.id;
|
||||
}
|
||||
|
||||
let newRuns = [];
|
||||
|
@ -289,7 +297,7 @@ export default {
|
|||
}, 2000);
|
||||
},
|
||||
duration(run) {
|
||||
let formatString = "h:mm:ss[s]";
|
||||
let formatString = 'h:mm:ss[s]';
|
||||
let start = moment(run.start_time);
|
||||
let end = moment(run.end_time);
|
||||
|
||||
|
@ -302,24 +310,24 @@ export default {
|
|||
return moment.duration(end.diff(start)).format(formatString);
|
||||
},
|
||||
endTime(run) {
|
||||
let formatString = "lll";
|
||||
let formatString = 'lll';
|
||||
let end = moment(run.end_time);
|
||||
|
||||
if (run.end_time === null) {
|
||||
return "";
|
||||
return '';
|
||||
}
|
||||
return "Finished " + end.format(formatString);
|
||||
return 'Finished ' + end.format(formatString);
|
||||
},
|
||||
endTimeHuman(run) {
|
||||
let end = moment(run.end_time);
|
||||
|
||||
if (run.end_time === null) {
|
||||
return "";
|
||||
return '';
|
||||
}
|
||||
return end.fromNow();
|
||||
}
|
||||
},
|
||||
created: function() {
|
||||
},
|
||||
created: function () {
|
||||
window.setInterval(() => {
|
||||
this.now = moment();
|
||||
}, 500);
|
||||
|
@ -331,9 +339,8 @@ export default {
|
|||
this.fetchAbort.abort();
|
||||
}
|
||||
clearTimeout(this.fetchRunsSchedule);
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
|
@ -7,7 +7,12 @@
|
|||
>
|
||||
<div>{{ fetchRunError }}</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.phase != 'setuperror'">
|
||||
<div class="flex items-center my-6 justify-between">
|
||||
|
@ -17,7 +22,7 @@
|
|||
<button
|
||||
@click="tasksDisplay = 'graph'"
|
||||
class="relative flex items-center focus:outline-none bg-blue-500 hover:bg-blue-600 text-white font-semibold hover:text-white py-2 px-4 border border-blue-700 rounded rounded-r-none"
|
||||
:class="{ 'bg-blue-600': tasksDisplay=='graph'}"
|
||||
:class="{ 'bg-blue-600': tasksDisplay == 'graph' }"
|
||||
title="Tasks Graph"
|
||||
>
|
||||
<i class="mr-1 mdi mdi-file-tree" />
|
||||
|
@ -26,7 +31,7 @@
|
|||
@click="tasksDisplay = 'list'"
|
||||
class="relative flex items-center focus:outline-none bg-blue-500 hover:bg-blue-600 text-white font-semibold hover:text-white py-2 px-4 border border-l-0 border-blue-700 rounded rounded-l-none"
|
||||
title="Tasks List"
|
||||
:class="{ 'bg-blue-600': tasksDisplay=='list'}"
|
||||
:class="{ 'bg-blue-600': tasksDisplay == 'list' }"
|
||||
>
|
||||
<i class="mr-1 mdi mdi-format-list-bulleted-square" />
|
||||
</button>
|
||||
|
@ -42,7 +47,8 @@
|
|||
class="font-mono leading-snug text-xs"
|
||||
v-for="(error, i) in run.setup_errors"
|
||||
v-bind:key="i"
|
||||
>{{error}}</pre>
|
||||
>{{ error }}</pre
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -50,21 +56,21 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchRun } from "@/util/data.js";
|
||||
import { userDirectRunTaskLink, projectRunTaskLink } from "@/util/link.js";
|
||||
import { fetchRun } from '@/util/data.js';
|
||||
import { userDirectRunTaskLink, projectRunTaskLink } from '@/util/link.js';
|
||||
|
||||
import rundetail from "@/components/rundetail.vue";
|
||||
import tasks from "@/components/tasks.vue";
|
||||
import tasksgraph from "@/components/tasksgraph.vue";
|
||||
import rundetail from '@/components/rundetail.vue';
|
||||
import tasks from '@/components/tasks.vue';
|
||||
import tasksgraph from '@/components/tasksgraph.vue';
|
||||
|
||||
export default {
|
||||
name: "runsummary",
|
||||
name: 'runsummary',
|
||||
components: { rundetail, tasks, tasksgraph },
|
||||
props: {
|
||||
ownertype: String,
|
||||
ownername: String,
|
||||
projectref: Array,
|
||||
runid: String
|
||||
runid: String,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -80,11 +86,11 @@ export default {
|
|||
taskYSpace: 20,
|
||||
hoverTask: null,
|
||||
|
||||
tasksDisplay: "graph"
|
||||
tasksDisplay: 'graph',
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
$route: async function() {
|
||||
$route: async function () {
|
||||
if (this.fetchAbort) {
|
||||
this.fetchAbort.abort();
|
||||
}
|
||||
|
@ -93,7 +99,7 @@ export default {
|
|||
this.fetchAbort = new AbortController();
|
||||
|
||||
this.fetchRun();
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
runTaskLink(task) {
|
||||
|
@ -110,16 +116,16 @@ export default {
|
|||
}
|
||||
},
|
||||
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;
|
||||
});
|
||||
},
|
||||
taskClass(task) {
|
||||
if (task.status == "success") return "success";
|
||||
if (task.status == "failed") return "failed";
|
||||
if (task.status == "stopped") return "failed";
|
||||
if (task.status == "running") return "running";
|
||||
return "unknown";
|
||||
if (task.status == 'success') return 'success';
|
||||
if (task.status == 'failed') return 'failed';
|
||||
if (task.status == 'stopped') return 'failed';
|
||||
if (task.status == 'running') return 'running';
|
||||
return 'unknown';
|
||||
},
|
||||
async fetchRun() {
|
||||
let { data, error, aborted } = await fetchRun(
|
||||
|
@ -145,9 +151,8 @@ export default {
|
|||
let task = tasks[taskID];
|
||||
task.link = this.runTaskLink(task);
|
||||
task.parents = this.parents(task);
|
||||
task.waiting_approval = this.run.tasks_waiting_approval.includes(
|
||||
taskID
|
||||
);
|
||||
task.waiting_approval =
|
||||
this.run.tasks_waiting_approval.includes(taskID);
|
||||
}
|
||||
|
||||
this.scheduleFetchRun();
|
||||
|
@ -157,9 +162,9 @@ export default {
|
|||
this.fetchRunSchedule = setTimeout(() => {
|
||||
this.fetchRun();
|
||||
}, 2000);
|
||||
}
|
||||
},
|
||||
created: function() {
|
||||
},
|
||||
created: function () {
|
||||
this.fetchAbort = new AbortController();
|
||||
this.fetchRun();
|
||||
},
|
||||
|
@ -168,9 +173,8 @@ export default {
|
|||
this.fetchAbort.abort();
|
||||
}
|
||||
clearTimeout(this.fetchRunSchedule);
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
|
@ -5,8 +5,10 @@
|
|||
</div>
|
||||
<div class="flex" v-for="secret in secrets" v-bind:key="secret.id">
|
||||
<div class="w-2/12">
|
||||
<span class="name">{{secret.name}}</span>
|
||||
<div v-if="showparentpath" class="text-sm font-light">from {{secret.parent_path}}</div>
|
||||
<span class="name">{{ secret.name }}</span>
|
||||
<div v-if="showparentpath" class="text-sm font-light">
|
||||
from {{ secret.parent_path }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -15,16 +17,12 @@
|
|||
<script>
|
||||
export default {
|
||||
components: {},
|
||||
name: "secrets",
|
||||
name: 'secrets',
|
||||
props: {
|
||||
secrets: Array,
|
||||
showparentpath: Boolean
|
||||
}
|
||||
showparentpath: Boolean,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
class="inline-block mr-1 mdi mdi-arrow-right"
|
||||
:class="{ 'arrow-down': active, 'arrow-right': !active }"
|
||||
></i>
|
||||
<span class="w-1/3 font-bold">{{step.name}}</span>
|
||||
<span class="w-1/3 font-bold">{{ step.name }}</span>
|
||||
</div>
|
||||
<span class>{{ duration }}</span>
|
||||
</div>
|
||||
|
@ -20,18 +20,24 @@
|
|||
<div v-if="step.type == 'run'">
|
||||
<div class="p-3 rounded-t bg-gray-900 text-white">
|
||||
<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
|
||||
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 v-if="step.exit_status != undefined">
|
||||
<span
|
||||
class="w-2/12 bg-gray-700 rounded-l px-3 py-1 text-center font-semibold"
|
||||
>Exit Status</span>
|
||||
>Exit Status</span
|
||||
>
|
||||
<span
|
||||
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>
|
||||
</div>
|
||||
<div
|
||||
|
@ -40,22 +46,27 @@
|
|||
>
|
||||
<i
|
||||
class="inline-block mr-1 mdi mdi-arrow-right"
|
||||
:class="{ 'arrow-down': commandActive, 'arrow-right': !commandActive }"
|
||||
:class="{
|
||||
'arrow-down': commandActive,
|
||||
'arrow-right': !commandActive,
|
||||
}"
|
||||
></i>
|
||||
<span>Command</span>
|
||||
</div>
|
||||
<div
|
||||
v-show="commandActive"
|
||||
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 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
|
||||
class="p-3 rounded-b bg-gray-900 text-white"
|
||||
:class="{ 'rounded': step.type != 'run' }"
|
||||
:class="{ rounded: step.type != 'run' }"
|
||||
>
|
||||
<Log
|
||||
v-bind:runid="runid"
|
||||
|
@ -72,22 +83,22 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import * as moment from "moment";
|
||||
import momentDurationFormatSetup from "moment-duration-format";
|
||||
import Log from "@/components/log.vue";
|
||||
import * as moment from 'moment';
|
||||
import momentDurationFormatSetup from 'moment-duration-format';
|
||||
import Log from '@/components/log.vue';
|
||||
|
||||
momentDurationFormatSetup(moment);
|
||||
|
||||
export default {
|
||||
name: "step",
|
||||
name: 'step',
|
||||
components: {
|
||||
Log
|
||||
Log,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
active: false,
|
||||
commandActive: true,
|
||||
now: moment()
|
||||
now: moment(),
|
||||
};
|
||||
},
|
||||
props: {
|
||||
|
@ -95,11 +106,11 @@ export default {
|
|||
taskid: String,
|
||||
setup: Boolean,
|
||||
stepnum: Number,
|
||||
step: Object
|
||||
step: Object,
|
||||
},
|
||||
computed: {
|
||||
duration() {
|
||||
let formatString = "h:mm:ss[s]";
|
||||
let formatString = 'h:mm:ss[s]';
|
||||
let start = moment(this.step.start_time);
|
||||
let end = moment(this.step.end_time);
|
||||
|
||||
|
@ -112,12 +123,12 @@ export default {
|
|||
return moment.duration(end.diff(start)).format(formatString);
|
||||
},
|
||||
stepClass() {
|
||||
if (this.step.phase == "success") return "success";
|
||||
if (this.step.phase == "failed") return "failed";
|
||||
if (this.step.phase == "stopped") return "failed";
|
||||
if (this.step.phase == "running") return "running";
|
||||
return "unknown";
|
||||
}
|
||||
if (this.step.phase == 'success') return 'success';
|
||||
if (this.step.phase == 'failed') return 'failed';
|
||||
if (this.step.phase == 'stopped') return 'failed';
|
||||
if (this.step.phase == 'running') return 'running';
|
||||
return 'unknown';
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
toggle() {
|
||||
|
@ -125,13 +136,13 @@ export default {
|
|||
},
|
||||
toggleCommand() {
|
||||
this.commandActive = !this.commandActive;
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
window.setInterval(() => {
|
||||
this.now = moment();
|
||||
}, 500);
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
<template>
|
||||
<div class="arrow">
|
||||
<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>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "tabarrow"
|
||||
name: 'tabarrow',
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -2,24 +2,31 @@
|
|||
<ul>
|
||||
<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="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">
|
||||
<span class="w-1/3 font-bold">{{task.name}}</span>
|
||||
<span class="w-1/3 font-bold">{{ task.name }}</span>
|
||||
</router-link>
|
||||
<div class="w-1/4">
|
||||
<span
|
||||
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"
|
||||
>Waiting Approval</span>
|
||||
>Waiting Approval</span
|
||||
>
|
||||
</div>
|
||||
<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>
|
||||
<li
|
||||
class="font-thin text-xs text-gray-600"
|
||||
v-for="dep in task.parents"
|
||||
v-bind:key="dep"
|
||||
>{{dep}}</li>
|
||||
>
|
||||
{{ dep }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<span class="w-16 text-right">{{ task.duration }}</span>
|
||||
|
@ -30,21 +37,21 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import * as moment from "moment";
|
||||
import momentDurationFormatSetup from "moment-duration-format";
|
||||
import * as moment from 'moment';
|
||||
import momentDurationFormatSetup from 'moment-duration-format';
|
||||
|
||||
momentDurationFormatSetup(moment);
|
||||
|
||||
export default {
|
||||
name: "tasks",
|
||||
name: 'tasks',
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
now: moment()
|
||||
now: moment(),
|
||||
};
|
||||
},
|
||||
props: {
|
||||
tasks: Object
|
||||
tasks: Object,
|
||||
},
|
||||
computed: {
|
||||
sortedTasks() {
|
||||
|
@ -59,18 +66,18 @@ export default {
|
|||
? -1
|
||||
: 0
|
||||
)
|
||||
.map(k => tasks[k]);
|
||||
.map((k) => tasks[k]);
|
||||
|
||||
for (let task of sortedTasks) {
|
||||
task.duration = this.duration(task);
|
||||
}
|
||||
|
||||
return sortedTasks;
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
duration(task) {
|
||||
let formatString = "h:mm:ss[s]";
|
||||
let formatString = 'h:mm:ss[s]';
|
||||
let start = moment(task.start_time);
|
||||
let end = moment(task.end_time);
|
||||
|
||||
|
@ -83,18 +90,18 @@ export default {
|
|||
return moment.duration(end.diff(start)).format(formatString);
|
||||
},
|
||||
taskClass(task) {
|
||||
if (task.status == "success") return "success";
|
||||
if (task.status == "failed") return "failed";
|
||||
if (task.status == "stopped") return "failed";
|
||||
if (task.status == "running") return "running";
|
||||
if (task.status == "skipped") return "skipped";
|
||||
return "unknown";
|
||||
}
|
||||
if (task.status == 'success') return 'success';
|
||||
if (task.status == 'failed') return 'failed';
|
||||
if (task.status == 'stopped') return 'failed';
|
||||
if (task.status == 'running') return 'running';
|
||||
if (task.status == 'skipped') return 'skipped';
|
||||
return 'unknown';
|
||||
},
|
||||
},
|
||||
created() {
|
||||
window.setInterval(() => {
|
||||
this.now = moment();
|
||||
}, 500);
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -64,13 +64,13 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import * as moment from "moment";
|
||||
import momentDurationFormatSetup from "moment-duration-format";
|
||||
import * as moment from 'moment';
|
||||
import momentDurationFormatSetup from 'moment-duration-format';
|
||||
|
||||
momentDurationFormatSetup(moment);
|
||||
|
||||
export default {
|
||||
name: "tasksgraph",
|
||||
name: 'tasksgraph',
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
|
@ -85,14 +85,14 @@ export default {
|
|||
taskYSpace: 20,
|
||||
hoverTask: null,
|
||||
|
||||
height: "400px"
|
||||
height: '400px',
|
||||
};
|
||||
},
|
||||
props: {
|
||||
tasks: Object
|
||||
tasks: Object,
|
||||
},
|
||||
computed: {
|
||||
segments: function() {
|
||||
segments: function () {
|
||||
let segments = [];
|
||||
for (let edge of this.edges) {
|
||||
for (let i = 0; i < edge.edgePoints.length - 1; i++) {
|
||||
|
@ -107,7 +107,7 @@ export default {
|
|||
}
|
||||
|
||||
// TODO(sgotti) set different colors to edges based on source task status???
|
||||
let stroke = "text-dark";
|
||||
let stroke = 'text-dark';
|
||||
segments.push({
|
||||
edge: edge,
|
||||
x1: edge.edgePoints[i].x,
|
||||
|
@ -115,7 +115,7 @@ export default {
|
|||
x2: edge.edgePoints[i + 1].x,
|
||||
y2: edge.edgePoints[i + 1].y,
|
||||
strokeWidth: strokeWidth,
|
||||
stroke: stroke
|
||||
stroke: stroke,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -130,16 +130,16 @@ export default {
|
|||
}
|
||||
|
||||
return this.graphTasks;
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
tasks: function(tasks) {
|
||||
tasks: function (tasks) {
|
||||
this.update(tasks);
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
duration(task) {
|
||||
let formatString = "h:mm:ss[s]";
|
||||
let formatString = 'h:mm:ss[s]';
|
||||
let start = moment(task.start_time);
|
||||
let end = moment(task.end_time);
|
||||
|
||||
|
@ -152,12 +152,12 @@ export default {
|
|||
return moment.duration(end.diff(start)).format(formatString);
|
||||
},
|
||||
taskClass(task) {
|
||||
if (task.status == "success") return "success";
|
||||
if (task.status == "failed") return "failed";
|
||||
if (task.status == "stopped") return "failed";
|
||||
if (task.status == "running") return "running";
|
||||
if (task.status == "skipped") return "skipped";
|
||||
return "unknown";
|
||||
if (task.status == 'success') return 'success';
|
||||
if (task.status == 'failed') return 'failed';
|
||||
if (task.status == 'stopped') return 'failed';
|
||||
if (task.status == 'running') return 'running';
|
||||
if (task.status == 'skipped') return 'skipped';
|
||||
return 'unknown';
|
||||
},
|
||||
update(tasks) {
|
||||
// sort tasks by level
|
||||
|
@ -169,7 +169,7 @@ export default {
|
|||
? -1
|
||||
: 0
|
||||
)
|
||||
.map(k => tasks[k]);
|
||||
.map((k) => tasks[k]);
|
||||
|
||||
this.graphTasks = graphTasks;
|
||||
|
||||
|
@ -180,7 +180,7 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
let taskChilds = function(tasks, task) {
|
||||
let taskChilds = function (tasks, task) {
|
||||
let childs = [];
|
||||
for (let ot of tasks) {
|
||||
for (let depTaskID in ot.depends) {
|
||||
|
@ -192,7 +192,7 @@ export default {
|
|||
return childs;
|
||||
};
|
||||
|
||||
let taskMaxChildLevel = function(tasks, task) {
|
||||
let taskMaxChildLevel = function (tasks, task) {
|
||||
let level = task.level;
|
||||
let childs = taskChilds(tasks, task);
|
||||
for (let child of childs) {
|
||||
|
@ -203,7 +203,7 @@ export default {
|
|||
return level;
|
||||
};
|
||||
|
||||
let levelTasks = function(tasks, level) {
|
||||
let levelTasks = function (tasks, level) {
|
||||
let levelTasks = [];
|
||||
for (let task of tasks) {
|
||||
if (task.level != level) {
|
||||
|
@ -214,7 +214,7 @@ export default {
|
|||
return levelTasks;
|
||||
};
|
||||
|
||||
let levelsTasks = function(tasks, startLevel) {
|
||||
let levelsTasks = function (tasks, startLevel) {
|
||||
let levelTasks = [];
|
||||
for (let task of tasks) {
|
||||
if (task.level < startLevel) {
|
||||
|
@ -225,13 +225,13 @@ export default {
|
|||
return levelTasks;
|
||||
};
|
||||
|
||||
let levelsTasksByRow = function(tasks, startLevel) {
|
||||
let levelsTasksByRow = function (tasks, startLevel) {
|
||||
return levelsTasks(tasks, startLevel).sort((a, b) =>
|
||||
a.row > b.row ? 1 : b.row > a.row ? -1 : 0
|
||||
);
|
||||
};
|
||||
|
||||
let levelFreeRow = function(tasks, level) {
|
||||
let levelFreeRow = function (tasks, level) {
|
||||
let rows = [];
|
||||
for (let task of tasks) {
|
||||
if (task.level != level) {
|
||||
|
@ -255,7 +255,7 @@ export default {
|
|||
return prevrow;
|
||||
};
|
||||
|
||||
let levelsMaxRow = function(tasks, level) {
|
||||
let levelsMaxRow = function (tasks, level) {
|
||||
let row = 0;
|
||||
for (let task of tasks) {
|
||||
if (level >= 0 && task.level > level) {
|
||||
|
@ -344,7 +344,7 @@ export default {
|
|||
sourceTask: pTask,
|
||||
targetTask: curTask,
|
||||
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({
|
||||
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({
|
||||
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({
|
||||
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({
|
||||
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);
|
||||
this.width = width + "px";
|
||||
this.width = width + 'px';
|
||||
|
||||
let height =
|
||||
(levelsMaxRow(graphTasks, -1) + 1) *
|
||||
(this.taskHeight + this.taskYSpace);
|
||||
this.height = height + "px";
|
||||
}
|
||||
this.height = height + 'px';
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.update(this.tasks);
|
||||
|
@ -393,6 +393,6 @@ export default {
|
|||
window.setInterval(() => {
|
||||
this.now = moment();
|
||||
}, 500);
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -8,22 +8,30 @@
|
|||
<div>Error fetching Run: {{ fetchRunError }}</div>
|
||||
<div>Error fetching Task: {{ fetchTaskError }}</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 class="mt-8 mb-4 flex justify-between items-center">
|
||||
<div class="flex items-center">
|
||||
<span class="text-2xl mr-3">{{task.name}}</span>
|
||||
<span class="text-2xl mr-3">{{ task.name }}</span>
|
||||
|
||||
<span
|
||||
class="mr-3 rounded px-2 py-1 text-xs"
|
||||
:class="taskClass(task)"
|
||||
>{{ task.status | capitalize }}</span>
|
||||
>{{ task.status | capitalize }}</span
|
||||
>
|
||||
</div>
|
||||
<button
|
||||
v-if="task.waiting_approval"
|
||||
class="btn btn-blue"
|
||||
@click="approveTask(run.id, task.id)"
|
||||
>Approve</button>
|
||||
>
|
||||
Approve
|
||||
</button>
|
||||
</div>
|
||||
<step
|
||||
v-bind:runid="runid"
|
||||
|
@ -44,23 +52,23 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchRun, fetchTask, approveTask } from "@/util/data.js";
|
||||
import { fetchRun, fetchTask, approveTask } from '@/util/data.js';
|
||||
|
||||
import step from "@/components/step.vue";
|
||||
import rundetail from "@/components/rundetail.vue";
|
||||
import step from '@/components/step.vue';
|
||||
import rundetail from '@/components/rundetail.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
step,
|
||||
rundetail
|
||||
rundetail,
|
||||
},
|
||||
name: "tasksummary",
|
||||
name: 'tasksummary',
|
||||
props: {
|
||||
ownertype: String,
|
||||
ownername: String,
|
||||
projectref: Array,
|
||||
runid: String,
|
||||
taskid: String
|
||||
taskid: String,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -70,11 +78,11 @@ export default {
|
|||
fetchTaskError: null,
|
||||
|
||||
run: null,
|
||||
task: null
|
||||
task: null,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
$route: async function() {
|
||||
$route: async function () {
|
||||
if (this.fetchAbort) {
|
||||
this.fetchAbort.abort();
|
||||
}
|
||||
|
@ -85,16 +93,16 @@ export default {
|
|||
|
||||
this.fetchRun();
|
||||
this.fetchTask();
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
taskClass(task) {
|
||||
if (task.status == "success") return "is-success";
|
||||
if (task.status == "failed") return "is-failed";
|
||||
if (task.status == "stopped") return "is-failed";
|
||||
if (task.status == "running") return "is-running";
|
||||
if (task.status == "skipped") return "is-skipped";
|
||||
return "unknown";
|
||||
if (task.status == 'success') return 'is-success';
|
||||
if (task.status == 'failed') return 'is-failed';
|
||||
if (task.status == 'stopped') return 'is-failed';
|
||||
if (task.status == 'running') return 'is-running';
|
||||
if (task.status == 'skipped') return 'is-skipped';
|
||||
return 'unknown';
|
||||
},
|
||||
async fetchRun() {
|
||||
let { data, error, aborted } = await fetchRun(
|
||||
|
@ -143,9 +151,9 @@ export default {
|
|||
this.fetchTask();
|
||||
}, 2000);
|
||||
},
|
||||
approveTask: approveTask
|
||||
approveTask: approveTask,
|
||||
},
|
||||
created: function() {
|
||||
created: function () {
|
||||
this.fetchAbort = new AbortController();
|
||||
|
||||
this.fetchRun();
|
||||
|
@ -157,9 +165,8 @@ export default {
|
|||
}
|
||||
clearTimeout(this.fetchRunSchedule);
|
||||
clearTimeout(this.fetchTaskSchedule);
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
|
@ -7,7 +7,10 @@
|
|||
class="mb-4 bg-red-100 border-l-4 border-red-500 text-red-700 p-4 rounded"
|
||||
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>
|
||||
<ul v-if="user.linked_accounts">
|
||||
<li
|
||||
|
@ -16,10 +19,14 @@
|
|||
v-bind:key="index"
|
||||
>
|
||||
<div>
|
||||
<span class="font-bold">{{la.remote_user_name}}</span>
|
||||
<span class="ml-1">(on remote source {{laRemoteSourceName(la)}})</span>
|
||||
<span class="font-bold">{{ la.remote_user_name }}</span>
|
||||
<span class="ml-1"
|
||||
>(on remote source {{ laRemoteSourceName(la) }})</span
|
||||
>
|
||||
</div>
|
||||
<button class="btn btn-red" @click="deleteLinkedAccount(la)">Delete</button>
|
||||
<button class="btn btn-red" @click="deleteLinkedAccount(la)">
|
||||
Delete
|
||||
</button>
|
||||
</li>
|
||||
<div
|
||||
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"
|
||||
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>
|
||||
<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
|
||||
class="fill-current h-4 w-4"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
@ -56,7 +67,9 @@
|
|||
</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>
|
||||
|
||||
|
@ -69,8 +82,10 @@
|
|||
v-for="token in user.tokens"
|
||||
v-bind:key="token"
|
||||
>
|
||||
<span class="font-bold">{{token}}</span>
|
||||
<button class="btn btn-red" @click="deleteUserToken(token)">Delete</button>
|
||||
<span class="font-bold">{{ token }}</span>
|
||||
<button class="btn btn-red" @click="deleteUserToken(token)">
|
||||
Delete
|
||||
</button>
|
||||
</li>
|
||||
<div
|
||||
v-if="deleteUserTokenError"
|
||||
|
@ -102,8 +117,10 @@
|
|||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<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="font-bold">
|
||||
User token created. Copy it now since it won't be showed again
|
||||
</p>
|
||||
<p class="text-sm">{{ token }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
|
@ -130,8 +147,10 @@
|
|||
type="text"
|
||||
placeholder="Token name"
|
||||
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
|
||||
v-if="createUserTokenError"
|
||||
|
@ -151,14 +170,14 @@ import {
|
|||
fetchRemoteSources,
|
||||
createUserToken,
|
||||
deleteUserToken,
|
||||
deleteLinkedAccount
|
||||
} from "@/util/data.js";
|
||||
deleteLinkedAccount,
|
||||
} from '@/util/data.js';
|
||||
|
||||
import { userAddLinkedAccountLink } from "@/util/link.js";
|
||||
import { userAddLinkedAccountLink } from '@/util/link.js';
|
||||
|
||||
export default {
|
||||
components: {},
|
||||
name: "usersettings",
|
||||
name: 'usersettings',
|
||||
props: {},
|
||||
data() {
|
||||
return {
|
||||
|
@ -169,7 +188,7 @@ export default {
|
|||
remotesources: [],
|
||||
token: null,
|
||||
newtokenname: null,
|
||||
selectedRemoteSourceName: null
|
||||
selectedRemoteSourceName: null,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
|
@ -181,7 +200,7 @@ export default {
|
|||
async fetchCurrentUser() {
|
||||
let { data, error } = await fetchCurrentUser();
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
this.$store.dispatch('setError', error);
|
||||
return;
|
||||
}
|
||||
this.user = data;
|
||||
|
@ -189,7 +208,7 @@ export default {
|
|||
async fetchRemoteSources() {
|
||||
let { data, error } = await fetchRemoteSources();
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
this.$store.dispatch('setError', error);
|
||||
return;
|
||||
}
|
||||
this.remotesources = data;
|
||||
|
@ -249,15 +268,13 @@ export default {
|
|||
return;
|
||||
}
|
||||
this.fetchCurrentUser();
|
||||
}
|
||||
},
|
||||
created: function() {
|
||||
},
|
||||
created: function () {
|
||||
this.fetchCurrentUser();
|
||||
this.fetchRemoteSources();
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
|
@ -18,21 +18,22 @@
|
|||
</div>
|
||||
<div class="flex" v-for="variable in variables" v-bind:key="variable.id">
|
||||
<div class="w-2/12">
|
||||
<span class="name">{{variable.name}}</span>
|
||||
<div v-if="showparentpath" class="text-sm font-light">from {{variable.parent_path}}</div>
|
||||
<span class="name">{{ variable.name }}</span>
|
||||
<div v-if="showparentpath" class="text-sm font-light">
|
||||
from {{ variable.parent_path }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-10/12">
|
||||
<div class="flex" v-for="val in variable.values" v-bind:key="val.id">
|
||||
<div class="w-2/12">
|
||||
<span>{{val.secret_name}}</span>
|
||||
<div
|
||||
v-if="val.matching_secret_parent_path"
|
||||
class="text-sm"
|
||||
>using secret from {{val.matching_secret_parent_path}}</div>
|
||||
<span>{{ val.secret_name }}</span>
|
||||
<div v-if="val.matching_secret_parent_path" class="text-sm">
|
||||
using secret from {{ val.matching_secret_parent_path }}
|
||||
</div>
|
||||
<div v-else class="text-sm text-red-600">no matching secret</div>
|
||||
</div>
|
||||
<div class="w-2/12">
|
||||
<span>{{val.secret_var}}</span>
|
||||
<span>{{ val.secret_var }}</span>
|
||||
</div>
|
||||
<div class="w-8/12">
|
||||
<div v-if="val.when">
|
||||
|
@ -43,13 +44,19 @@
|
|||
<span>{{ type }}</span>
|
||||
</div>
|
||||
<div class="w-1/3">
|
||||
<div v-for="include in val.when[type].include" v-bind:key="include.match">
|
||||
<div>{{include.match}}</div>
|
||||
<div
|
||||
v-for="include in val.when[type].include"
|
||||
v-bind:key="include.match"
|
||||
>
|
||||
<div>{{ include.match }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-1/3">
|
||||
<div v-for="exclude in val.when[type].exclude" v-bind:key="exclude.match">
|
||||
<div>{{exclude.match}}</div>
|
||||
<div
|
||||
v-for="exclude in val.when[type].exclude"
|
||||
v-bind:key="exclude.match"
|
||||
>
|
||||
<div>{{ exclude.match }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -66,15 +73,12 @@
|
|||
<script>
|
||||
export default {
|
||||
components: {},
|
||||
name: "vars",
|
||||
name: 'vars',
|
||||
props: {
|
||||
variables: Array,
|
||||
showparentpath: Boolean
|
||||
}
|
||||
showparentpath: Boolean,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
@tailwind base;
|
||||
@tailwind components;
|
||||
|
||||
@import "@/css/_ansi.scss";
|
||||
@import '@/css/_ansi.scss';
|
||||
|
||||
.btn {
|
||||
@apply font-bold py-2 px-4 rounded;
|
||||
|
@ -119,7 +119,7 @@
|
|||
border-radius: 290486px;
|
||||
border-right-color: transparent;
|
||||
border-top-color: transparent;
|
||||
content: "";
|
||||
content: '';
|
||||
display: block;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
|
|
26
src/main.js
26
src/main.js
|
@ -1,11 +1,11 @@
|
|||
import "@/css/tailwind.scss";
|
||||
import { getUser } from "@/util/auth";
|
||||
import "@mdi/font/css/materialdesignicons.css";
|
||||
import Vue from "vue";
|
||||
import Vue2Filters from "vue2-filters";
|
||||
import App from "./App.vue";
|
||||
import router from "./router";
|
||||
import store from "./store";
|
||||
import '@/css/tailwind.scss';
|
||||
import { getUser } from '@/util/auth';
|
||||
import '@mdi/font/css/materialdesignicons.css';
|
||||
import Vue from 'vue';
|
||||
import Vue2Filters from 'vue2-filters';
|
||||
import App from './App.vue';
|
||||
import router from './router';
|
||||
import store from './store';
|
||||
|
||||
Vue.use(Vue2Filters);
|
||||
|
||||
|
@ -13,12 +13,12 @@ Vue.use(Vue2Filters);
|
|||
new Vue({
|
||||
router,
|
||||
store,
|
||||
created: function() {
|
||||
created: function () {
|
||||
let user = getUser();
|
||||
if (user) {
|
||||
store.dispatch("setUser", user);
|
||||
store.dispatch('setUser', user);
|
||||
}
|
||||
store.dispatch("setRegisterUser", null);
|
||||
store.dispatch('setRegisterUser', null);
|
||||
},
|
||||
render: h => h(App)
|
||||
}).$mount("#app");
|
||||
render: (h) => h(App),
|
||||
}).$mount('#app');
|
||||
|
|
557
src/router.js
557
src/router.js
|
@ -1,249 +1,348 @@
|
|||
import Vue from "vue";
|
||||
import VueRouter from "vue-router";
|
||||
import Home from "./views/Home.vue";
|
||||
import User from "./views/User.vue";
|
||||
import Org from "./views/Org.vue";
|
||||
import Project from "./views/Project.vue";
|
||||
import ProjectGroup from "./views/ProjectGroup.vue";
|
||||
import AddLinkedAccount from "./views/AddLinkedAccount.vue";
|
||||
import usersettings from "./components/usersettings.vue";
|
||||
import projects from "./components/projects.vue";
|
||||
import projectsettings from "./components/projectsettings.vue";
|
||||
import projectgroupsettings from "./components/projectgroupsettings.vue";
|
||||
import createproject from "./components/createproject.vue";
|
||||
import createprojectgroup from "./components/createprojectgroup.vue";
|
||||
import createorganization from "./components/createorganization.vue";
|
||||
import orgmembers from "./components/orgmembers.vue";
|
||||
import runs from "./components/runs.vue";
|
||||
import runsummary from "./components/runsummary.vue";
|
||||
import tasksummary from "./components/tasksummary.vue";
|
||||
import Oauth2 from "./views/Oauth2.vue";
|
||||
import Register from "./views/Register.vue";
|
||||
import Login from "./views/Login.vue";
|
||||
import Logout from "./views/Logout.vue";
|
||||
import CreateSource from "./views/CreateSource.vue";
|
||||
import Vue from 'vue';
|
||||
import VueRouter from 'vue-router';
|
||||
import Home from './views/Home.vue';
|
||||
import User from './views/User.vue';
|
||||
import Org from './views/Org.vue';
|
||||
import Project from './views/Project.vue';
|
||||
import ProjectGroup from './views/ProjectGroup.vue';
|
||||
import AddLinkedAccount from './views/AddLinkedAccount.vue';
|
||||
import usersettings from './components/usersettings.vue';
|
||||
import projects from './components/projects.vue';
|
||||
import projectsettings from './components/projectsettings.vue';
|
||||
import projectgroupsettings from './components/projectgroupsettings.vue';
|
||||
import createproject from './components/createproject.vue';
|
||||
import createprojectgroup from './components/createprojectgroup.vue';
|
||||
import createorganization from './components/createorganization.vue';
|
||||
import orgmembers from './components/orgmembers.vue';
|
||||
import runs from './components/runs.vue';
|
||||
import runsummary from './components/runsummary.vue';
|
||||
import tasksummary from './components/tasksummary.vue';
|
||||
import Oauth2 from './views/Oauth2.vue';
|
||||
import Register from './views/Register.vue';
|
||||
import Login from './views/Login.vue';
|
||||
import Logout from './views/Logout.vue';
|
||||
import CreateSource from './views/CreateSource.vue';
|
||||
|
||||
import { parseRef, projectRunLink } from "@/util/link.js";
|
||||
import { fetchProject } from "@/util/data.js";
|
||||
import { parseRef, projectRunLink } from '@/util/link.js';
|
||||
import { fetchProject } from '@/util/data.js';
|
||||
|
||||
import store from "./store";
|
||||
import store from './store';
|
||||
|
||||
Vue.use(VueRouter);
|
||||
|
||||
const router = new VueRouter({
|
||||
mode: "history",
|
||||
mode: 'history',
|
||||
routes: [
|
||||
{
|
||||
path: "/register",
|
||||
name: "register",
|
||||
path: '/register',
|
||||
name: 'register',
|
||||
component: Register,
|
||||
},
|
||||
{
|
||||
path: "/newsource",
|
||||
name: "newsource",
|
||||
path: '/newsource',
|
||||
name: 'newsource',
|
||||
component: CreateSource,
|
||||
},
|
||||
{
|
||||
path: "/login",
|
||||
name: "login",
|
||||
component: Login
|
||||
path: '/login',
|
||||
name: 'login',
|
||||
component: Login,
|
||||
},
|
||||
{
|
||||
path: "/logout",
|
||||
name: "logout",
|
||||
component: Logout
|
||||
path: '/logout',
|
||||
name: 'logout',
|
||||
component: Logout,
|
||||
},
|
||||
{
|
||||
path: "/oauth2/callback",
|
||||
name: "oauth2callback",
|
||||
component: Oauth2
|
||||
path: '/oauth2/callback',
|
||||
name: 'oauth2callback',
|
||||
component: Oauth2,
|
||||
},
|
||||
{
|
||||
path: "/",
|
||||
name: "home",
|
||||
component: Home
|
||||
path: '/',
|
||||
name: 'home',
|
||||
component: Home,
|
||||
},
|
||||
{
|
||||
path: "/neworganization",
|
||||
path: '/neworganization',
|
||||
component: createorganization,
|
||||
},
|
||||
{
|
||||
path: "/user/:username",
|
||||
path: '/user/:username',
|
||||
component: User,
|
||||
props: (route) => ({ username: route.params.username }),
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "user",
|
||||
path: '',
|
||||
name: 'user',
|
||||
component: projects,
|
||||
props: (route) => ({ ownertype: "user", ownername: route.params.username })
|
||||
props: (route) => ({
|
||||
ownertype: 'user',
|
||||
ownername: route.params.username,
|
||||
}),
|
||||
},
|
||||
{
|
||||
path: "projects",
|
||||
name: "user projects",
|
||||
path: 'projects',
|
||||
name: 'user projects',
|
||||
component: projects,
|
||||
props: (route) => ({ ownertype: "user", ownername: route.params.username })
|
||||
props: (route) => ({
|
||||
ownertype: 'user',
|
||||
ownername: route.params.username,
|
||||
}),
|
||||
},
|
||||
{
|
||||
path: "runs",
|
||||
name: "user direct runs",
|
||||
path: 'runs',
|
||||
name: 'user direct runs',
|
||||
component: runs,
|
||||
props: (route) => ({ ownertype: "user", ownername: route.params.username })
|
||||
props: (route) => ({
|
||||
ownertype: 'user',
|
||||
ownername: route.params.username,
|
||||
}),
|
||||
},
|
||||
{
|
||||
path: "runs/:runid",
|
||||
name: "user direct run",
|
||||
path: 'runs/:runid',
|
||||
name: 'user direct run',
|
||||
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",
|
||||
name: "user direct run task",
|
||||
path: 'runs/:runid/tasks/:taskid',
|
||||
name: 'user direct run task',
|
||||
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",
|
||||
name: "user settings",
|
||||
path: 'settings',
|
||||
name: 'user settings',
|
||||
component: usersettings,
|
||||
props: (route) => ({ username: route.params.username }),
|
||||
},
|
||||
{
|
||||
path: "linkedaccounts/add/:remotesource",
|
||||
name: "user add linked account",
|
||||
path: 'linkedaccounts/add/:remotesource',
|
||||
name: 'user add linked account',
|
||||
component: AddLinkedAccount,
|
||||
props: (route) => ({ username: route.params.username, remoteSourceName: route.params.remotesource })
|
||||
props: (route) => ({
|
||||
username: route.params.username,
|
||||
remoteSourceName: route.params.remotesource,
|
||||
}),
|
||||
},
|
||||
{
|
||||
path: "createprojectgroup",
|
||||
name: "user create project group",
|
||||
path: 'createprojectgroup',
|
||||
name: 'user create project group',
|
||||
component: createprojectgroup,
|
||||
props: (route) => ({ ownertype: "user", ownername: route.params.username })
|
||||
props: (route) => ({
|
||||
ownertype: 'user',
|
||||
ownername: route.params.username,
|
||||
}),
|
||||
},
|
||||
{
|
||||
path: "createproject",
|
||||
name: "user create project",
|
||||
path: 'createproject',
|
||||
name: 'user create project',
|
||||
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,
|
||||
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: [
|
||||
{
|
||||
path: "",
|
||||
name: "user project",
|
||||
path: '',
|
||||
name: 'user project',
|
||||
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",
|
||||
name: "user project runs",
|
||||
path: 'runs',
|
||||
name: 'user project 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",
|
||||
name: "user project branches runs",
|
||||
path: 'branches',
|
||||
name: 'user project branches 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",
|
||||
name: "user project tags runs",
|
||||
path: 'tags',
|
||||
name: 'user project tags 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",
|
||||
name: "user project pull requests runs",
|
||||
path: 'pullrequests',
|
||||
name: 'user project pull requests 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",
|
||||
name: "user project run",
|
||||
path: 'runs/:runid',
|
||||
name: 'user project run',
|
||||
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",
|
||||
name: "user project run task",
|
||||
path: 'runs/:runid/tasks/:taskid',
|
||||
name: 'user project run task',
|
||||
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",
|
||||
name: "user project settings",
|
||||
path: 'settings',
|
||||
name: 'user project settings',
|
||||
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,
|
||||
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: [
|
||||
{
|
||||
path: "",
|
||||
name: "user project group",
|
||||
path: '',
|
||||
name: 'user project group',
|
||||
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",
|
||||
name: "user project group projects",
|
||||
path: 'projects',
|
||||
name: 'user project group 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",
|
||||
name: "user project group settings",
|
||||
path: 'settings',
|
||||
name: 'user project group settings',
|
||||
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",
|
||||
name: "user project group create project group",
|
||||
path: 'createprojectgroup',
|
||||
name: 'user project group create project group',
|
||||
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",
|
||||
name: "user project group create project",
|
||||
path: 'createproject',
|
||||
name: 'user project group create project',
|
||||
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,
|
||||
props: (route) => ({ orgname: route.params.orgname }),
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "org",
|
||||
path: '',
|
||||
name: 'org',
|
||||
component: projects,
|
||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname })
|
||||
props: (route) => ({
|
||||
ownertype: 'org',
|
||||
ownername: route.params.orgname,
|
||||
}),
|
||||
},
|
||||
{
|
||||
path: "projects",
|
||||
name: "org projects",
|
||||
path: 'projects',
|
||||
name: 'org projects',
|
||||
component: projects,
|
||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname })
|
||||
props: (route) => ({
|
||||
ownertype: 'org',
|
||||
ownername: route.params.orgname,
|
||||
}),
|
||||
},
|
||||
{
|
||||
path: "members",
|
||||
name: "org members",
|
||||
path: 'members',
|
||||
name: 'org members',
|
||||
component: orgmembers,
|
||||
props: (route) => ({ orgname: route.params.orgname })
|
||||
props: (route) => ({ orgname: route.params.orgname }),
|
||||
},
|
||||
/* {
|
||||
path: "settings",
|
||||
|
@ -252,141 +351,213 @@ const router = new VueRouter({
|
|||
props: (route) => ({ username: route.params.username }),
|
||||
}, */
|
||||
{
|
||||
path: "createprojectgroup",
|
||||
name: "org create project group",
|
||||
path: 'createprojectgroup',
|
||||
name: 'org create project group',
|
||||
component: createprojectgroup,
|
||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname })
|
||||
props: (route) => ({
|
||||
ownertype: 'org',
|
||||
ownername: route.params.orgname,
|
||||
}),
|
||||
},
|
||||
{
|
||||
path: "createproject",
|
||||
name: "org create project",
|
||||
path: 'createproject',
|
||||
name: 'org create project',
|
||||
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,
|
||||
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: [
|
||||
{
|
||||
path: "",
|
||||
name: "org project",
|
||||
path: '',
|
||||
name: 'org project',
|
||||
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",
|
||||
name: "org project runs",
|
||||
path: 'runs',
|
||||
name: 'org project 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",
|
||||
name: "org project branches runs",
|
||||
path: 'branches',
|
||||
name: 'org project branches 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",
|
||||
name: "org project tags runs",
|
||||
path: 'tags',
|
||||
name: 'org project tags 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",
|
||||
name: "org project pull requests runs",
|
||||
path: 'pullrequests',
|
||||
name: 'org project pull requests 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",
|
||||
name: "org project run",
|
||||
path: 'runs/:runid',
|
||||
name: 'org project run',
|
||||
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",
|
||||
name: "org project run task",
|
||||
path: 'runs/:runid/tasks/:taskid',
|
||||
name: 'org project run task',
|
||||
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",
|
||||
name: "org project settings",
|
||||
path: 'settings',
|
||||
name: 'org project settings',
|
||||
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,
|
||||
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: [
|
||||
{
|
||||
path: "",
|
||||
name: "org project group",
|
||||
path: '',
|
||||
name: 'org project group',
|
||||
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",
|
||||
name: "org project group projects",
|
||||
path: 'projects',
|
||||
name: 'org project group 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",
|
||||
name: "org project group settings",
|
||||
path: 'settings',
|
||||
name: 'org project group settings',
|
||||
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",
|
||||
name: "org project group create project group",
|
||||
path: 'createprojectgroup',
|
||||
name: 'org project group create project group',
|
||||
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",
|
||||
name: "org project group create project",
|
||||
path: 'createproject',
|
||||
name: 'org project group create project',
|
||||
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) => {
|
||||
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
|
||||
let projectref = query.projectref
|
||||
let runid = query.runid
|
||||
let projectref = query.projectref;
|
||||
let runid = query.runid;
|
||||
|
||||
let { data, error } = await fetchProject(projectref);
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
this.$store.dispatch('setError', error);
|
||||
return;
|
||||
}
|
||||
|
||||
let project = data;
|
||||
|
||||
let parts = project.path.split("/")
|
||||
let nextPath = projectRunLink(parts[0], parts[1], parts.slice(2), runid)
|
||||
let parts = project.path.split('/');
|
||||
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 Vuex from 'vuex'
|
||||
import Vue from 'vue';
|
||||
import Vuex from 'vuex';
|
||||
|
||||
Vue.use(Vuex)
|
||||
Vue.use(Vuex);
|
||||
|
||||
const state = {
|
||||
error: null,
|
||||
user: null,
|
||||
registeruser: null,
|
||||
}
|
||||
};
|
||||
|
||||
const getters = {
|
||||
// global error
|
||||
error: state => {
|
||||
return state.error
|
||||
error: (state) => {
|
||||
return state.error;
|
||||
},
|
||||
user: state => {
|
||||
return state.user
|
||||
user: (state) => {
|
||||
return state.user;
|
||||
},
|
||||
registeruser: state => {
|
||||
return state.registeruser
|
||||
}
|
||||
}
|
||||
registeruser: (state) => {
|
||||
return state.registeruser;
|
||||
},
|
||||
};
|
||||
|
||||
const mutations = {
|
||||
setError(state, error) {
|
||||
state.error = error
|
||||
state.error = error;
|
||||
},
|
||||
setUser(state, user) {
|
||||
state.user = user
|
||||
state.user = user;
|
||||
},
|
||||
setRegisterUser(state, user) {
|
||||
state.registeruser = user
|
||||
}
|
||||
}
|
||||
state.registeruser = user;
|
||||
},
|
||||
};
|
||||
|
||||
const actions = {
|
||||
setError({ commit }, error) {
|
||||
commit('setError', error)
|
||||
commit('setError', error);
|
||||
},
|
||||
setUser({ commit }, user) {
|
||||
commit('setUser', user)
|
||||
commit('setUser', user);
|
||||
},
|
||||
setRegisterUser({ commit }, user) {
|
||||
commit('setRegisterUser', user)
|
||||
}
|
||||
}
|
||||
|
||||
commit('setRegisterUser', user);
|
||||
},
|
||||
};
|
||||
|
||||
export default new Vuex.Store({
|
||||
state,
|
||||
getters,
|
||||
actions,
|
||||
mutations,
|
||||
})
|
||||
});
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import store from "@/store";
|
||||
import store from '@/store';
|
||||
|
||||
const ID_TOKEN_KEY = "id_token";
|
||||
const USER_KEY = "user";
|
||||
const LOGIN_REDIRECT_KEY = "login_redirect";
|
||||
const ID_TOKEN_KEY = 'id_token';
|
||||
const USER_KEY = 'user';
|
||||
const LOGIN_REDIRECT_KEY = 'login_redirect';
|
||||
|
||||
let API_URL = window.CONFIG.API_URL;
|
||||
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) {
|
||||
setIdToken(token);
|
||||
setUser(user);
|
||||
store.dispatch("setUser", user);
|
||||
store.dispatch('setUser', user);
|
||||
}
|
||||
|
||||
export function doLogout() {
|
||||
unsetIdToken();
|
||||
unsetUser();
|
||||
store.dispatch("setUser", null);
|
||||
store.dispatch('setUser', null);
|
||||
}
|
||||
|
||||
export function apiurlwithtoken(path) {
|
||||
let u = new URL(API_URL + API_BASE_PATH + path);
|
||||
let idToken = getIdToken();
|
||||
if (idToken) {
|
||||
u.searchParams.append("access_token", idToken);
|
||||
u.searchParams.append('access_token', idToken);
|
||||
}
|
||||
return u;
|
||||
}
|
||||
|
@ -33,19 +33,19 @@ export function apiurl(path) {
|
|||
}
|
||||
|
||||
export function loginurl() {
|
||||
return apiurl("/auth/login");
|
||||
return apiurl('/auth/login');
|
||||
}
|
||||
|
||||
export function authorizeurl() {
|
||||
return apiurl("/auth/authorize");
|
||||
return apiurl('/auth/authorize');
|
||||
}
|
||||
|
||||
export function registerurl() {
|
||||
return new apiurl("/auth/register");
|
||||
return new apiurl('/auth/register');
|
||||
}
|
||||
|
||||
export function oauth2callbackurl() {
|
||||
return new apiurl("/auth/oauth2/callback");
|
||||
return new apiurl('/auth/oauth2/callback');
|
||||
}
|
||||
|
||||
export async function loginapi(init) {
|
||||
|
@ -64,19 +64,19 @@ export async function registerapi(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) {
|
||||
init = {};
|
||||
}
|
||||
if (init.headers === undefined) {
|
||||
init["headers"] = {};
|
||||
init['headers'] = {};
|
||||
}
|
||||
if (signal) {
|
||||
init["signal"] = signal;
|
||||
init['signal'] = signal;
|
||||
}
|
||||
let idToken = token || getIdToken();
|
||||
if (idToken) {
|
||||
init.headers["Authorization"] = tokenType + " " + idToken;
|
||||
init.headers['Authorization'] = tokenType + ' ' + idToken;
|
||||
}
|
||||
|
||||
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 { apiurl, fetch as authfetch, loginapi, registerapi } from "@/util/auth";
|
||||
import router from '@/router';
|
||||
import { apiurl, fetch as authfetch, loginapi, registerapi } from '@/util/auth';
|
||||
|
||||
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_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 async function fetch(url, init, signal, token, tokenType) {
|
||||
try {
|
||||
|
@ -10,8 +11,8 @@ export async function fetch(url, init, signal, token, tokenType) {
|
|||
if (!res.ok) {
|
||||
if (res.status === 401) {
|
||||
router.push({
|
||||
name: "login",
|
||||
query: { redirect: router.currentRoute.fullPath }
|
||||
name: 'login',
|
||||
query: { redirect: router.currentRoute.fullPath },
|
||||
});
|
||||
// if we return a response containing an error what happens is
|
||||
// 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 };
|
||||
}
|
||||
} catch (e) {
|
||||
if (e.name == "AbortError") {
|
||||
if (e.name == 'AbortError') {
|
||||
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) {
|
||||
let init = {
|
||||
method: "POST",
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
remote_source_name: remotesourcename,
|
||||
login_name: username,
|
||||
password: password
|
||||
})
|
||||
password: password,
|
||||
}),
|
||||
};
|
||||
|
||||
try {
|
||||
|
@ -62,7 +63,7 @@ export async function login(username, password, remotesourcename) {
|
|||
return { data: await res.json(), error: null };
|
||||
}
|
||||
} 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
|
||||
) {
|
||||
let init = {
|
||||
method: "POST",
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
username: username,
|
||||
remote_source_name: remotesourcename,
|
||||
remote_source_login_name: remoteloginname,
|
||||
remote_source_login_password: remotepassword
|
||||
})
|
||||
remote_source_login_password: remotepassword,
|
||||
}),
|
||||
};
|
||||
|
||||
try {
|
||||
|
@ -91,111 +92,122 @@ export async function register(
|
|||
return { data: await res.json(), error: null };
|
||||
}
|
||||
} 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) {
|
||||
let path = "/user";
|
||||
let path = '/user';
|
||||
return await fetch(apiurl(path), null, signal);
|
||||
}
|
||||
|
||||
export async function fetchOrgMembers(orgref, signal) {
|
||||
let path = "/orgs/" + orgref + "/members";
|
||||
let path = '/orgs/' + orgref + '/members';
|
||||
return await fetch(apiurl(path), null, signal);
|
||||
}
|
||||
|
||||
export async function fetchRuns(group, startRunID, lastrun, signal) {
|
||||
let u = apiurl("/runs");
|
||||
let u = apiurl('/runs');
|
||||
if (group) {
|
||||
u.searchParams.append("group", group);
|
||||
u.searchParams.append('group', group);
|
||||
}
|
||||
if (lastrun) {
|
||||
u.searchParams.append("lastrun", true);
|
||||
u.searchParams.append('lastrun', true);
|
||||
}
|
||||
if (startRunID) {
|
||||
u.searchParams.append("start", startRunID);
|
||||
u.searchParams.append('start', startRunID);
|
||||
}
|
||||
|
||||
return await fetch(u, null, 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) {
|
||||
return await fetch(apiurl("/runs/" + runid + "/tasks/" + taskid), signal);
|
||||
return await fetch(apiurl('/runs/' + runid + '/tasks/' + taskid), signal);
|
||||
}
|
||||
|
||||
export async function fetchUser(username, signal) {
|
||||
let path = "/users/" + username;
|
||||
let path = '/users/' + username;
|
||||
return await fetch(apiurl(path), null, signal);
|
||||
}
|
||||
|
||||
export async function fetchProjectGroup(projectgroupref, signal) {
|
||||
let path = "/projectgroups/" + encodeURIComponent(projectgroupref);
|
||||
let path = '/projectgroups/' + encodeURIComponent(projectgroupref);
|
||||
|
||||
return await fetch(apiurl(path), null, signal);
|
||||
}
|
||||
|
||||
export async function fetchProjectGroupSubgroups(projectgroupref, signal) {
|
||||
let path = "/projectgroups/" + encodeURIComponent(projectgroupref);
|
||||
path += "/subgroups";
|
||||
let path = '/projectgroups/' + encodeURIComponent(projectgroupref);
|
||||
path += '/subgroups';
|
||||
|
||||
return await fetch(apiurl(path), null, signal);
|
||||
}
|
||||
|
||||
export async function fetchProjectGroupProjects(projectgroupref, signal) {
|
||||
let path = "/projectgroups/" + encodeURIComponent(projectgroupref);
|
||||
path += "/projects";
|
||||
let path = '/projectgroups/' + encodeURIComponent(projectgroupref);
|
||||
path += '/projects';
|
||||
|
||||
return await fetch(apiurl(path), null, signal);
|
||||
}
|
||||
|
||||
export async function fetchProject(ref, signal) {
|
||||
let path = "/projects/" + encodeURIComponent(ref);
|
||||
let path = '/projects/' + encodeURIComponent(ref);
|
||||
|
||||
return await fetch(apiurl(path), null, signal);
|
||||
}
|
||||
|
||||
export async function fetchSecrets(ownertype, ref, all, signal) {
|
||||
let path;
|
||||
if (ownertype == "project") {
|
||||
path = "/projects/";
|
||||
} else if (ownertype == "projectgroup") {
|
||||
path = "/projectgroups/";
|
||||
if (ownertype == 'project') {
|
||||
path = '/projects/';
|
||||
} else if (ownertype == 'projectgroup') {
|
||||
path = '/projectgroups/';
|
||||
}
|
||||
path += encodeURIComponent(ref);
|
||||
path += "/secrets";
|
||||
path += '/secrets';
|
||||
if (all) {
|
||||
path += "?tree&removeoverridden";
|
||||
path += '?tree&removeoverridden';
|
||||
}
|
||||
return await fetch(apiurl(path), null, signal);
|
||||
}
|
||||
|
||||
export async function fetchVariables(ownertype, ref, all, signal) {
|
||||
let path;
|
||||
if (ownertype == "project") {
|
||||
path = "/projects/";
|
||||
} else if (ownertype == "projectgroup") {
|
||||
path = "/projectgroups/";
|
||||
if (ownertype == 'project') {
|
||||
path = '/projects/';
|
||||
} else if (ownertype == 'projectgroup') {
|
||||
path = '/projectgroups/';
|
||||
}
|
||||
path += encodeURIComponent(ref);
|
||||
path += "/variables";
|
||||
path += '/variables';
|
||||
if (all) {
|
||||
path += "?tree&removeoverridden";
|
||||
path += '?tree&removeoverridden';
|
||||
}
|
||||
return await fetch(apiurl(path), null, signal);
|
||||
}
|
||||
|
||||
export async function createRemoteSource(
|
||||
token, type, name, clientID, clientSecret, apiURL, authType, skipVerify,
|
||||
sshHostKey, skipSshHostKeyCheck, registrationEnabled, loginEnabled, signal,
|
||||
token,
|
||||
type,
|
||||
name,
|
||||
clientID,
|
||||
clientSecret,
|
||||
apiURL,
|
||||
authType,
|
||||
skipVerify,
|
||||
sshHostKey,
|
||||
skipSshHostKeyCheck,
|
||||
registrationEnabled,
|
||||
loginEnabled,
|
||||
signal
|
||||
) {
|
||||
let path = "/remotesources";
|
||||
let path = '/remotesources';
|
||||
let init = {
|
||||
method: "POST",
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
name,
|
||||
apiurl: apiURL,
|
||||
|
@ -208,38 +220,38 @@ export async function createRemoteSource(
|
|||
oauth_2_client_secret: clientSecret,
|
||||
registration_enabled: registrationEnabled,
|
||||
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) {
|
||||
let path = "/orgs";
|
||||
let path = '/orgs';
|
||||
let init = {
|
||||
method: "POST",
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
name: orgname,
|
||||
visibility: visibility
|
||||
})
|
||||
visibility: visibility,
|
||||
}),
|
||||
};
|
||||
return await fetch(apiurl(path), init, signal);
|
||||
}
|
||||
|
||||
export async function createUserToken(username, tokenname, signal) {
|
||||
let path = "/users/" + username + "/tokens";
|
||||
let path = '/users/' + username + '/tokens';
|
||||
let init = {
|
||||
method: "POST",
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
token_name: tokenname
|
||||
})
|
||||
token_name: tokenname,
|
||||
}),
|
||||
};
|
||||
return await fetch(apiurl(path), init, signal);
|
||||
}
|
||||
|
||||
export async function deleteUserToken(username, tokenname, signal) {
|
||||
let path = "/users/" + username + "/tokens/" + tokenname;
|
||||
let path = '/users/' + username + '/tokens/' + tokenname;
|
||||
let init = {
|
||||
method: "DELETE"
|
||||
method: 'DELETE',
|
||||
};
|
||||
return await fetch(apiurl(path), init, signal);
|
||||
}
|
||||
|
@ -251,90 +263,90 @@ export async function createUserLinkedAccount(
|
|||
password,
|
||||
signal
|
||||
) {
|
||||
let path = "/users/" + username + "/linkedaccounts";
|
||||
let path = '/users/' + username + '/linkedaccounts';
|
||||
let init = {
|
||||
method: "POST",
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
remote_source_name: remotesourcename,
|
||||
remote_source_login_name: loginname,
|
||||
remote_source_login_password: password
|
||||
})
|
||||
remote_source_login_password: password,
|
||||
}),
|
||||
};
|
||||
return await fetch(apiurl(path), init, signal);
|
||||
}
|
||||
|
||||
export async function deleteLinkedAccount(username, laid, signal) {
|
||||
let path = "/users/" + username + "/linkedaccounts/" + laid;
|
||||
let path = '/users/' + username + '/linkedaccounts/' + laid;
|
||||
let init = {
|
||||
method: "DELETE"
|
||||
method: 'DELETE',
|
||||
};
|
||||
return await fetch(apiurl(path), init, signal);
|
||||
}
|
||||
|
||||
export async function restartRun(runid, fromStart, signal) {
|
||||
let path = "/runs/" + runid + "/actions";
|
||||
let path = '/runs/' + runid + '/actions';
|
||||
let init = {
|
||||
method: "PUT",
|
||||
method: 'PUT',
|
||||
body: JSON.stringify({
|
||||
action_type: "restart",
|
||||
from_start: fromStart
|
||||
})
|
||||
action_type: 'restart',
|
||||
from_start: fromStart,
|
||||
}),
|
||||
};
|
||||
return await fetch(apiurl(path), init, signal);
|
||||
}
|
||||
|
||||
export async function cancelRun(runid, signal) {
|
||||
let path = "/runs/" + runid + "/actions";
|
||||
let path = '/runs/' + runid + '/actions';
|
||||
let init = {
|
||||
method: "PUT",
|
||||
method: 'PUT',
|
||||
body: JSON.stringify({
|
||||
action_type: "cancel"
|
||||
})
|
||||
action_type: 'cancel',
|
||||
}),
|
||||
};
|
||||
return await fetch(apiurl(path), init, signal);
|
||||
}
|
||||
|
||||
export async function stopRun(runid, signal) {
|
||||
let path = "/runs/" + runid + "/actions";
|
||||
let path = '/runs/' + runid + '/actions';
|
||||
let init = {
|
||||
method: "PUT",
|
||||
method: 'PUT',
|
||||
body: JSON.stringify({
|
||||
action_type: "stop"
|
||||
})
|
||||
action_type: 'stop',
|
||||
}),
|
||||
};
|
||||
return await fetch(apiurl(path), init, signal);
|
||||
}
|
||||
|
||||
export async function approveTask(runid, taskid, signal) {
|
||||
let path = "/runs/" + runid + "/tasks/" + taskid + "/actions";
|
||||
let path = '/runs/' + runid + '/tasks/' + taskid + '/actions';
|
||||
let init = {
|
||||
method: "PUT",
|
||||
method: 'PUT',
|
||||
body: JSON.stringify({
|
||||
action_type: "approve"
|
||||
})
|
||||
action_type: 'approve',
|
||||
}),
|
||||
};
|
||||
return await fetch(apiurl(path), init, signal);
|
||||
}
|
||||
|
||||
export async function fetchRemoteSources(signal) {
|
||||
let path = "/remotesources";
|
||||
let path = '/remotesources';
|
||||
return await fetch(apiurl(path), null, signal);
|
||||
}
|
||||
|
||||
export async function userRemoteRepos(remotesourceid, signal) {
|
||||
let path = "/user/remoterepos/" + remotesourceid;
|
||||
let path = '/user/remoterepos/' + remotesourceid;
|
||||
return await fetch(apiurl(path, null, signal));
|
||||
}
|
||||
|
||||
export async function createProjectGroup(parentref, name, visibility, signal) {
|
||||
let path = "/projectgroups";
|
||||
let path = '/projectgroups';
|
||||
let init = {
|
||||
method: "POST",
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
name: name,
|
||||
parent_ref: parentref,
|
||||
visibility: visibility
|
||||
})
|
||||
visibility: visibility,
|
||||
}),
|
||||
};
|
||||
return await fetch(apiurl(path), init, signal);
|
||||
}
|
||||
|
@ -345,13 +357,13 @@ export async function updateProjectGroup(
|
|||
visibility,
|
||||
signal
|
||||
) {
|
||||
let path = "/projectgroups/" + encodeURIComponent(projectgroupref);
|
||||
let path = '/projectgroups/' + encodeURIComponent(projectgroupref);
|
||||
let init = {
|
||||
method: "PUT",
|
||||
method: 'PUT',
|
||||
body: JSON.stringify({
|
||||
name: name,
|
||||
visibility: visibility
|
||||
})
|
||||
visibility: visibility,
|
||||
}),
|
||||
};
|
||||
return await fetch(apiurl(path), init, signal);
|
||||
}
|
||||
|
@ -365,56 +377,61 @@ export async function createProject(
|
|||
passvarstoforkedpr,
|
||||
signal
|
||||
) {
|
||||
let path = "/projects";
|
||||
let path = '/projects';
|
||||
let init = {
|
||||
method: "POST",
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
name: name,
|
||||
parent_ref: parentref,
|
||||
visibility: visibility,
|
||||
remote_source_name: remotesourcename,
|
||||
repo_path: remoterepopath,
|
||||
pass_vars_to_forked_pr: passvarstoforkedpr
|
||||
})
|
||||
pass_vars_to_forked_pr: passvarstoforkedpr,
|
||||
}),
|
||||
};
|
||||
return await fetch(apiurl(path), init, signal);
|
||||
}
|
||||
|
||||
export async function updateProject(projectref, name, visibility, passvarstoforkedpr, signal) {
|
||||
let path = "/projects/" + encodeURIComponent(projectref);
|
||||
export async function updateProject(
|
||||
projectref,
|
||||
name,
|
||||
visibility,
|
||||
passvarstoforkedpr,
|
||||
signal
|
||||
) {
|
||||
let path = '/projects/' + encodeURIComponent(projectref);
|
||||
let init = {
|
||||
method: "PUT",
|
||||
method: 'PUT',
|
||||
body: JSON.stringify({
|
||||
name: name,
|
||||
visibility: visibility,
|
||||
pass_vars_to_forked_pr: passvarstoforkedpr
|
||||
})
|
||||
pass_vars_to_forked_pr: passvarstoforkedpr,
|
||||
}),
|
||||
};
|
||||
return await fetch(apiurl(path), init, signal);
|
||||
}
|
||||
|
||||
export async function deleteProject(projectref, signal) {
|
||||
let path = "/projects/" + encodeURIComponent(projectref);
|
||||
let path = '/projects/' + encodeURIComponent(projectref);
|
||||
let init = {
|
||||
method: "DELETE"
|
||||
method: 'DELETE',
|
||||
};
|
||||
return await fetch(apiurl(path), init, signal);
|
||||
}
|
||||
|
||||
export async function projectUpdateRepoLinkedAccount(projectref, signal) {
|
||||
let path =
|
||||
"/projects/" + encodeURIComponent(projectref) + "/updaterepolinkedaccount";
|
||||
'/projects/' + encodeURIComponent(projectref) + '/updaterepolinkedaccount';
|
||||
let init = {
|
||||
method: "PUT"
|
||||
method: 'PUT',
|
||||
};
|
||||
return await fetch(apiurl(path), init, signal);
|
||||
}
|
||||
|
||||
export async function deleteProjectGroup(projectgroupref, signal) {
|
||||
let path = "/projectgroups/" + encodeURIComponent(projectgroupref);
|
||||
let path = '/projectgroups/' + encodeURIComponent(projectgroupref);
|
||||
let init = {
|
||||
method: "DELETE"
|
||||
method: 'DELETE',
|
||||
};
|
||||
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) {
|
||||
ref = ref.replace(/\.proj/, "")
|
||||
ref = ref.replace(/\.proj/, '');
|
||||
// return empty array or split return an array with the empty element
|
||||
if (!ref) {
|
||||
return []
|
||||
return [];
|
||||
}
|
||||
return ref.split("/")
|
||||
return ref.split('/');
|
||||
}
|
||||
|
||||
export function ownerLink(ownertype, ownername) {
|
||||
if (ownertype == "user") {
|
||||
return { name: ownertype, params: { username: ownername } }
|
||||
} else if (ownertype == "org") {
|
||||
return { name: ownertype, params: { orgname: ownername } }
|
||||
if (ownertype == 'user') {
|
||||
return { name: ownertype, params: { username: ownername } };
|
||||
} else if (ownertype == 'org') {
|
||||
return { name: ownertype, params: { orgname: 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) {
|
||||
if (ownertype == "user") {
|
||||
return { name: ownertype + " settings", params: { username: ownername } }
|
||||
} else if (ownertype == "org") {
|
||||
return { name: ownertype + " settings", params: { orgname: ownername } }
|
||||
if (ownertype == 'user') {
|
||||
return { name: ownertype + ' settings', params: { username: ownername } };
|
||||
} else if (ownertype == 'org') {
|
||||
return { name: ownertype + ' settings', params: { orgname: ownername } };
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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
|
||||
// path), unfortunately, we cannot use route name and params since it will path
|
||||
// escape it
|
||||
export function projectGroupPath(ownertype, ownername, projectgroupref) {
|
||||
let path = `/${ownertype}/${ownername}`
|
||||
let path = `/${ownertype}/${ownername}`;
|
||||
// root project group will have a .proj without a name
|
||||
let projectgrouppath = (projectgroupref.join("/") + ".proj")
|
||||
path = `${path}/projectgroups/${projectgrouppath}`
|
||||
return path
|
||||
let projectgrouppath = projectgroupref.join('/') + '.proj';
|
||||
path = `${path}/projectgroups/${projectgrouppath}`;
|
||||
return path;
|
||||
}
|
||||
|
||||
export function projectPath(ownertype, ownername, projectref) {
|
||||
let path = `/${ownertype}/${ownername}`
|
||||
let projectpath = (projectref.join("/") + ".proj")
|
||||
path = `${path}/projects/${projectpath}`
|
||||
return path
|
||||
let path = `/${ownertype}/${ownername}`;
|
||||
let projectpath = projectref.join('/') + '.proj';
|
||||
path = `${path}/projects/${projectpath}`;
|
||||
return path;
|
||||
}
|
||||
|
||||
export function projectGroupLink(ownertype, ownername, projectgroupref) {
|
||||
return { path: projectGroupPath(ownertype, ownername, projectgroupref) }
|
||||
return { path: projectGroupPath(ownertype, ownername, projectgroupref) };
|
||||
}
|
||||
|
||||
export function projectGroupProjectsLink(ownertype, ownername, projectgroupref) {
|
||||
let projectgrouppath = (projectgroupref.join("/") + ".proj")
|
||||
return { path: `/${ownertype}/${ownername}/projectgroups/${projectgrouppath}/projects` }
|
||||
export function projectGroupProjectsLink(
|
||||
ownertype,
|
||||
ownername,
|
||||
projectgroupref
|
||||
) {
|
||||
let projectgrouppath = projectgroupref.join('/') + '.proj';
|
||||
return {
|
||||
path: `/${ownertype}/${ownername}/projectgroups/${projectgrouppath}/projects`,
|
||||
};
|
||||
}
|
||||
|
||||
export function projectLink(ownertype, ownername, projectref) {
|
||||
let projectpath = (projectref.join("/") + ".proj")
|
||||
return { path: `/${ownertype}/${ownername}/projects/${projectpath}` }
|
||||
let projectpath = projectref.join('/') + '.proj';
|
||||
return { path: `/${ownertype}/${ownername}/projects/${projectpath}` };
|
||||
}
|
||||
|
||||
export function projectRunsLink(ownertype, ownername, projectref) {
|
||||
let projectpath = (projectref.join("/") + ".proj")
|
||||
return { path: `/${ownertype}/${ownername}/projects/${projectpath}/runs` }
|
||||
let projectpath = projectref.join('/') + '.proj';
|
||||
return { path: `/${ownertype}/${ownername}/projects/${projectpath}/runs` };
|
||||
}
|
||||
|
||||
export function projectBranchesRunsLink(ownertype, ownername, projectref) {
|
||||
let projectpath = (projectref.join("/") + ".proj")
|
||||
return { path: `/${ownertype}/${ownername}/projects/${projectpath}/branches` }
|
||||
let projectpath = projectref.join('/') + '.proj';
|
||||
return {
|
||||
path: `/${ownertype}/${ownername}/projects/${projectpath}/branches`,
|
||||
};
|
||||
}
|
||||
|
||||
export function projectTagsRunsLink(ownertype, ownername, projectref) {
|
||||
let projectpath = (projectref.join("/") + ".proj")
|
||||
return { path: `/${ownertype}/${ownername}/projects/${projectpath}/tags` }
|
||||
let projectpath = projectref.join('/') + '.proj';
|
||||
return { path: `/${ownertype}/${ownername}/projects/${projectpath}/tags` };
|
||||
}
|
||||
|
||||
export function projectPRsRunsLink(ownertype, ownername, projectref) {
|
||||
let projectpath = (projectref.join("/") + ".proj")
|
||||
return { path: `/${ownertype}/${ownername}/projects/${projectpath}/pullrequests` }
|
||||
let projectpath = projectref.join('/') + '.proj';
|
||||
return {
|
||||
path: `/${ownertype}/${ownername}/projects/${projectpath}/pullrequests`,
|
||||
};
|
||||
}
|
||||
|
||||
export function projectRunLink(ownertype, ownername, projectref, runid) {
|
||||
let projectpath = (projectref.join("/") + ".proj")
|
||||
return { path: `/${ownertype}/${ownername}/projects/${projectpath}/runs/${runid}` }
|
||||
let projectpath = projectref.join('/') + '.proj';
|
||||
return {
|
||||
path: `/${ownertype}/${ownername}/projects/${projectpath}/runs/${runid}`,
|
||||
};
|
||||
}
|
||||
|
||||
export function projectRunTaskLink(ownertype, ownername, projectref, runid, taskid) {
|
||||
let projectpath = (projectref.join("/") + ".proj")
|
||||
return { path: `/${ownertype}/${ownername}/projects/${projectpath}/runs/${runid}/tasks/${taskid}` }
|
||||
export function projectRunTaskLink(
|
||||
ownertype,
|
||||
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) {
|
||||
let path = projectGroupPath(ownertype, ownername, projectgroupref)
|
||||
return { path: `${path}/settings` }
|
||||
export function projectGroupSettingsLink(
|
||||
ownertype,
|
||||
ownername,
|
||||
projectgroupref
|
||||
) {
|
||||
let path = projectGroupPath(ownertype, ownername, projectgroupref);
|
||||
return { path: `${path}/settings` };
|
||||
}
|
||||
|
||||
export function projectSettingsLink(ownertype, ownername, projectref) {
|
||||
let projectpath = (projectref.join("/") + ".proj")
|
||||
return { path: `/${ownertype}/${ownername}/projects/${projectpath}/settings` }
|
||||
let projectpath = projectref.join('/') + '.proj';
|
||||
return {
|
||||
path: `/${ownertype}/${ownername}/projects/${projectpath}/settings`,
|
||||
};
|
||||
}
|
||||
|
||||
export function projectGroupCreateProjectGroupLink(ownertype, ownername, projectgroupref) {
|
||||
let path = projectGroupPath(ownertype, ownername, projectgroupref)
|
||||
return { path: `${path}/createprojectgroup` }
|
||||
export function projectGroupCreateProjectGroupLink(
|
||||
ownertype,
|
||||
ownername,
|
||||
projectgroupref
|
||||
) {
|
||||
let path = projectGroupPath(ownertype, ownername, projectgroupref);
|
||||
return { path: `${path}/createprojectgroup` };
|
||||
}
|
||||
|
||||
export function projectGroupCreateProjectLink(ownertype, ownername, projectgroupref) {
|
||||
let path = projectGroupPath(ownertype, ownername, projectgroupref)
|
||||
return { path: `${path}/createproject` }
|
||||
export function projectGroupCreateProjectLink(
|
||||
ownertype,
|
||||
ownername,
|
||||
projectgroupref
|
||||
) {
|
||||
let path = projectGroupPath(ownertype, ownername, projectgroupref);
|
||||
return { path: `${path}/createproject` };
|
||||
}
|
|
@ -1,11 +1,10 @@
|
|||
|
||||
export function runStatus(run) {
|
||||
// * if the run has a result then return the result
|
||||
// * if stopping return "stopping"
|
||||
// * return the phase
|
||||
if (run.result != "unknown") return run.result;
|
||||
if (run.stopping) return "stopping";
|
||||
if (run.phase != "finished") return run.phase;
|
||||
if (run.result != 'unknown') return run.result;
|
||||
if (run.stopping) return 'stopping';
|
||||
if (run.phase != 'finished') return run.phase;
|
||||
|
||||
return run.result;
|
||||
}
|
||||
|
@ -13,13 +12,13 @@ export function runStatus(run) {
|
|||
export function runResultClass(run) {
|
||||
let status = runStatus(run);
|
||||
|
||||
if (status == "setuperror") return "setuperror";
|
||||
if (status == "queued") return "unknown";
|
||||
if (status == "cancelled") return "failed";
|
||||
if (status == "running") return "running";
|
||||
if (status == "stopping") return "failed";
|
||||
if (status == "stopped") return "failed";
|
||||
if (status == "success") return "success";
|
||||
if (status == "failed") return "failed";
|
||||
return "unknown";
|
||||
if (status == 'setuperror') return 'setuperror';
|
||||
if (status == 'queued') return 'unknown';
|
||||
if (status == 'cancelled') return 'failed';
|
||||
if (status == 'running') return 'running';
|
||||
if (status == 'stopping') return 'failed';
|
||||
if (status == 'stopped') return 'failed';
|
||||
if (status == 'success') return 'success';
|
||||
if (status == 'failed') return 'failed';
|
||||
return 'unknown';
|
||||
}
|
|
@ -13,36 +13,44 @@
|
|||
v-if="remotesource.auth_type == 'password'"
|
||||
action="Add Linked Account"
|
||||
:name="remotesource.name"
|
||||
v-on:login="doAddLinkedAccount(remotesource.name, $event.username, $event.password)"
|
||||
v-on:login="
|
||||
doAddLinkedAccount(
|
||||
remotesource.name,
|
||||
$event.username,
|
||||
$event.password
|
||||
)
|
||||
"
|
||||
/>
|
||||
<button
|
||||
v-else
|
||||
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
|
||||
@click="doAddLinkedAccount(remotesource.name)"
|
||||
>Add Linked Account with {{remotesource.name}}</button>
|
||||
>
|
||||
Add Linked Account with {{ remotesource.name }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<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 {
|
||||
name: "AddLinkedAccount",
|
||||
name: 'AddLinkedAccount',
|
||||
props: {
|
||||
username: String,
|
||||
remoteSourceName: String
|
||||
remoteSourceName: String,
|
||||
},
|
||||
components: {
|
||||
LoginForm
|
||||
LoginForm,
|
||||
},
|
||||
data: function() {
|
||||
data: function () {
|
||||
return {
|
||||
addLinkedAccountError: null,
|
||||
remotesource: null
|
||||
remotesource: null,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
|
@ -52,7 +60,7 @@ export default {
|
|||
async fetchRemoteSources() {
|
||||
let { data, error } = await fetchRemoteSources();
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
this.$store.dispatch('setError', error);
|
||||
return;
|
||||
}
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
|
@ -79,17 +87,13 @@ export default {
|
|||
return;
|
||||
}
|
||||
this.$router.push({
|
||||
name: "user settings",
|
||||
params: { username: this.username }
|
||||
name: 'user settings',
|
||||
params: { username: this.username },
|
||||
});
|
||||
}
|
||||
},
|
||||
created: function() {
|
||||
},
|
||||
created: function () {
|
||||
this.fetchRemoteSources();
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -8,13 +8,9 @@
|
|||
<span class="block sm:inline">{{ error }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<div >
|
||||
<div
|
||||
class="flex justify-center items-center w-max"
|
||||
>
|
||||
<CreateSourceForm
|
||||
v-on:createSource="createSource($event)"
|
||||
/>
|
||||
<div>
|
||||
<div class="flex justify-center items-center w-max">
|
||||
<CreateSourceForm v-on:createSource="createSource($event)" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -22,40 +18,53 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import CreateSourceForm from "@/components/createsourceform";
|
||||
import { createRemoteSource } from "@/util/data.js";
|
||||
import router from "@/router";
|
||||
import CreateSourceForm from '@/components/createsourceform';
|
||||
import { createRemoteSource } from '@/util/data.js';
|
||||
import router from '@/router';
|
||||
|
||||
export default {
|
||||
name: "CreateSource",
|
||||
name: 'CreateSource',
|
||||
components: {
|
||||
CreateSourceForm
|
||||
CreateSourceForm,
|
||||
},
|
||||
data: function() {
|
||||
data: function () {
|
||||
return {
|
||||
error: null,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
async createSource({
|
||||
token, name, type, clientId, clientSecret, url, skipVerify, sshHostKey,
|
||||
token,
|
||||
name,
|
||||
type,
|
||||
clientId,
|
||||
clientSecret,
|
||||
url,
|
||||
skipVerify,
|
||||
sshHostKey,
|
||||
skipSshHostKeyCheck,
|
||||
}) {
|
||||
const res = await createRemoteSource(
|
||||
token, type, name, clientId, clientSecret, url, "oauth2", skipVerify,
|
||||
sshHostKey, skipSshHostKeyCheck, true, true, undefined,
|
||||
token,
|
||||
type,
|
||||
name,
|
||||
clientId,
|
||||
clientSecret,
|
||||
url,
|
||||
'oauth2',
|
||||
skipVerify,
|
||||
sshHostKey,
|
||||
skipSshHostKeyCheck,
|
||||
true,
|
||||
true,
|
||||
undefined
|
||||
);
|
||||
if (res.error)
|
||||
this.$store.dispatch("setError", res.error);
|
||||
else
|
||||
router.push({name: "login"});
|
||||
}
|
||||
if (res.error) this.$store.dispatch('setError', res.error);
|
||||
else router.push({ name: 'login' });
|
||||
},
|
||||
mounted: function() {
|
||||
this.$store.dispatch("setError", null);
|
||||
},
|
||||
mounted: function () {
|
||||
this.$store.dispatch('setError', null);
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
|
|
|
@ -1,25 +1,15 @@
|
|||
<template>
|
||||
<div class="home flex flex-col items-center">
|
||||
<img
|
||||
class="w-64 h-64"
|
||||
src="/img/agola-logo-name.svg" alt="agola logo"
|
||||
/>
|
||||
<img class="w-64 h-64" src="/img/agola-logo-name.svg" alt="agola logo" />
|
||||
<h1 class="text-2xl">CI/CD redefined</h1>
|
||||
<div class="m-8">
|
||||
<h1 class="text-lg">
|
||||
Hi, you are almost ready to go! Just
|
||||
<router-link
|
||||
class="underline text-blue-600"
|
||||
to="/login"
|
||||
>
|
||||
<router-link class="underline text-blue-600" to="/login">
|
||||
login
|
||||
</router-link>
|
||||
into your account
|
||||
or create a
|
||||
<router-link
|
||||
class="underline text-blue-600"
|
||||
to="/register"
|
||||
>
|
||||
into your account or create a
|
||||
<router-link class="underline text-blue-600" to="/register">
|
||||
new one
|
||||
</router-link>
|
||||
</h1>
|
||||
|
@ -28,22 +18,22 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from "vuex";
|
||||
import { mapGetters } from 'vuex';
|
||||
|
||||
export default {
|
||||
name: "Home",
|
||||
name: 'Home',
|
||||
components: {},
|
||||
computed: {
|
||||
...mapGetters(["user"])
|
||||
...mapGetters(['user']),
|
||||
},
|
||||
created: function() {
|
||||
created: function () {
|
||||
let user = this.$store.getters.user;
|
||||
if (user) {
|
||||
this.$router.push({
|
||||
name: "user",
|
||||
params: { username: this.user.username }
|
||||
name: 'user',
|
||||
params: { username: this.user.username },
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -13,13 +13,8 @@
|
|||
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
||||
>
|
||||
No remote sources defined
|
||||
<router-link
|
||||
class="underline text-blue-600 block"
|
||||
to="/newsource"
|
||||
>
|
||||
<button class="btn btn-blue">
|
||||
Create one
|
||||
</button>
|
||||
<router-link class="underline text-blue-600 block" to="/newsource">
|
||||
<button class="btn btn-blue">Create one</button>
|
||||
</router-link>
|
||||
</div>
|
||||
<div
|
||||
|
@ -61,25 +56,25 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchRemoteSources, login } from "@/util/data";
|
||||
import { fetchRemoteSources, login } from '@/util/data';
|
||||
import {
|
||||
setLoggedUser,
|
||||
unsetLoginRedirect,
|
||||
setLoginRedirect,
|
||||
doLogout
|
||||
} from "@/util/auth";
|
||||
doLogout,
|
||||
} from '@/util/auth';
|
||||
|
||||
import LoginForm from "@/components/loginform";
|
||||
import LoginForm from '@/components/loginform';
|
||||
|
||||
export default {
|
||||
name: "Login",
|
||||
name: 'Login',
|
||||
components: {
|
||||
LoginForm
|
||||
LoginForm,
|
||||
},
|
||||
data: function() {
|
||||
data: function () {
|
||||
return {
|
||||
error: null,
|
||||
remotesources: null
|
||||
remotesources: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -96,20 +91,20 @@ export default {
|
|||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async fetchRemoteSources() {
|
||||
let { data, error } = await fetchRemoteSources();
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
this.$store.dispatch('setError', error);
|
||||
return;
|
||||
}
|
||||
this.remotesources = data;
|
||||
},
|
||||
async doLogin(username, password, remotesourcename) {
|
||||
unsetLoginRedirect();
|
||||
let redirect = this.$route.query["redirect"];
|
||||
let redirect = this.$route.query['redirect'];
|
||||
|
||||
this.error = null;
|
||||
|
||||
|
@ -131,18 +126,16 @@ export default {
|
|||
unsetLoginRedirect();
|
||||
this.$router.push(redirect);
|
||||
} else {
|
||||
this.$router.push({ name: "home" });
|
||||
}
|
||||
this.$router.push({ name: 'home' });
|
||||
}
|
||||
},
|
||||
mounted: function() {
|
||||
this.$store.dispatch("setError", null);
|
||||
},
|
||||
created: function() {
|
||||
mounted: function () {
|
||||
this.$store.dispatch('setError', null);
|
||||
},
|
||||
created: function () {
|
||||
doLogout();
|
||||
this.fetchRemoteSources();
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
<script>
|
||||
import { doLogout } from "@/util/auth";
|
||||
import { doLogout } from '@/util/auth';
|
||||
|
||||
export default {
|
||||
name: "Logout",
|
||||
created: function() {
|
||||
name: 'Logout',
|
||||
created: function () {
|
||||
doLogout();
|
||||
this.$router.push("/");
|
||||
}
|
||||
this.$router.push('/');
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
|
|
|
@ -11,32 +11,32 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { fetch } from "@/util/data";
|
||||
import { fetch } from '@/util/data';
|
||||
|
||||
import {
|
||||
oauth2callbackurl,
|
||||
setLoggedUser,
|
||||
unsetLoginRedirect,
|
||||
getLoginRedirect
|
||||
} from "@/util/auth";
|
||||
getLoginRedirect,
|
||||
} from '@/util/auth';
|
||||
|
||||
export default {
|
||||
components: {},
|
||||
name: "Oauth2",
|
||||
name: 'Oauth2',
|
||||
props: {},
|
||||
data() {
|
||||
return {
|
||||
error: null,
|
||||
run: null,
|
||||
code: this.$route.query.code,
|
||||
username: null
|
||||
username: null,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
async doOauth2() {
|
||||
let u = oauth2callbackurl();
|
||||
u.searchParams.append("code", this.$route.query.code);
|
||||
u.searchParams.append("state", this.$route.query.state);
|
||||
u.searchParams.append('code', this.$route.query.code);
|
||||
u.searchParams.append('state', this.$route.query.state);
|
||||
let { data, error } = await fetch(u);
|
||||
if (error) {
|
||||
// set local login error on failed oauth2.
|
||||
|
@ -44,29 +44,28 @@ export default {
|
|||
return;
|
||||
}
|
||||
|
||||
if (data.request_type === "loginuser") {
|
||||
if (data.request_type === 'loginuser') {
|
||||
setLoggedUser(data.response.token, data.response.user);
|
||||
let redirect = getLoginRedirect(redirect);
|
||||
if (redirect) {
|
||||
unsetLoginRedirect();
|
||||
this.$router.push(redirect);
|
||||
} else {
|
||||
this.$router.push({ name: "home" });
|
||||
this.$router.push({ name: 'home' });
|
||||
}
|
||||
} else if (data.request_type === "authorize") {
|
||||
this.$store.dispatch("setRegisterUser", data.response);
|
||||
this.$router.push("/register");
|
||||
} else if (data.request_type === "createuserla") {
|
||||
} else if (data.request_type === 'authorize') {
|
||||
this.$store.dispatch('setRegisterUser', data.response);
|
||||
this.$router.push('/register');
|
||||
} else if (data.request_type === 'createuserla') {
|
||||
this.$router.push({
|
||||
name: "user settings",
|
||||
params: { username: this.username }
|
||||
name: 'user settings',
|
||||
params: { username: this.username },
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
created: function() {
|
||||
},
|
||||
created: function () {
|
||||
this.doOauth2();
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -9,13 +9,15 @@
|
|||
<span class="mx-2">/</span>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="ownerLink('org', orgname)">{{orgname}}</router-link>
|
||||
<router-link :to="ownerLink('org', orgname)">{{
|
||||
orgname
|
||||
}}</router-link>
|
||||
</li>
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
<div class="mb-8 flex justify-between">
|
||||
<span class="text-3xl">{{orgname}}</span>
|
||||
<span class="text-3xl">{{ orgname }}</span>
|
||||
<createprojectbutton v-on:click="goToCreate($event)" />
|
||||
</div>
|
||||
|
||||
|
@ -23,7 +25,12 @@
|
|||
<ul class="flex-grow tab">
|
||||
<li
|
||||
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)">
|
||||
<i class="mr-1 mdi mdi-home" />
|
||||
|
@ -42,7 +49,13 @@
|
|||
<li
|
||||
v-if="$route.name.endsWith('org project group settings')"
|
||||
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, [])">
|
||||
<i class="mr-1 mdi mdi-settings" />
|
||||
|
@ -52,7 +65,9 @@
|
|||
<li
|
||||
v-if="$route.name.endsWith('org settings')"
|
||||
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)">
|
||||
<i class="mr-1 mdi mdi-settings" />
|
||||
|
@ -65,7 +80,7 @@
|
|||
<div class="relative">
|
||||
<div
|
||||
class="flex -mt-3"
|
||||
v-click-outside="() => dropdownActive = false"
|
||||
v-click-outside="() => (dropdownActive = false)"
|
||||
@click="dropdownActive = !dropdownActive"
|
||||
>
|
||||
<button
|
||||
|
@ -108,9 +123,8 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import * as vClickOutside from "v-click-outside-x";
|
||||
import * as vClickOutside from 'v-click-outside-x';
|
||||
|
||||
import {
|
||||
ownerLink,
|
||||
|
@ -119,23 +133,23 @@ import {
|
|||
orgMembersLink,
|
||||
projectGroupCreateProjectGroupLink,
|
||||
projectGroupCreateProjectLink,
|
||||
projectGroupSettingsLink
|
||||
} from "@/util/link.js";
|
||||
projectGroupSettingsLink,
|
||||
} from '@/util/link.js';
|
||||
|
||||
import createprojectbutton from "@/components/createprojectbutton.vue";
|
||||
import createprojectbutton from '@/components/createprojectbutton.vue';
|
||||
|
||||
export default {
|
||||
name: "Org",
|
||||
name: 'Org',
|
||||
components: { createprojectbutton },
|
||||
directives: {
|
||||
clickOutside: vClickOutside.directive
|
||||
clickOutside: vClickOutside.directive,
|
||||
},
|
||||
props: {
|
||||
orgname: String
|
||||
orgname: String,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dropdownActive: false
|
||||
dropdownActive: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
|
@ -147,19 +161,18 @@ export default {
|
|||
projectGroupCreateProjectLink: projectGroupCreateProjectLink,
|
||||
projectGroupSettingsLink: projectGroupSettingsLink,
|
||||
goToCreate(type) {
|
||||
if (type == "project") {
|
||||
if (type == 'project') {
|
||||
this.$router.push(
|
||||
projectGroupCreateProjectLink("org", this.orgname, [])
|
||||
projectGroupCreateProjectLink('org', this.orgname, [])
|
||||
);
|
||||
return;
|
||||
}
|
||||
this.$router.push(
|
||||
projectGroupCreateProjectGroupLink("org", this.orgname, [])
|
||||
projectGroupCreateProjectGroupLink('org', this.orgname, [])
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
<template>
|
||||
<div>
|
||||
<projbreadcrumbs :ownertype="ownertype" :ownername="ownername" :projectref="projectref" />
|
||||
<projbreadcrumbs
|
||||
:ownertype="ownertype"
|
||||
:ownername="ownername"
|
||||
:projectref="projectref"
|
||||
/>
|
||||
|
||||
<div class="mb-8">
|
||||
<span class="text-3xl">{{projectName()}}</span>
|
||||
<span class="text-3xl">{{ projectName() }}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between">
|
||||
|
@ -17,7 +21,13 @@
|
|||
</li>
|
||||
<li
|
||||
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)">
|
||||
<i class="mr-1 mdi mdi-asterisk" />
|
||||
|
@ -26,45 +36,84 @@
|
|||
</li>
|
||||
<li
|
||||
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" />
|
||||
<span>Branches</span>
|
||||
</router-link>
|
||||
</li>
|
||||
<li
|
||||
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" />
|
||||
<span>Tags</span>
|
||||
</router-link>
|
||||
</li>
|
||||
<li
|
||||
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" />
|
||||
<span>Pull Requests</span>
|
||||
</router-link>
|
||||
</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 />
|
||||
</li>
|
||||
<li
|
||||
class="tab-element"
|
||||
v-if="run && ($route.name.endsWith('project run') || $route.name.endsWith('project run task'))"
|
||||
:class="[{ 'tab-element-selected': $route.name.endsWith('project run') }]"
|
||||
v-if="
|
||||
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>
|
||||
Run
|
||||
<strong>#{{run.counter}}</strong>
|
||||
<strong>#{{ run.counter }}</strong>
|
||||
</p>
|
||||
</router-link>
|
||||
</li>
|
||||
|
@ -74,23 +123,41 @@
|
|||
<li
|
||||
class="tab-element"
|
||||
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
|
||||
:to="projectRunTaskLink(ownertype, ownername, projectref, $route.params.runid, $route.params.taskid)"
|
||||
:to="
|
||||
projectRunTaskLink(
|
||||
ownertype,
|
||||
ownername,
|
||||
projectref,
|
||||
$route.params.runid,
|
||||
$route.params.taskid
|
||||
)
|
||||
"
|
||||
>
|
||||
<p>
|
||||
Task
|
||||
<strong>{{run.tasks[$route.params.taskid].name}}</strong>
|
||||
<strong>{{ run.tasks[$route.params.taskid].name }}</strong>
|
||||
</p>
|
||||
</router-link>
|
||||
</li>
|
||||
<li
|
||||
v-if="$route.name.endsWith('project settings')"
|
||||
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" />
|
||||
<span>Project Settings</span>
|
||||
</router-link>
|
||||
|
@ -101,7 +168,7 @@
|
|||
<div class="relative">
|
||||
<div
|
||||
class="flex -mt-3"
|
||||
v-click-outside="() => dropdownActive = false"
|
||||
v-click-outside="() => (dropdownActive = false)"
|
||||
@click="dropdownActive = !dropdownActive"
|
||||
>
|
||||
<button
|
||||
|
@ -135,9 +202,8 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import * as vClickOutside from "v-click-outside-x";
|
||||
import * as vClickOutside from 'v-click-outside-x';
|
||||
|
||||
import {
|
||||
projectLink,
|
||||
|
@ -147,35 +213,35 @@ import {
|
|||
projectPRsRunsLink,
|
||||
projectRunLink,
|
||||
projectRunTaskLink,
|
||||
projectSettingsLink
|
||||
} from "@/util/link.js";
|
||||
projectSettingsLink,
|
||||
} from '@/util/link.js';
|
||||
|
||||
import { fetchRun } from "@/util/data.js";
|
||||
import { fetchRun } from '@/util/data.js';
|
||||
|
||||
import projbreadcrumbs from "@/components/projbreadcrumbs.vue";
|
||||
import tabarrow from "@/components/tabarrow.vue";
|
||||
import projbreadcrumbs from '@/components/projbreadcrumbs.vue';
|
||||
import tabarrow from '@/components/tabarrow.vue';
|
||||
|
||||
export default {
|
||||
name: "Project",
|
||||
name: 'Project',
|
||||
components: { projbreadcrumbs, tabarrow },
|
||||
directives: {
|
||||
clickOutside: vClickOutside.directive
|
||||
clickOutside: vClickOutside.directive,
|
||||
},
|
||||
props: {
|
||||
ownertype: String,
|
||||
ownername: String,
|
||||
projectref: Array
|
||||
projectref: Array,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
fetchAbort: null,
|
||||
|
||||
dropdownActive: false,
|
||||
run: null
|
||||
run: null,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
$route: async function(route) {
|
||||
$route: async function (route) {
|
||||
if (this.fetchAbort) {
|
||||
this.fetchAbort.abort();
|
||||
}
|
||||
|
@ -191,12 +257,12 @@ export default {
|
|||
return;
|
||||
}
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
this.$store.dispatch('setError', error);
|
||||
return;
|
||||
}
|
||||
this.run = data;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
projectLink: projectLink,
|
||||
|
@ -209,9 +275,9 @@ export default {
|
|||
projectSettingsLink: projectSettingsLink,
|
||||
projectName() {
|
||||
return this.projectref[this.projectref.length - 1];
|
||||
}
|
||||
},
|
||||
created: async function() {
|
||||
},
|
||||
created: async function () {
|
||||
this.fetchAbort = new AbortController();
|
||||
|
||||
if (this.$route.params.runid) {
|
||||
|
@ -223,7 +289,7 @@ export default {
|
|||
return;
|
||||
}
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
this.$store.dispatch('setError', error);
|
||||
return;
|
||||
}
|
||||
this.run = data;
|
||||
|
@ -233,9 +299,8 @@ export default {
|
|||
if (this.fetchAbort) {
|
||||
this.fetchAbort.abort();
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
<template>
|
||||
<div>
|
||||
<projbreadcrumbs
|
||||
|
@ -8,7 +7,7 @@
|
|||
/>
|
||||
|
||||
<div class="mb-8 flex justify-between">
|
||||
<span class="text-3xl">{{projectGroupName()}}</span>
|
||||
<span class="text-3xl">{{ projectGroupName() }}</span>
|
||||
<createprojectbutton v-on:click="goToCreate($event)" />
|
||||
</div>
|
||||
|
||||
|
@ -16,9 +15,19 @@
|
|||
<ul class="flex-grow tab">
|
||||
<li
|
||||
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" />
|
||||
<span>Projects</span>
|
||||
</router-link>
|
||||
|
@ -26,9 +35,19 @@
|
|||
<li
|
||||
v-if="$route.name.endsWith('project group settings')"
|
||||
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" />
|
||||
<span>Project Group Settings</span>
|
||||
</router-link>
|
||||
|
@ -39,7 +58,7 @@
|
|||
<div class="relative">
|
||||
<div
|
||||
class="flex -mt-3"
|
||||
v-click-outside="() => dropdownActive = false"
|
||||
v-click-outside="() => (dropdownActive = false)"
|
||||
@click="dropdownActive = !dropdownActive"
|
||||
>
|
||||
<button
|
||||
|
@ -57,7 +76,13 @@
|
|||
<li>
|
||||
<router-link
|
||||
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" />
|
||||
<span>Project Group Settings</span>
|
||||
|
@ -73,34 +98,33 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import * as vClickOutside from "v-click-outside-x";
|
||||
import * as vClickOutside from 'v-click-outside-x';
|
||||
|
||||
import {
|
||||
projectGroupProjectsLink,
|
||||
projectGroupSettingsLink,
|
||||
projectGroupCreateProjectGroupLink,
|
||||
projectGroupCreateProjectLink
|
||||
} from "@/util/link.js";
|
||||
projectGroupCreateProjectLink,
|
||||
} from '@/util/link.js';
|
||||
|
||||
import projbreadcrumbs from "@/components/projbreadcrumbs.vue";
|
||||
import createprojectbutton from "@/components/createprojectbutton.vue";
|
||||
import projbreadcrumbs from '@/components/projbreadcrumbs.vue';
|
||||
import createprojectbutton from '@/components/createprojectbutton.vue';
|
||||
|
||||
export default {
|
||||
name: "ProjectGroup",
|
||||
name: 'ProjectGroup',
|
||||
components: { projbreadcrumbs, createprojectbutton },
|
||||
directives: {
|
||||
clickOutside: vClickOutside.directive
|
||||
clickOutside: vClickOutside.directive,
|
||||
},
|
||||
props: {
|
||||
ownertype: String,
|
||||
ownername: String,
|
||||
projectgroupref: Array
|
||||
projectgroupref: Array,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dropdownActive: false
|
||||
dropdownActive: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
|
@ -110,12 +134,12 @@ export default {
|
|||
projectGroupCreateProjectLink: projectGroupCreateProjectLink,
|
||||
projectGroupName() {
|
||||
if (!this.projectgroupref.length) {
|
||||
return "Root Project Group";
|
||||
return 'Root Project Group';
|
||||
}
|
||||
return this.projectgroupref[this.projectgroupref.length - 1];
|
||||
},
|
||||
goToCreate(type) {
|
||||
if (type == "project") {
|
||||
if (type == 'project') {
|
||||
this.$router.push(
|
||||
projectGroupCreateProjectLink(
|
||||
this.ownertype,
|
||||
|
@ -132,10 +156,9 @@ export default {
|
|||
this.projectgroupref
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
|
@ -28,13 +28,8 @@
|
|||
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
||||
>
|
||||
No remote sources defined
|
||||
<router-link
|
||||
class="underline text-blue-600 block"
|
||||
to="/newsource"
|
||||
>
|
||||
<button class="btn btn-blue">
|
||||
Create one
|
||||
</button>
|
||||
<router-link class="underline text-blue-600 block" to="/newsource">
|
||||
<button class="btn btn-blue">Create one</button>
|
||||
</router-link>
|
||||
</div>
|
||||
<div
|
||||
|
@ -75,29 +70,29 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from "vuex";
|
||||
import { mapGetters } from 'vuex';
|
||||
|
||||
import LoginForm from "@/components/loginform";
|
||||
import RegisterForm from "@/components/registerform";
|
||||
import LoginForm from '@/components/loginform';
|
||||
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 {
|
||||
name: "Register",
|
||||
name: 'Register',
|
||||
components: {
|
||||
LoginForm,
|
||||
RegisterForm
|
||||
RegisterForm,
|
||||
},
|
||||
data: function() {
|
||||
data: function () {
|
||||
return {
|
||||
error: null,
|
||||
remotesources: null
|
||||
remotesources: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["registeruser"]),
|
||||
...mapGetters(['registeruser']),
|
||||
|
||||
hasRemoteSources() {
|
||||
if (this.remotesources) {
|
||||
|
@ -112,13 +107,13 @@ export default {
|
|||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async fetchRemoteSources() {
|
||||
let { data, error } = await fetchRemoteSources();
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
this.$store.dispatch('setError', error);
|
||||
return;
|
||||
}
|
||||
this.remotesources = data;
|
||||
|
@ -127,12 +122,12 @@ export default {
|
|||
let u = authorizeurl();
|
||||
let res = await (
|
||||
await fetch(u, {
|
||||
method: "POST",
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
remote_source_name: remotesourcename,
|
||||
login_name: username,
|
||||
password: password
|
||||
})
|
||||
password: password,
|
||||
}),
|
||||
})
|
||||
).json();
|
||||
|
||||
|
@ -140,11 +135,11 @@ export default {
|
|||
window.location = res.oauth2_redirect;
|
||||
return;
|
||||
}
|
||||
this.$store.dispatch("setRegisterUser", {
|
||||
this.$store.dispatch('setRegisterUser', {
|
||||
remote_user_info: res.remote_user_info,
|
||||
remote_source_name: res.remote_source_name,
|
||||
remote_source_login_name: username,
|
||||
remote_source_login_password: password
|
||||
remote_source_login_password: password,
|
||||
});
|
||||
},
|
||||
async doRegister(
|
||||
|
@ -170,18 +165,15 @@ export default {
|
|||
window.location = data.oauth2_redirect;
|
||||
return;
|
||||
}
|
||||
this.$router.push({ name: "home" });
|
||||
}
|
||||
this.$router.push({ name: 'home' });
|
||||
},
|
||||
mounted: function() {
|
||||
this.$store.dispatch("setError", null);
|
||||
},
|
||||
created: function() {
|
||||
mounted: function () {
|
||||
this.$store.dispatch('setError', null);
|
||||
},
|
||||
created: function () {
|
||||
doLogout();
|
||||
this.fetchRemoteSources();
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -9,13 +9,15 @@
|
|||
<span class="mx-2">/</span>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="ownerLink('user', username)">{{username}}</router-link>
|
||||
<router-link :to="ownerLink('user', username)">{{
|
||||
username
|
||||
}}</router-link>
|
||||
</li>
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
<div class="mb-8 flex justify-between">
|
||||
<span class="text-3xl">{{username}}</span>
|
||||
<span class="text-3xl">{{ username }}</span>
|
||||
<createprojectbutton v-on:click="goToCreate($event)" />
|
||||
</div>
|
||||
|
||||
|
@ -23,7 +25,12 @@
|
|||
<ul class="flex-grow tab">
|
||||
<li
|
||||
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)">
|
||||
<i class="mr-1 mdi mdi-home" />
|
||||
|
@ -32,7 +39,9 @@
|
|||
</li>
|
||||
<li
|
||||
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)">
|
||||
<i class="mr-1 mdi mdi-run-fast" />
|
||||
|
@ -40,19 +49,29 @@
|
|||
</router-link>
|
||||
</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 />
|
||||
</li>
|
||||
<li
|
||||
class="tab-element"
|
||||
v-if="run && ($route.name === 'user direct run' || $route.name == 'user direct run task')"
|
||||
:class="[{ 'tab-element-selected': $route.name === 'user direct run' }]"
|
||||
v-if="
|
||||
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)">
|
||||
<span>
|
||||
Run
|
||||
<strong>#{{run.counter}}</strong>
|
||||
<strong>#{{ run.counter }}</strong>
|
||||
</span>
|
||||
</router-link>
|
||||
</li>
|
||||
|
@ -62,21 +81,35 @@
|
|||
<li
|
||||
class="tab-element"
|
||||
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
|
||||
:to="userDirectRunTaskLink(username, $route.params.runid, $route.params.taskid)"
|
||||
:to="
|
||||
userDirectRunTaskLink(
|
||||
username,
|
||||
$route.params.runid,
|
||||
$route.params.taskid
|
||||
)
|
||||
"
|
||||
>
|
||||
<span>
|
||||
Task
|
||||
<strong>{{run.tasks[$route.params.taskid].name}}</strong>
|
||||
<strong>{{ run.tasks[$route.params.taskid].name }}</strong>
|
||||
</span>
|
||||
</router-link>
|
||||
</li>
|
||||
<li
|
||||
v-if="$route.name.endsWith('user project group settings')"
|
||||
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, [])">
|
||||
<i class="mr-1 mdi mdi-settings" />
|
||||
|
@ -86,7 +119,9 @@
|
|||
<li
|
||||
v-if="$route.name.endsWith('user settings')"
|
||||
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)">
|
||||
<i class="mr-1 mdi mdi-settings" />
|
||||
|
@ -99,7 +134,7 @@
|
|||
<div class="relative">
|
||||
<div
|
||||
class="flex -mt-3"
|
||||
v-click-outside="() => dropdownActive = false"
|
||||
v-click-outside="() => (dropdownActive = false)"
|
||||
@click="dropdownActive = !dropdownActive"
|
||||
>
|
||||
<button
|
||||
|
@ -134,7 +169,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import * as vClickOutside from "v-click-outside-x";
|
||||
import * as vClickOutside from 'v-click-outside-x';
|
||||
|
||||
import {
|
||||
ownerLink,
|
||||
|
@ -145,33 +180,33 @@ import {
|
|||
ownerSettingsLink,
|
||||
projectGroupCreateProjectGroupLink,
|
||||
projectGroupCreateProjectLink,
|
||||
projectGroupSettingsLink
|
||||
} from "@/util/link.js";
|
||||
projectGroupSettingsLink,
|
||||
} from '@/util/link.js';
|
||||
|
||||
import { fetchRun } from "@/util/data.js";
|
||||
import { fetchRun } from '@/util/data.js';
|
||||
|
||||
import createprojectbutton from "@/components/createprojectbutton.vue";
|
||||
import tabarrow from "@/components/tabarrow.vue";
|
||||
import createprojectbutton from '@/components/createprojectbutton.vue';
|
||||
import tabarrow from '@/components/tabarrow.vue';
|
||||
|
||||
export default {
|
||||
name: "User",
|
||||
name: 'User',
|
||||
components: { createprojectbutton, tabarrow },
|
||||
directives: {
|
||||
clickOutside: vClickOutside.directive
|
||||
clickOutside: vClickOutside.directive,
|
||||
},
|
||||
props: {
|
||||
username: String
|
||||
username: String,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
fetchAbort: null,
|
||||
|
||||
dropdownActive: false,
|
||||
run: null
|
||||
run: null,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
$route: async function(route) {
|
||||
$route: async function (route) {
|
||||
if (this.fetchAbort) {
|
||||
this.fetchAbort.abort();
|
||||
}
|
||||
|
@ -187,12 +222,12 @@ export default {
|
|||
return;
|
||||
}
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
this.$store.dispatch('setError', error);
|
||||
return;
|
||||
}
|
||||
this.run = data;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
ownerLink: ownerLink,
|
||||
|
@ -205,18 +240,18 @@ export default {
|
|||
projectGroupCreateProjectLink: projectGroupCreateProjectLink,
|
||||
projectGroupSettingsLink: projectGroupSettingsLink,
|
||||
goToCreate(type) {
|
||||
if (type == "project") {
|
||||
if (type == 'project') {
|
||||
this.$router.push(
|
||||
projectGroupCreateProjectLink("user", this.username, [])
|
||||
projectGroupCreateProjectLink('user', this.username, [])
|
||||
);
|
||||
return;
|
||||
}
|
||||
this.$router.push(
|
||||
projectGroupCreateProjectGroupLink("user", this.username, [])
|
||||
projectGroupCreateProjectGroupLink('user', this.username, [])
|
||||
);
|
||||
}
|
||||
},
|
||||
created: async function() {
|
||||
},
|
||||
created: async function () {
|
||||
this.fetchAbort = new AbortController();
|
||||
|
||||
if (this.$route.params.runid) {
|
||||
|
@ -228,7 +263,7 @@ export default {
|
|||
return;
|
||||
}
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
this.$store.dispatch('setError', error);
|
||||
return;
|
||||
}
|
||||
this.run = data;
|
||||
|
@ -238,9 +273,8 @@ export default {
|
|||
if (this.fetchAbort) {
|
||||
this.fetchAbort.abort();
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
<style scoped lang="scss"></style>
|
||||
|
|
75
tailwind.js
75
tailwind.js
|
@ -6,43 +6,54 @@ module.exports = {
|
|||
padding: '2rem',
|
||||
},
|
||||
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: {
|
||||
default: '1px',
|
||||
'0': '0',
|
||||
'2': '2px',
|
||||
'4': '4px',
|
||||
'5': '5px',
|
||||
'6': '6px',
|
||||
0: '0',
|
||||
2: '2px',
|
||||
4: '4px',
|
||||
5: '5px',
|
||||
6: '6px',
|
||||
},
|
||||
spacing: {
|
||||
px: '1px',
|
||||
'2px': '2px',
|
||||
'3px': '3px',
|
||||
'0': '0',
|
||||
'1': '0.25rem',
|
||||
'2': '0.5rem',
|
||||
'3': '0.75rem',
|
||||
'4': '1rem',
|
||||
'5': '1.25rem',
|
||||
'6': '1.5rem',
|
||||
'8': '2rem',
|
||||
'10': '2.5rem',
|
||||
'12': '3rem',
|
||||
'16': '4rem',
|
||||
'20': '5rem',
|
||||
'24': '6rem',
|
||||
'32': '8rem',
|
||||
'40': '10rem',
|
||||
'48': '12rem',
|
||||
'56': '14rem',
|
||||
'64': '16rem',
|
||||
0: '0',
|
||||
1: '0.25rem',
|
||||
2: '0.5rem',
|
||||
3: '0.75rem',
|
||||
4: '1rem',
|
||||
5: '1.25rem',
|
||||
6: '1.5rem',
|
||||
8: '2rem',
|
||||
10: '2.5rem',
|
||||
12: '3rem',
|
||||
16: '4rem',
|
||||
20: '5rem',
|
||||
24: '6rem',
|
||||
32: '8rem',
|
||||
40: '10rem',
|
||||
48: '12rem',
|
||||
56: '14rem',
|
||||
64: '16rem',
|
||||
},
|
||||
colors: {
|
||||
dark: '#4a4a4a',
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
variants: {
|
||||
backgroundColor: ['responsive', 'hover', 'focus', 'disabled'],
|
||||
|
@ -56,9 +67,9 @@ module.exports = {
|
|||
function ({ addVariant, e }) {
|
||||
addVariant('disabled', ({ modifySelectors, separator }) => {
|
||||
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 = {
|
||||
css: {
|
||||
sourceMap: true
|
||||
}
|
||||
sourceMap: true,
|
||||
},
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue