*: 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 = {
|
module.exports = {
|
||||||
presets: [
|
presets: ['@vue/cli-plugin-babel/preset'],
|
||||||
'@vue/cli-plugin-babel/preset'
|
};
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,12 +2,8 @@
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"paths": {
|
"paths": {
|
||||||
"*": [
|
"*": ["types/*"]
|
||||||
"types/*"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"include": [
|
"include": ["./src/**/*"]
|
||||||
"./src/**/*"
|
|
||||||
]
|
|
||||||
}
|
}
|
|
@ -1977,6 +1977,13 @@
|
||||||
"yallist": "^2.1.2"
|
"yallist": "^2.1.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"prettier": {
|
||||||
|
"version": "1.19.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz",
|
||||||
|
"integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"source-map": {
|
"source-map": {
|
||||||
"version": "0.6.1",
|
"version": "0.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||||
|
@ -9849,11 +9856,10 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"prettier": {
|
"prettier": {
|
||||||
"version": "1.19.1",
|
"version": "2.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz",
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz",
|
||||||
"integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==",
|
"integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"pretty-error": {
|
"pretty-error": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
"eslint": "^6.7.2",
|
"eslint": "^6.7.2",
|
||||||
"eslint-plugin-vue": "^6.2.2",
|
"eslint-plugin-vue": "^6.2.2",
|
||||||
"node-sass": "^4.14.1",
|
"node-sass": "^4.14.1",
|
||||||
|
"prettier": "2.5.1",
|
||||||
"sass-loader": "^8.0.2",
|
"sass-loader": "^8.0.2",
|
||||||
"tailwindcss": "^1.9.6",
|
"tailwindcss": "^1.9.6",
|
||||||
"vue-template-compiler": "^2.6.12"
|
"vue-template-compiler": "^2.6.12"
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
"plugins": [
|
plugins: [require('tailwindcss')('tailwind.js'), require('autoprefixer')()],
|
||||||
require('tailwindcss')('tailwind.js'),
|
};
|
||||||
require('autoprefixer')(),
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
61
src/App.vue
61
src/App.vue
|
@ -1,7 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<nav class="bg-gray-800 p-3 text-white">
|
<nav class="bg-gray-800 p-3 text-white">
|
||||||
<div class="container flex items-center justify-between flex-wrap bg-gray-800">
|
<div
|
||||||
|
class="container flex items-center justify-between flex-wrap bg-gray-800"
|
||||||
|
>
|
||||||
<div class="mr-6">
|
<div class="mr-6">
|
||||||
<router-link
|
<router-link
|
||||||
class="font-semibold flex items-center flex-shrink-0 text-xl tracking-tight"
|
class="font-semibold flex items-center flex-shrink-0 text-xl tracking-tight"
|
||||||
|
@ -28,12 +30,12 @@
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="w-full block flex-grow lg:flex lg:items-center lg:w-auto"
|
class="w-full block flex-grow lg:flex lg:items-center lg:w-auto"
|
||||||
:class="{'hidden' : !navActive}"
|
:class="{ hidden: !navActive }"
|
||||||
>
|
>
|
||||||
<div class="text-sm lg:flex-grow"></div>
|
<div class="text-sm lg:flex-grow"></div>
|
||||||
<div v-if="user" class="relative mr-3">
|
<div v-if="user" class="relative mr-3">
|
||||||
<button
|
<button
|
||||||
v-click-outside="() => createDropdownActive = false"
|
v-click-outside="() => (createDropdownActive = false)"
|
||||||
@click="createDropdownActive = !createDropdownActive"
|
@click="createDropdownActive = !createDropdownActive"
|
||||||
class="relative flex items-center focus:outline-none"
|
class="relative flex items-center focus:outline-none"
|
||||||
>
|
>
|
||||||
|
@ -49,7 +51,8 @@
|
||||||
<router-link
|
<router-link
|
||||||
class="block px-4 py-2 hover:bg-blue-500 hover:text-white"
|
class="block px-4 py-2 hover:bg-blue-500 hover:text-white"
|
||||||
to="/neworganization"
|
to="/neworganization"
|
||||||
>New Organization</router-link>
|
>New Organization</router-link
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -57,7 +60,7 @@
|
||||||
<div v-if="user" class="relative">
|
<div v-if="user" class="relative">
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<button
|
<button
|
||||||
v-click-outside="() => userDropdownActive = false"
|
v-click-outside="() => (userDropdownActive = false)"
|
||||||
@click="userDropdownActive = !userDropdownActive"
|
@click="userDropdownActive = !userDropdownActive"
|
||||||
class="relative flex items-center focus:outline-none"
|
class="relative flex items-center focus:outline-none"
|
||||||
>
|
>
|
||||||
|
@ -98,18 +101,30 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="navbar-item">
|
<div v-else class="navbar-item">
|
||||||
<router-link class="btn btn-blue" to="/register">Sign up</router-link>
|
<router-link class="btn btn-blue" to="/register"
|
||||||
<router-link class="ml-2 btn btn-blue" to="/login">Login</router-link>
|
>Sign up</router-link
|
||||||
|
>
|
||||||
|
<router-link class="ml-2 btn btn-blue" to="/login"
|
||||||
|
>Login</router-link
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div v-if="error" class="container h-screen" role="alert">
|
<div v-if="error" class="container h-screen" role="alert">
|
||||||
<div v-if="error" class="h-full flex justify-center items-center" role="alert">
|
<div
|
||||||
|
v-if="error"
|
||||||
|
class="h-full flex justify-center items-center"
|
||||||
|
role="alert"
|
||||||
|
>
|
||||||
<div v-if="error" class="w-full" role="alert">
|
<div v-if="error" class="w-full" role="alert">
|
||||||
<div class="bg-red-500 text-white font-bold rounded-t px-4 py-2">Error</div>
|
<div class="bg-red-500 text-white font-bold rounded-t px-4 py-2">
|
||||||
<div class="border border-t-0 border-red-400 rounded-b bg-red-100 px-4 py-3 text-red-700">
|
Error
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="border border-t-0 border-red-400 rounded-b bg-red-100 px-4 py-3 text-red-700"
|
||||||
|
>
|
||||||
<p class="mb-8">Failed to fetch data: {{ error }}</p>
|
<p class="mb-8">Failed to fetch data: {{ error }}</p>
|
||||||
<button class="btn btn-red" @click="reload()">Retry</button>
|
<button class="btn btn-red" @click="reload()">Retry</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -123,48 +138,46 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as vClickOutside from "v-click-outside-x";
|
import * as vClickOutside from 'v-click-outside-x';
|
||||||
|
|
||||||
import { mapGetters } from "vuex";
|
import { mapGetters } from 'vuex';
|
||||||
|
|
||||||
import { ownerSettingsLink } from "@/util/link.js";
|
import { ownerSettingsLink } from '@/util/link.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "App",
|
name: 'App',
|
||||||
directives: {
|
directives: {
|
||||||
clickOutside: vClickOutside.directive
|
clickOutside: vClickOutside.directive,
|
||||||
},
|
},
|
||||||
components: {},
|
components: {},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(["error", "user"])
|
...mapGetters(['error', 'user']),
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
routerActive: true,
|
routerActive: true,
|
||||||
navActive: false,
|
navActive: false,
|
||||||
userDropdownActive: false,
|
userDropdownActive: false,
|
||||||
createDropdownActive: false
|
createDropdownActive: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
$route: function () {
|
$route: function () {
|
||||||
this.userDropdownActive = false;
|
this.userDropdownActive = false;
|
||||||
this.createDropdownActive = false;
|
this.createDropdownActive = false;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
// method to reload current view from https://github.com/vuejs/vue-router/issues/296#issuecomment-356530037
|
// method to reload current view from https://github.com/vuejs/vue-router/issues/296#issuecomment-356530037
|
||||||
methods: {
|
methods: {
|
||||||
ownerSettingsLink: ownerSettingsLink,
|
ownerSettingsLink: ownerSettingsLink,
|
||||||
reload() {
|
reload() {
|
||||||
this.$store.dispatch("setError", null);
|
this.$store.dispatch('setError', null);
|
||||||
this.routerActive = false;
|
this.routerActive = false;
|
||||||
this.$nextTick(() => (this.routerActive = true));
|
this.$nextTick(() => (this.routerActive = true));
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
|
@ -8,19 +8,21 @@
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Organization name"
|
placeholder="Organization name"
|
||||||
v-model="orgName"
|
v-model="orgName"
|
||||||
>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" v-model="orgIsPrivate">
|
<input type="checkbox" v-model="orgIsPrivate" />
|
||||||
Private
|
Private
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
|
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
|
||||||
@click="createOrg()"
|
@click="createOrg()"
|
||||||
>Create Organization</button>
|
>
|
||||||
|
Create Organization
|
||||||
|
</button>
|
||||||
<div
|
<div
|
||||||
v-if="createOrgError"
|
v-if="createOrgError"
|
||||||
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
||||||
|
@ -32,19 +34,19 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { createOrganization } from "@/util/data.js";
|
import { createOrganization } from '@/util/data.js';
|
||||||
|
|
||||||
import { ownerLink } from "@/util/link.js";
|
import { ownerLink } from '@/util/link.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: {},
|
||||||
name: "createorganization",
|
name: 'createorganization',
|
||||||
props: {},
|
props: {},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
createOrgError: null,
|
createOrgError: null,
|
||||||
orgIsPrivate: false,
|
orgIsPrivate: false,
|
||||||
orgName: null
|
orgName: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -54,9 +56,9 @@ export default {
|
||||||
async createOrg() {
|
async createOrg() {
|
||||||
this.resetErrors();
|
this.resetErrors();
|
||||||
|
|
||||||
let visibility = "public";
|
let visibility = 'public';
|
||||||
if (this.orgIsPrivate) {
|
if (this.orgIsPrivate) {
|
||||||
visibility = "private";
|
visibility = 'private';
|
||||||
}
|
}
|
||||||
|
|
||||||
let { error } = await createOrganization(this.orgName, visibility);
|
let { error } = await createOrganization(this.orgName, visibility);
|
||||||
|
@ -65,14 +67,11 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$router.push(ownerLink("org", this.orgName));
|
this.$router.push(ownerLink('org', this.orgName));
|
||||||
}
|
|
||||||
},
|
},
|
||||||
created: async function() {}
|
},
|
||||||
|
created: async function () {},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,17 +7,18 @@
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Project Name"
|
placeholder="Project Name"
|
||||||
v-model="projectName"
|
v-model="projectName"
|
||||||
>
|
/>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" v-model="projectIsPrivate">
|
<input type="checkbox" v-model="projectIsPrivate" />
|
||||||
Private
|
Private
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label class="checkbox">
|
<label class="checkbox">
|
||||||
<input type="checkbox" v-model="pass_vars_to_forked_pr" />
|
<input type="checkbox" v-model="pass_vars_to_forked_pr" />
|
||||||
Pass variables to run even if triggered by PR from forked repo (DANGEROUS)
|
Pass variables to run even if triggered by PR from forked repo
|
||||||
|
(DANGEROUS)
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3 flex items-center">
|
<div class="mb-3 flex items-center">
|
||||||
|
@ -31,31 +32,48 @@
|
||||||
v-for="(rs, index) in remoteSources"
|
v-for="(rs, index) in remoteSources"
|
||||||
v-bind:key="rs.id"
|
v-bind:key="rs.id"
|
||||||
:value="index"
|
:value="index"
|
||||||
>{{ rs.name }}</option>
|
>
|
||||||
|
{{ rs.name }}
|
||||||
|
</option>
|
||||||
</select>
|
</select>
|
||||||
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2">
|
<div
|
||||||
<svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
|
class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2"
|
||||||
<path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"></path>
|
>
|
||||||
|
<svg
|
||||||
|
class="fill-current h-4 w-4"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"
|
||||||
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
class="ml-3 btn btn-blue"
|
class="ml-3 btn btn-blue"
|
||||||
v-bind:class="{ 'spinner': fetchRemoteReposLoading }"
|
v-bind:class="{ spinner: fetchRemoteReposLoading }"
|
||||||
:disabled="selectedRemoteSourceIndex == null"
|
:disabled="selectedRemoteSourceIndex == null"
|
||||||
@click="fetchRemoteRepos()"
|
@click="fetchRemoteRepos()"
|
||||||
>Fetch remote repositories</button>
|
>
|
||||||
|
Fetch remote repositories
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="remoteRepos.length">
|
<div v-if="remoteRepos.length">
|
||||||
<h4 class="text-xl">Available remote repositories</h4>
|
<h4 class="text-xl">Available remote repositories</h4>
|
||||||
<remoterepos :remoterepos="remoteRepos" v-on:reposelected="repoSelected($event)"/>
|
<remoterepos
|
||||||
|
:remoterepos="remoteRepos"
|
||||||
|
v-on:reposelected="repoSelected($event)"
|
||||||
|
/>
|
||||||
<button
|
<button
|
||||||
class="btn btn-blue"
|
class="btn btn-blue"
|
||||||
v-bind:class="{ 'spinner': createProjectLoading }"
|
v-bind:class="{ spinner: createProjectLoading }"
|
||||||
:disabled="!createProjectButtonEnabled"
|
:disabled="!createProjectButtonEnabled"
|
||||||
@click="createProject()"
|
@click="createProject()"
|
||||||
>Create Project</button>
|
>
|
||||||
|
Create Project
|
||||||
|
</button>
|
||||||
<div
|
<div
|
||||||
v-if="createProjectError"
|
v-if="createProjectError"
|
||||||
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
||||||
|
@ -72,20 +90,20 @@ import {
|
||||||
fetchCurrentUser,
|
fetchCurrentUser,
|
||||||
fetchRemoteSources,
|
fetchRemoteSources,
|
||||||
createProject,
|
createProject,
|
||||||
userRemoteRepos
|
userRemoteRepos,
|
||||||
} from "@/util/data.js";
|
} from '@/util/data.js';
|
||||||
|
|
||||||
import { projectLink } from "@/util/link.js";
|
import { projectLink } from '@/util/link.js';
|
||||||
|
|
||||||
import remoterepos from "@/components/remoterepos.vue";
|
import remoterepos from '@/components/remoterepos.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { remoterepos },
|
components: { remoterepos },
|
||||||
name: "createproject",
|
name: 'createproject',
|
||||||
props: {
|
props: {
|
||||||
ownertype: String,
|
ownertype: String,
|
||||||
ownername: String,
|
ownername: String,
|
||||||
projectgroupref: Array
|
projectgroupref: Array,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -98,15 +116,15 @@ export default {
|
||||||
remoteSources: null,
|
remoteSources: null,
|
||||||
remoteRepos: [],
|
remoteRepos: [],
|
||||||
selectedRemoteSourceIndex: null,
|
selectedRemoteSourceIndex: null,
|
||||||
projectName: "",
|
projectName: '',
|
||||||
projectIsPrivate: false,
|
projectIsPrivate: false,
|
||||||
remoteRepoPath: null
|
remoteRepoPath: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
createProjectButtonEnabled: function () {
|
createProjectButtonEnabled: function () {
|
||||||
return this.projectName.length && this.remoteRepoPath;
|
return this.projectName.length && this.remoteRepoPath;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
watch: {},
|
watch: {},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -143,7 +161,7 @@ export default {
|
||||||
let { data, error } = await userRemoteRepos(remoteSource.id);
|
let { data, error } = await userRemoteRepos(remoteSource.id);
|
||||||
this.stopFetchRemoteReposLoading();
|
this.stopFetchRemoteReposLoading();
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.remoteRepos = data;
|
this.remoteRepos = data;
|
||||||
|
@ -155,11 +173,11 @@ export default {
|
||||||
if (this.projectgroupref) {
|
if (this.projectgroupref) {
|
||||||
refArray = [...refArray, ...this.projectgroupref];
|
refArray = [...refArray, ...this.projectgroupref];
|
||||||
}
|
}
|
||||||
let parentref = refArray.join("/");
|
let parentref = refArray.join('/');
|
||||||
|
|
||||||
let visibility = "public";
|
let visibility = 'public';
|
||||||
if (this.projectIsPrivate) {
|
if (this.projectIsPrivate) {
|
||||||
visibility = "private";
|
visibility = 'private';
|
||||||
}
|
}
|
||||||
|
|
||||||
let remoteSource = this.remoteSources[this.selectedRemoteSourceIndex];
|
let remoteSource = this.remoteSources[this.selectedRemoteSourceIndex];
|
||||||
|
@ -186,12 +204,12 @@ export default {
|
||||||
this.$router.push(
|
this.$router.push(
|
||||||
projectLink(this.ownertype, this.ownername, projectref)
|
projectLink(this.ownertype, this.ownername, projectref)
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created: async function () {
|
created: async function () {
|
||||||
let { data, error } = await fetchCurrentUser();
|
let { data, error } = await fetchCurrentUser();
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.user = data;
|
this.user = data;
|
||||||
|
@ -199,7 +217,7 @@ export default {
|
||||||
// TODO(sgotti) filter only remote source where the user has a linked account
|
// TODO(sgotti) filter only remote source where the user has a linked account
|
||||||
({ data, error } = await fetchRemoteSources());
|
({ data, error } = await fetchRemoteSources());
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,10 +233,8 @@ export default {
|
||||||
}
|
}
|
||||||
this.remoteSources = remoteSources;
|
this.remoteSources = remoteSources;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,11 @@
|
||||||
<button
|
<button
|
||||||
@click="clicked"
|
@click="clicked"
|
||||||
class="relative flex items-center focus:outline-none bg-green-500 hover:bg-green-600 text-white font-semibold hover:text-white py-2 px-4 border border-green-700 rounded rounded-r-none"
|
class="relative flex items-center focus:outline-none bg-green-500 hover:bg-green-600 text-white font-semibold hover:text-white py-2 px-4 border border-green-700 rounded rounded-r-none"
|
||||||
>{{ buttonValue }}</button>
|
>
|
||||||
|
{{ buttonValue }}
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
v-click-outside="() => dropdownActive = false"
|
v-click-outside="() => (dropdownActive = false)"
|
||||||
@click="dropdownActive = !dropdownActive"
|
@click="dropdownActive = !dropdownActive"
|
||||||
class="relative flex items-center focus:outline-none bg-green-500 hover:bg-green-600 text-white font-semibold hover:text-white py-2 px-4 border border-l-0 border-green-700 rounded rounded-l-none"
|
class="relative flex items-center focus:outline-none bg-green-500 hover:bg-green-600 text-white font-semibold hover:text-white py-2 px-4 border border-l-0 border-green-700 rounded rounded-l-none"
|
||||||
>
|
>
|
||||||
|
@ -24,14 +26,16 @@
|
||||||
href="#"
|
href="#"
|
||||||
class="block px-4 py-2 hover:bg-blue-500 hover:text-white"
|
class="block px-4 py-2 hover:bg-blue-500 hover:text-white"
|
||||||
@click="setButton('project')"
|
@click="setButton('project')"
|
||||||
>New Project</a>
|
>New Project</a
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
class="block px-4 py-2 hover:bg-blue-500 hover:text-white"
|
class="block px-4 py-2 hover:bg-blue-500 hover:text-white"
|
||||||
@click="setButton('projectgroup')"
|
@click="setButton('projectgroup')"
|
||||||
>New Project Group</a>
|
>New Project Group</a
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -40,28 +44,28 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as vClickOutside from "v-click-outside-x";
|
import * as vClickOutside from 'v-click-outside-x';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: {},
|
||||||
directives: {
|
directives: {
|
||||||
clickOutside: vClickOutside.directive
|
clickOutside: vClickOutside.directive,
|
||||||
},
|
},
|
||||||
name: "createprojectbutton",
|
name: 'createprojectbutton',
|
||||||
props: {},
|
props: {},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
dropdownActive: false,
|
dropdownActive: false,
|
||||||
type: "project"
|
type: 'project',
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
buttonValue: function () {
|
buttonValue: function () {
|
||||||
if (this.type == "project") {
|
if (this.type == 'project') {
|
||||||
return "New Project";
|
return 'New Project';
|
||||||
}
|
|
||||||
return "New Project Group";
|
|
||||||
}
|
}
|
||||||
|
return 'New Project Group';
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
setButton(type) {
|
setButton(type) {
|
||||||
|
@ -69,12 +73,10 @@ export default {
|
||||||
this.dropdownActive = false;
|
this.dropdownActive = false;
|
||||||
},
|
},
|
||||||
clicked() {
|
clicked() {
|
||||||
this.$emit("click", this.type);
|
this.$emit('click', this.type);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
|
@ -7,20 +7,22 @@
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Project Group Name"
|
placeholder="Project Group Name"
|
||||||
v-model="projectGroupName"
|
v-model="projectGroupName"
|
||||||
>
|
/>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" v-model="projectGroupIsPrivate">
|
<input type="checkbox" v-model="projectGroupIsPrivate" />
|
||||||
Private
|
Private
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
|
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
|
||||||
v-bind:class="{ 'spinner': createProjectGroupLoading }"
|
v-bind:class="{ spinner: createProjectGroupLoading }"
|
||||||
:disabled="!createProjectGroupButtonEnabled"
|
:disabled="!createProjectGroupButtonEnabled"
|
||||||
@click="createProjectGroup()"
|
@click="createProjectGroup()"
|
||||||
>Create ProjectGroup</button>
|
>
|
||||||
|
Create ProjectGroup
|
||||||
|
</button>
|
||||||
<div
|
<div
|
||||||
v-if="createProjectGroupError"
|
v-if="createProjectGroupError"
|
||||||
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
||||||
|
@ -32,31 +34,31 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { createProjectGroup } from "@/util/data.js";
|
import { createProjectGroup } from '@/util/data.js';
|
||||||
|
|
||||||
import { projectGroupLink } from "@/util/link.js";
|
import { projectGroupLink } from '@/util/link.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: {},
|
||||||
name: "createprojectgroup",
|
name: 'createprojectgroup',
|
||||||
props: {
|
props: {
|
||||||
ownertype: String,
|
ownertype: String,
|
||||||
ownername: String,
|
ownername: String,
|
||||||
projectgroupref: Array
|
projectgroupref: Array,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
createProjectGroupError: null,
|
createProjectGroupError: null,
|
||||||
createProjectGroupLoading: false,
|
createProjectGroupLoading: false,
|
||||||
createProjectGroupLoadingTimeout: null,
|
createProjectGroupLoadingTimeout: null,
|
||||||
projectGroupName: "",
|
projectGroupName: '',
|
||||||
projectGroupIsPrivate: false
|
projectGroupIsPrivate: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
createProjectGroupButtonEnabled: function () {
|
createProjectGroupButtonEnabled: function () {
|
||||||
return this.projectGroupName.length;
|
return this.projectGroupName.length;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
resetErrors() {
|
resetErrors() {
|
||||||
|
@ -78,11 +80,11 @@ export default {
|
||||||
if (this.projectgroupref) {
|
if (this.projectgroupref) {
|
||||||
refArray = [...refArray, ...this.projectgroupref];
|
refArray = [...refArray, ...this.projectgroupref];
|
||||||
}
|
}
|
||||||
let parentref = refArray.join("/");
|
let parentref = refArray.join('/');
|
||||||
|
|
||||||
let visibility = "public";
|
let visibility = 'public';
|
||||||
if (this.projectGroupIsPrivate) {
|
if (this.projectGroupIsPrivate) {
|
||||||
visibility = "private";
|
visibility = 'private';
|
||||||
}
|
}
|
||||||
|
|
||||||
this.startProjectGroupLoading();
|
this.startProjectGroupLoading();
|
||||||
|
@ -104,12 +106,9 @@ export default {
|
||||||
this.$router.push(
|
this.$router.push(
|
||||||
projectGroupLink(this.ownertype, this.ownername, projectgroupref)
|
projectGroupLink(this.ownertype, this.ownername, projectgroupref)
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,17 +12,31 @@
|
||||||
</h1>
|
</h1>
|
||||||
<form
|
<form
|
||||||
class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4"
|
class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4"
|
||||||
@submit.prevent="$emit('createSource', { token, name, type, clientId, clientSecret, url, skipVerify, sshHostKey, skipSshHostKeyCheck })"
|
@submit.prevent="
|
||||||
|
$emit('createSource', {
|
||||||
|
token,
|
||||||
|
name,
|
||||||
|
type,
|
||||||
|
clientId,
|
||||||
|
clientSecret,
|
||||||
|
url,
|
||||||
|
skipVerify,
|
||||||
|
sshHostKey,
|
||||||
|
skipSshHostKeyCheck,
|
||||||
|
})
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label class="block text-sm font-bold mb-2" for="token">Agola Admin token</label>
|
<label class="block text-sm font-bold mb-2" for="token"
|
||||||
|
>Agola Admin token</label
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||||
id="token"
|
id="token"
|
||||||
type="password"
|
type="password"
|
||||||
placeholder="Agola Admin token"
|
placeholder="Agola Admin token"
|
||||||
v-model="token"
|
v-model="token"
|
||||||
>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label class="block text-sm font-bold mb-2" for="type">Type</label>
|
<label class="block text-sm font-bold mb-2" for="type">Type</label>
|
||||||
|
@ -37,7 +51,9 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label class="block text-sm font-bold mb-2" for="name">Source name</label>
|
<label class="block text-sm font-bold mb-2" for="name"
|
||||||
|
>Source name</label
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||||
id="name"
|
id="name"
|
||||||
|
@ -45,17 +61,19 @@
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Source name (only numbers, letters and -)"
|
placeholder="Source name (only numbers, letters and -)"
|
||||||
v-model="name"
|
v-model="name"
|
||||||
>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label class="block text-sm font-bold mb-2" for="url">Source API URL</label>
|
<label class="block text-sm font-bold mb-2" for="url"
|
||||||
|
>Source API URL</label
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||||
id="url"
|
id="url"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="API URL"
|
placeholder="API URL"
|
||||||
v-model="url"
|
v-model="url"
|
||||||
>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4 flex flex-row">
|
<div class="mb-4 flex flex-row">
|
||||||
<input
|
<input
|
||||||
|
@ -63,11 +81,15 @@
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
class="h-6 w-6 border border-gray-300 rounded-md checked:bg-blue-600 checked:border-transparent focus:outline-none"
|
class="h-6 w-6 border border-gray-300 rounded-md checked:bg-blue-600 checked:border-transparent focus:outline-none"
|
||||||
v-model="skipVerify"
|
v-model="skipVerify"
|
||||||
|
/>
|
||||||
|
<label class="text-sm mt-auto font-bold mx-2" for="skip_verify"
|
||||||
|
>Skip TLS certificate validation</label
|
||||||
>
|
>
|
||||||
<label class="text-sm mt-auto font-bold mx-2" for="skip_verify">Skip TLS certificate validation</label>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label class="block text-sm font-bold mb-2" for="ssh_key">Source Public SSH Key</label>
|
<label class="block text-sm font-bold mb-2" for="ssh_key"
|
||||||
|
>Source Public SSH Key</label
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||||
id="ssh_key"
|
id="ssh_key"
|
||||||
|
@ -75,7 +97,7 @@
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
placeholder="Public SSH key"
|
placeholder="Public SSH key"
|
||||||
v-model="sshHostKey"
|
v-model="sshHostKey"
|
||||||
>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4 flex flex-row">
|
<div class="mb-4 flex flex-row">
|
||||||
<input
|
<input
|
||||||
|
@ -83,45 +105,52 @@
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
class="h-6 w-6 border border-gray-300 rounded-md checked:bg-blue-600 checked:border-transparent focus:outline-none"
|
class="h-6 w-6 border border-gray-300 rounded-md checked:bg-blue-600 checked:border-transparent focus:outline-none"
|
||||||
v-model="skipSshHostKeyCheck"
|
v-model="skipSshHostKeyCheck"
|
||||||
|
/>
|
||||||
|
<label class="text-sm mt-auto font-bold mx-2" for="skip_ssh_key_check"
|
||||||
|
>Skip SSH host key check</label
|
||||||
>
|
>
|
||||||
<label class="text-sm mt-auto font-bold mx-2" for="skip_ssh_key_check">Skip SSH host key check</label>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label class="block text-sm font-bold mb-2" for="client_id">Source client ID</label>
|
<label class="block text-sm font-bold mb-2" for="client_id"
|
||||||
|
>Source client ID</label
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||||
id="client_id"
|
id="client_id"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Client ID"
|
placeholder="Client ID"
|
||||||
v-model="clientId"
|
v-model="clientId"
|
||||||
>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label class="block text-sm font-bold mb-2" for="client_secret">Source client secret</label>
|
<label class="block text-sm font-bold mb-2" for="client_secret"
|
||||||
|
>Source client secret</label
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||||
id="client_secret"
|
id="client_secret"
|
||||||
type="password"
|
type="password"
|
||||||
placeholder="Client secret"
|
placeholder="Client secret"
|
||||||
v-model="clientSecret"
|
v-model="clientSecret"
|
||||||
>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-center">
|
<div class="flex justify-center">
|
||||||
<button
|
<button
|
||||||
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
|
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
|
||||||
type="submit"
|
type="submit"
|
||||||
>Create</button>
|
>
|
||||||
|
Create
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { GITHUB_SSH_KEY, GITHUB_API_URL } from "@/util/data"
|
import { GITHUB_SSH_KEY, GITHUB_API_URL } from '@/util/data';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "CreateSourceForm",
|
name: 'CreateSourceForm',
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
name: null,
|
name: null,
|
||||||
|
@ -137,7 +166,7 @@ export default {
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
type: function (value) {
|
type: function (value) {
|
||||||
if (value === "github") {
|
if (value === 'github') {
|
||||||
this.url = GITHUB_API_URL;
|
this.url = GITHUB_API_URL;
|
||||||
this.sshHostKey = GITHUB_SSH_KEY;
|
this.sshHostKey = GITHUB_SSH_KEY;
|
||||||
this.skipVerify = false;
|
this.skipVerify = false;
|
||||||
|
@ -147,5 +176,3 @@ export default {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -43,18 +43,18 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { apiurl, fetch } from "@/util/auth";
|
import { apiurl, fetch } from '@/util/auth';
|
||||||
import AnsiUp from "ansi_up";
|
import AnsiUp from 'ansi_up';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Log",
|
name: 'Log',
|
||||||
props: {
|
props: {
|
||||||
show: Boolean,
|
show: Boolean,
|
||||||
runid: String,
|
runid: String,
|
||||||
taskid: String,
|
taskid: String,
|
||||||
setup: Boolean,
|
setup: Boolean,
|
||||||
step: Number,
|
step: Number,
|
||||||
stepphase: String
|
stepphase: String,
|
||||||
},
|
},
|
||||||
computed: {},
|
computed: {},
|
||||||
data() {
|
data() {
|
||||||
|
@ -65,7 +65,7 @@ export default {
|
||||||
fetchAbort: null,
|
fetchAbort: null,
|
||||||
|
|
||||||
items: [],
|
items: [],
|
||||||
lastitem: "",
|
lastitem: '',
|
||||||
lines: [],
|
lines: [],
|
||||||
formatter: formatter,
|
formatter: formatter,
|
||||||
es: null,
|
es: null,
|
||||||
|
@ -73,7 +73,7 @@ export default {
|
||||||
streaming: false,
|
streaming: false,
|
||||||
done: false,
|
done: false,
|
||||||
logExists: null,
|
logExists: null,
|
||||||
error: null
|
error: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -83,7 +83,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
let follow = false;
|
let follow = false;
|
||||||
if (this.stepphase == "running") {
|
if (this.stepphase == 'running') {
|
||||||
follow = true;
|
follow = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,14 +94,14 @@ export default {
|
||||||
this.logExists = null;
|
this.logExists = null;
|
||||||
this.error = null;
|
this.error = null;
|
||||||
|
|
||||||
let path = "/logs?runID=" + this.runid + "&taskID=" + this.taskid;
|
let path = '/logs?runID=' + this.runid + '&taskID=' + this.taskid;
|
||||||
if (this.setup) {
|
if (this.setup) {
|
||||||
path += "&setup";
|
path += '&setup';
|
||||||
} else {
|
} else {
|
||||||
path += "&step=" + this.step;
|
path += '&step=' + this.step;
|
||||||
}
|
}
|
||||||
if (follow) {
|
if (follow) {
|
||||||
path += "&follow";
|
path += '&follow';
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -111,7 +111,7 @@ export default {
|
||||||
this.streaming = true;
|
this.streaming = true;
|
||||||
const reader = res.body.getReader();
|
const reader = res.body.getReader();
|
||||||
|
|
||||||
let lastline = "";
|
let lastline = '';
|
||||||
let j = 0;
|
let j = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
let { done, value } = await reader.read();
|
let { done, value } = await reader.read();
|
||||||
|
@ -122,12 +122,12 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let data = new TextDecoder("utf-8").decode(value, { stream: true });
|
let data = new TextDecoder('utf-8').decode(value, { stream: true });
|
||||||
|
|
||||||
let part = "";
|
let part = '';
|
||||||
for (var i = 0; i < data.length; i++) {
|
for (var i = 0; i < data.length; i++) {
|
||||||
let c = data.charAt(i);
|
let c = data.charAt(i);
|
||||||
if (c == "\r") {
|
if (c == '\r') {
|
||||||
// replace lastline from start, simulating line feed (go to start of line)
|
// replace lastline from start, simulating line feed (go to start of line)
|
||||||
// this isn't perfect since the previous line contents could have
|
// this isn't perfect since the previous line contents could have
|
||||||
// been written using different colors and this will lose them but
|
// been written using different colors and this will lose them but
|
||||||
|
@ -136,17 +136,17 @@ export default {
|
||||||
lastline.slice(0, j) + part + lastline.slice(j + part.length);
|
lastline.slice(0, j) + part + lastline.slice(j + part.length);
|
||||||
j = 0;
|
j = 0;
|
||||||
this.lastitem = this.formatter.ansi_to_html(lastline);
|
this.lastitem = this.formatter.ansi_to_html(lastline);
|
||||||
part = "";
|
part = '';
|
||||||
} else if (c == "\n") {
|
} else if (c == '\n') {
|
||||||
lastline =
|
lastline =
|
||||||
lastline.slice(0, j) + part + lastline.slice(j + part.length);
|
lastline.slice(0, j) + part + lastline.slice(j + part.length);
|
||||||
j += part.length;
|
j += part.length;
|
||||||
this.lastitem = this.formatter.ansi_to_html(lastline);
|
this.lastitem = this.formatter.ansi_to_html(lastline);
|
||||||
this.items.push(this.lastitem);
|
this.items.push(this.lastitem);
|
||||||
this.lastitem = "";
|
this.lastitem = '';
|
||||||
lastline = "";
|
lastline = '';
|
||||||
j = 0;
|
j = 0;
|
||||||
part = "";
|
part = '';
|
||||||
} else {
|
} else {
|
||||||
part += c;
|
part += c;
|
||||||
}
|
}
|
||||||
|
@ -174,7 +174,7 @@ export default {
|
||||||
this.fetchAbort.abort();
|
this.fetchAbort.abort();
|
||||||
}
|
}
|
||||||
this.fetchAbort = new AbortController();
|
this.fetchAbort = new AbortController();
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
show: function (post, pre) {
|
show: function (post, pre) {
|
||||||
|
@ -193,14 +193,14 @@ export default {
|
||||||
if (this.fetching) {
|
if (this.fetching) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (post == "running") {
|
if (post == 'running') {
|
||||||
this.abortFetch();
|
this.abortFetch();
|
||||||
this.getLogs(true);
|
this.getLogs(true);
|
||||||
} else {
|
} else {
|
||||||
this.abortFetch();
|
this.abortFetch();
|
||||||
this.getLogs(false);
|
this.getLogs(false);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
this.fetchAbort = new AbortController();
|
this.fetchAbort = new AbortController();
|
||||||
|
@ -217,6 +217,6 @@ export default {
|
||||||
if (this.es !== null) {
|
if (this.es !== null) {
|
||||||
this.es.close();
|
this.es.close();
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -5,50 +5,53 @@
|
||||||
@submit.prevent="$emit('login', { username, password })"
|
@submit.prevent="$emit('login', { username, password })"
|
||||||
>
|
>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label class="block text-sm font-bold mb-2" for="username">Username</label>
|
<label class="block text-sm font-bold mb-2" for="username"
|
||||||
|
>Username</label
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||||
id="username"
|
id="username"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Username"
|
placeholder="Username"
|
||||||
v-model="username"
|
v-model="username"
|
||||||
>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-6">
|
<div class="mb-6">
|
||||||
<label class="block text-sm font-bold mb-2" for="password">Password</label>
|
<label class="block text-sm font-bold mb-2" for="password"
|
||||||
|
>Password</label
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
class="appearance-none border rounded w-full py-2 px-3 mb-3 leading-tight focus:outline-none focus:shadow-outline"
|
class="appearance-none border rounded w-full py-2 px-3 mb-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||||
id="password"
|
id="password"
|
||||||
type="password"
|
type="password"
|
||||||
placeholder="******************"
|
placeholder="******************"
|
||||||
v-model="password"
|
v-model="password"
|
||||||
>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-center">
|
<div class="flex justify-center">
|
||||||
<button
|
<button
|
||||||
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
|
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
|
||||||
type="submit"
|
type="submit"
|
||||||
>{{action}} with {{name}}</button>
|
>
|
||||||
|
{{ action }} with {{ name }}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "LoginForm",
|
name: 'LoginForm',
|
||||||
props: {
|
props: {
|
||||||
action: String,
|
action: String,
|
||||||
name: String
|
name: String,
|
||||||
},
|
},
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
username: null,
|
username: null,
|
||||||
password: null
|
password: null,
|
||||||
};
|
};
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,39 +12,38 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { fetchOrgMembers } from "@/util/data.js";
|
import { fetchOrgMembers } from '@/util/data.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: {},
|
||||||
name: "orgmembers",
|
name: 'orgmembers',
|
||||||
props: {
|
props: {
|
||||||
orgname: String
|
orgname: String,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
members: []
|
members: [],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
$route: async function () {
|
$route: async function () {
|
||||||
this.fetchOrgMembers(this.orgname);
|
this.fetchOrgMembers(this.orgname);
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async fetchOrgMembers(orgname) {
|
async fetchOrgMembers(orgname) {
|
||||||
let { data, error } = await fetchOrgMembers(orgname);
|
let { data, error } = await fetchOrgMembers(orgname);
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.members = data.members;
|
this.members = data.members;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
this.fetchOrgMembers(this.orgname);
|
this.fetchOrgMembers(this.orgname);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
|
@ -8,51 +8,61 @@
|
||||||
<span class="mx-2">/</span>
|
<span class="mx-2">/</span>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<router-link :to="ownerLink(ownertype, ownername)">{{ownername}}</router-link>
|
<router-link :to="ownerLink(ownertype, ownername)">{{
|
||||||
|
ownername
|
||||||
|
}}</router-link>
|
||||||
</li>
|
</li>
|
||||||
<li v-for="(ref, i) in projectref" v-bind:key="i">
|
<li v-for="(ref, i) in projectref" v-bind:key="i">
|
||||||
<span class="mx-2">/</span>
|
<span class="mx-2">/</span>
|
||||||
<router-link
|
<router-link
|
||||||
v-if="i + 1 < projectref.length"
|
v-if="i + 1 < projectref.length"
|
||||||
:to="projectGroupLink(ownertype, ownername, projectref.slice(0, i+1))"
|
:to="
|
||||||
>{{ref}}</router-link>
|
projectGroupLink(ownertype, ownername, projectref.slice(0, i + 1))
|
||||||
|
"
|
||||||
|
>{{ ref }}</router-link
|
||||||
|
>
|
||||||
<router-link
|
<router-link
|
||||||
v-else
|
v-else
|
||||||
:to="projectLink(ownertype, ownername, projectref.slice(0, i + 1))"
|
:to="projectLink(ownertype, ownername, projectref.slice(0, i + 1))"
|
||||||
>{{ref}}</router-link>
|
>{{ ref }}</router-link
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li v-for="(ref, i) in projectgroupref" v-bind:key="i">
|
<li v-for="(ref, i) in projectgroupref" v-bind:key="i">
|
||||||
<span class="mx-2">/</span>
|
<span class="mx-2">/</span>
|
||||||
<router-link
|
<router-link
|
||||||
:to="projectGroupLink(ownertype, ownername, projectgroupref.slice(0, i+1))"
|
:to="
|
||||||
>{{ref}}</router-link>
|
projectGroupLink(
|
||||||
|
ownertype,
|
||||||
|
ownername,
|
||||||
|
projectgroupref.slice(0, i + 1)
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>{{ ref }}</router-link
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
</nav>
|
</nav>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ownerLink, projectLink, projectGroupLink } from "@/util/link.js";
|
import { ownerLink, projectLink, projectGroupLink } from '@/util/link.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "projbreadcrumbs",
|
name: 'projbreadcrumbs',
|
||||||
components: {},
|
components: {},
|
||||||
props: {
|
props: {
|
||||||
ownertype: String,
|
ownertype: String,
|
||||||
ownername: String,
|
ownername: String,
|
||||||
projectref: Array,
|
projectref: Array,
|
||||||
projectgroupref: Array
|
projectgroupref: Array,
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
ownerLink: ownerLink,
|
ownerLink: ownerLink,
|
||||||
projectLink: projectLink,
|
projectLink: projectLink,
|
||||||
projectGroupLink: projectGroupLink
|
projectGroupLink: projectGroupLink,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
||||||
<style scoped lang="scss">
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -20,7 +20,9 @@
|
||||||
Private
|
Private
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-blue" @click="updateProjectGroup()">Update</button>
|
<button class="btn btn-blue" @click="updateProjectGroup()">
|
||||||
|
Update
|
||||||
|
</button>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="updateProjectGroupError"
|
v-if="updateProjectGroupError"
|
||||||
|
@ -35,14 +37,22 @@
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<p class="panel-title">Secrets</p>
|
<p class="panel-title">Secrets</p>
|
||||||
<div class="p-4">
|
<div class="p-4">
|
||||||
<projectsecrets :secrets="secrets" :allsecrets="allsecrets" type="projectgroup" />
|
<projectsecrets
|
||||||
|
:secrets="secrets"
|
||||||
|
:allsecrets="allsecrets"
|
||||||
|
type="projectgroup"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<p class="panel-title">Variables</p>
|
<p class="panel-title">Variables</p>
|
||||||
<div class="p-4">
|
<div class="p-4">
|
||||||
<projectvars :variables="variables" :allvariables="allvariables" type="projectgroup" />
|
<projectvars
|
||||||
|
:variables="variables"
|
||||||
|
:allvariables="allvariables"
|
||||||
|
type="projectgroup"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -56,16 +66,13 @@
|
||||||
>
|
>
|
||||||
<p>
|
<p>
|
||||||
This operation
|
This operation
|
||||||
<strong>CANNOT</strong> be undone.
|
<strong>CANNOT</strong> be undone. This operation will remove
|
||||||
This operation will remove
|
|
||||||
<strong>{{ projectGroupPath }}</strong>
|
<strong>{{ projectGroupPath }}</strong>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<label class="block mb-2">
|
<label class="block mb-2">
|
||||||
Please type the project group name for confirmation:
|
Please type the project group name for confirmation:
|
||||||
<span
|
<span class="text-red-500 font-bold">{{ projectGroupName }}</span>
|
||||||
class="text-red-500 font-bold"
|
|
||||||
>{{ projectGroupName }}</span>
|
|
||||||
</label>
|
</label>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<input
|
<input
|
||||||
|
@ -79,7 +86,9 @@
|
||||||
class="btn btn-red"
|
class="btn btn-red"
|
||||||
@click="deleteProjectGroup()"
|
@click="deleteProjectGroup()"
|
||||||
:disabled="!deleteButtonEnabled"
|
:disabled="!deleteButtonEnabled"
|
||||||
>Delete Project Group</button>
|
>
|
||||||
|
Delete Project Group
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -98,21 +107,21 @@ import {
|
||||||
fetchSecrets,
|
fetchSecrets,
|
||||||
fetchVariables,
|
fetchVariables,
|
||||||
updateProjectGroup,
|
updateProjectGroup,
|
||||||
deleteProjectGroup
|
deleteProjectGroup,
|
||||||
} from "@/util/data.js";
|
} from '@/util/data.js';
|
||||||
|
|
||||||
import { projectGroupLink } from "@/util/link.js";
|
import { projectGroupLink } from '@/util/link.js';
|
||||||
|
|
||||||
import projectsecrets from "@/components/projectsecrets";
|
import projectsecrets from '@/components/projectsecrets';
|
||||||
import projectvars from "@/components/projectvars";
|
import projectvars from '@/components/projectvars';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { projectsecrets, projectvars },
|
components: { projectsecrets, projectvars },
|
||||||
name: "projectgroupsettings",
|
name: 'projectgroupsettings',
|
||||||
props: {
|
props: {
|
||||||
ownertype: String,
|
ownertype: String,
|
||||||
ownername: String,
|
ownername: String,
|
||||||
projectgroupref: Array
|
projectgroupref: Array,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -124,7 +133,7 @@ export default {
|
||||||
allsecrets: [],
|
allsecrets: [],
|
||||||
variables: [],
|
variables: [],
|
||||||
allvariables: [],
|
allvariables: [],
|
||||||
projectGroupNameToDelete: ""
|
projectGroupNameToDelete: '',
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -132,8 +141,8 @@ export default {
|
||||||
return this.projectgroupref[this.projectgroupref.length - 1];
|
return this.projectgroupref[this.projectgroupref.length - 1];
|
||||||
},
|
},
|
||||||
projectGroupPath: function () {
|
projectGroupPath: function () {
|
||||||
return ["", this.ownertype, this.ownername, ...this.projectgroupref].join(
|
return ['', this.ownertype, this.ownername, ...this.projectgroupref].join(
|
||||||
"/"
|
'/'
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
deleteButtonEnabled: function () {
|
deleteButtonEnabled: function () {
|
||||||
|
@ -141,7 +150,7 @@ export default {
|
||||||
},
|
},
|
||||||
isRootProjectGroup() {
|
isRootProjectGroup() {
|
||||||
return this.projectgroupref.length == 0;
|
return this.projectgroupref.length == 0;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
resetErrors() {
|
resetErrors() {
|
||||||
|
@ -154,12 +163,12 @@ export default {
|
||||||
let projectgroupref = [
|
let projectgroupref = [
|
||||||
this.ownertype,
|
this.ownertype,
|
||||||
this.ownername,
|
this.ownername,
|
||||||
...this.projectgroupref
|
...this.projectgroupref,
|
||||||
].join("/");
|
].join('/');
|
||||||
|
|
||||||
let visibility = "public";
|
let visibility = 'public';
|
||||||
if (this.projectGroupIsPrivate) {
|
if (this.projectGroupIsPrivate) {
|
||||||
visibility = "private";
|
visibility = 'private';
|
||||||
}
|
}
|
||||||
let { error } = await updateProjectGroup(
|
let { error } = await updateProjectGroup(
|
||||||
projectgroupref,
|
projectgroupref,
|
||||||
|
@ -175,8 +184,8 @@ export default {
|
||||||
let projectgroupref = [
|
let projectgroupref = [
|
||||||
this.ownertype,
|
this.ownertype,
|
||||||
this.ownername,
|
this.ownername,
|
||||||
...this.projectgroupref
|
...this.projectgroupref,
|
||||||
].join("/");
|
].join('/');
|
||||||
|
|
||||||
if (this.projectGroupNameToDelete == this.projectGroupName) {
|
if (this.projectGroupNameToDelete == this.projectGroupName) {
|
||||||
let { error } = await deleteProjectGroup(projectgroupref);
|
let { error } = await deleteProjectGroup(projectgroupref);
|
||||||
|
@ -192,70 +201,68 @@ export default {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created: async function () {
|
created: async function () {
|
||||||
let projectgroupref = [
|
let projectgroupref = [
|
||||||
this.ownertype,
|
this.ownertype,
|
||||||
this.ownername,
|
this.ownername,
|
||||||
...this.projectgroupref
|
...this.projectgroupref,
|
||||||
].join("/");
|
].join('/');
|
||||||
|
|
||||||
let { data, error } = await fetchProjectGroup(projectgroupref);
|
let { data, error } = await fetchProjectGroup(projectgroupref);
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.projectGroup = data;
|
this.projectGroup = data;
|
||||||
this.projectGroupIsPrivate = this.projectGroup.visibility == "private";
|
this.projectGroupIsPrivate = this.projectGroup.visibility == 'private';
|
||||||
|
|
||||||
({ data, error } = await fetchSecrets(
|
({ data, error } = await fetchSecrets(
|
||||||
"projectgroup",
|
'projectgroup',
|
||||||
projectgroupref,
|
projectgroupref,
|
||||||
false
|
false
|
||||||
));
|
));
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.secrets = data;
|
this.secrets = data;
|
||||||
|
|
||||||
({ data, error } = await fetchSecrets(
|
({ data, error } = await fetchSecrets(
|
||||||
"projectgroup",
|
'projectgroup',
|
||||||
projectgroupref,
|
projectgroupref,
|
||||||
true
|
true
|
||||||
));
|
));
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.allsecrets = data;
|
this.allsecrets = data;
|
||||||
|
|
||||||
({ data, error } = await fetchVariables(
|
({ data, error } = await fetchVariables(
|
||||||
"projectgroup",
|
'projectgroup',
|
||||||
projectgroupref,
|
projectgroupref,
|
||||||
false
|
false
|
||||||
));
|
));
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.variables = data;
|
this.variables = data;
|
||||||
|
|
||||||
({ data, error } = await fetchVariables(
|
({ data, error } = await fetchVariables(
|
||||||
"projectgroup",
|
'projectgroup',
|
||||||
projectgroupref,
|
projectgroupref,
|
||||||
true
|
true
|
||||||
));
|
));
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.allvariables = data;
|
this.allvariables = data;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
|
@ -2,12 +2,19 @@
|
||||||
<div>
|
<div>
|
||||||
<h4 class="text-xl my-3">Projects</h4>
|
<h4 class="text-xl my-3">Projects</h4>
|
||||||
<div v-if="fetchProjectsLoading" class="ml-6 flex w-48">
|
<div v-if="fetchProjectsLoading" class="ml-6 flex w-48">
|
||||||
<div v-bind:class="{ 'spinner': fetchProjectsLoading }"></div>
|
<div v-bind:class="{ spinner: fetchProjectsLoading }"></div>
|
||||||
</div>
|
</div>
|
||||||
<ul v-else-if="projects.length > 0">
|
<ul v-else-if="projects.length > 0">
|
||||||
<li class="mb-2 border rounded-l" v-for="project in projects" v-bind:key="project.id">
|
<li
|
||||||
|
class="mb-2 border rounded-l"
|
||||||
|
v-for="project in projects"
|
||||||
|
v-bind:key="project.id"
|
||||||
|
>
|
||||||
<div class="pl-4 py-4 flex items-center">
|
<div class="pl-4 py-4 flex items-center">
|
||||||
<router-link class="item" :to="projectLink(ownertype, ownername, ref(project.name))">
|
<router-link
|
||||||
|
class="item"
|
||||||
|
:to="projectLink(ownertype, ownername, ref(project.name))"
|
||||||
|
>
|
||||||
<span class="font-bold">{{ project.name }}</span>
|
<span class="font-bold">{{ project.name }}</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
|
@ -19,7 +26,7 @@
|
||||||
|
|
||||||
<h4 class="text-xl my-3">Project Groups</h4>
|
<h4 class="text-xl my-3">Project Groups</h4>
|
||||||
<div v-if="fetchProjectGroupsLoading" class="ml-6 flex w-48">
|
<div v-if="fetchProjectGroupsLoading" class="ml-6 flex w-48">
|
||||||
<div v-bind:class="{ 'spinner': fetchProjectGroupsLoading }"></div>
|
<div v-bind:class="{ spinner: fetchProjectGroupsLoading }"></div>
|
||||||
</div>
|
</div>
|
||||||
<ul v-else-if="projectgroups.length > 0">
|
<ul v-else-if="projectgroups.length > 0">
|
||||||
<li
|
<li
|
||||||
|
@ -44,18 +51,18 @@
|
||||||
<script>
|
<script>
|
||||||
import {
|
import {
|
||||||
fetchProjectGroupProjects,
|
fetchProjectGroupProjects,
|
||||||
fetchProjectGroupSubgroups
|
fetchProjectGroupSubgroups,
|
||||||
} from "@/util/data.js";
|
} from '@/util/data.js';
|
||||||
|
|
||||||
import { projectLink, projectGroupLink } from "@/util/link.js";
|
import { projectLink, projectGroupLink } from '@/util/link.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: {},
|
||||||
name: "Projects",
|
name: 'Projects',
|
||||||
props: {
|
props: {
|
||||||
ownertype: String,
|
ownertype: String,
|
||||||
ownername: String,
|
ownername: String,
|
||||||
projectgroupref: Array
|
projectgroupref: Array,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -65,7 +72,7 @@ export default {
|
||||||
fetchProjectsLoading: false,
|
fetchProjectsLoading: false,
|
||||||
|
|
||||||
projects: [],
|
projects: [],
|
||||||
projectgroups: []
|
projectgroups: [],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -76,7 +83,7 @@ export default {
|
||||||
this.fetchAbort = new AbortController();
|
this.fetchAbort = new AbortController();
|
||||||
this.fetchProjects(this.ownertype, this.ownername);
|
this.fetchProjects(this.ownertype, this.ownername);
|
||||||
this.fetchProjectGroups(this.ownertype, this.ownername);
|
this.fetchProjectGroups(this.ownertype, this.ownername);
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
startFetchProjectsLoading() {
|
startFetchProjectsLoading() {
|
||||||
|
@ -107,7 +114,7 @@ export default {
|
||||||
|
|
||||||
this.startFetchProjectsLoading();
|
this.startFetchProjectsLoading();
|
||||||
let { data, error, aborted } = await fetchProjectGroupProjects(
|
let { data, error, aborted } = await fetchProjectGroupProjects(
|
||||||
projectgroupref.join("/"),
|
projectgroupref.join('/'),
|
||||||
this.fetchAbort.signal
|
this.fetchAbort.signal
|
||||||
);
|
);
|
||||||
this.stopFetchProjectsLoading();
|
this.stopFetchProjectsLoading();
|
||||||
|
@ -115,7 +122,7 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.projects = data;
|
this.projects = data;
|
||||||
|
@ -127,7 +134,7 @@ export default {
|
||||||
}
|
}
|
||||||
this.startFetchProjectGroupsLoading();
|
this.startFetchProjectGroupsLoading();
|
||||||
let { data, error, aborted } = await fetchProjectGroupSubgroups(
|
let { data, error, aborted } = await fetchProjectGroupSubgroups(
|
||||||
projectgroupref.join("/"),
|
projectgroupref.join('/'),
|
||||||
this.fetchAbort.signal
|
this.fetchAbort.signal
|
||||||
);
|
);
|
||||||
this.stopFetchProjectGroupsLoading();
|
this.stopFetchProjectGroupsLoading();
|
||||||
|
@ -135,13 +142,13 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.projectgroups = data;
|
this.projectgroups = data;
|
||||||
},
|
},
|
||||||
projectLink: projectLink,
|
projectLink: projectLink,
|
||||||
projectGroupLink: projectGroupLink
|
projectGroupLink: projectGroupLink,
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
this.fetchAbort = new AbortController();
|
this.fetchAbort = new AbortController();
|
||||||
|
@ -152,9 +159,8 @@ export default {
|
||||||
if (this.fetchAbort) {
|
if (this.fetchAbort) {
|
||||||
this.fetchAbort.abort();
|
this.fetchAbort.abort();
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
|
@ -7,33 +7,34 @@
|
||||||
<hr class="my-6 border-t" />
|
<hr class="my-6 border-t" />
|
||||||
|
|
||||||
<h5 class="text-2xl">All secrets (local and inherited)</h5>
|
<h5 class="text-2xl">All secrets (local and inherited)</h5>
|
||||||
<secrets v-if="allsecrets.length" :secrets="allsecrets" :showparentpath="true" />
|
<secrets
|
||||||
|
v-if="allsecrets.length"
|
||||||
|
:secrets="allsecrets"
|
||||||
|
:showparentpath="true"
|
||||||
|
/>
|
||||||
<span v-else>No secrets</span>
|
<span v-else>No secrets</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import secrets from "@/components/secrets";
|
import secrets from '@/components/secrets';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { secrets },
|
components: { secrets },
|
||||||
name: "projectsecrets",
|
name: 'projectsecrets',
|
||||||
props: {
|
props: {
|
||||||
secrets: Array,
|
secrets: Array,
|
||||||
allsecrets: Array,
|
allsecrets: Array,
|
||||||
type: String
|
type: String,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
typetitle() {
|
typetitle() {
|
||||||
if (this.type == "project") return "Project";
|
if (this.type == 'project') return 'Project';
|
||||||
if (this.type == "projectgroup") return "Project group";
|
if (this.type == 'projectgroup') return 'Project group';
|
||||||
return "";
|
return '';
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,8 @@
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label class="checkbox">
|
<label class="checkbox">
|
||||||
<input type="checkbox" v-model="project.pass_vars_to_forked_pr" />
|
<input type="checkbox" v-model="project.pass_vars_to_forked_pr" />
|
||||||
Pass variables to run even if triggered by PR from forked repo (DANGEROUS)
|
Pass variables to run even if triggered by PR from forked repo
|
||||||
|
(DANGEROUS)
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-blue" @click="updateProject()">Update</button>
|
<button class="btn btn-blue" @click="updateProject()">Update</button>
|
||||||
|
@ -38,14 +39,22 @@
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<p class="panel-title">Secrets</p>
|
<p class="panel-title">Secrets</p>
|
||||||
<div class="p-4">
|
<div class="p-4">
|
||||||
<projectsecrets :secrets="secrets" :allsecrets="allsecrets" type="project" />
|
<projectsecrets
|
||||||
|
:secrets="secrets"
|
||||||
|
:allsecrets="allsecrets"
|
||||||
|
type="project"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<p class="panel-title">Variables</p>
|
<p class="panel-title">Variables</p>
|
||||||
<div class="p-4">
|
<div class="p-4">
|
||||||
<projectvars :variables="variables" :allvariables="allvariables" type="project" />
|
<projectvars
|
||||||
|
:variables="variables"
|
||||||
|
:allvariables="allvariables"
|
||||||
|
type="project"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -59,16 +68,13 @@
|
||||||
>
|
>
|
||||||
<p>
|
<p>
|
||||||
This operation
|
This operation
|
||||||
<strong>CANNOT</strong> be undone.
|
<strong>CANNOT</strong> be undone. This operation will remove
|
||||||
This operation will remove
|
|
||||||
<strong>{{ projectPath }}</strong>
|
<strong>{{ projectPath }}</strong>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<label class="block mb-2">
|
<label class="block mb-2">
|
||||||
Please type the project name for confirmation:
|
Please type the project name for confirmation:
|
||||||
<span
|
<span class="text-red-500 font-bold">{{ projectName }}</span>
|
||||||
class="text-red-500 font-bold"
|
|
||||||
>{{ projectName }}</span>
|
|
||||||
</label>
|
</label>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<input
|
<input
|
||||||
|
@ -82,7 +88,9 @@
|
||||||
class="btn btn-red"
|
class="btn btn-red"
|
||||||
@click="deleteProject()"
|
@click="deleteProject()"
|
||||||
:disabled="!deleteButtonEnabled"
|
:disabled="!deleteButtonEnabled"
|
||||||
>Delete Project</button>
|
>
|
||||||
|
Delete Project
|
||||||
|
</button>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="deleteProjectError"
|
v-if="deleteProjectError"
|
||||||
|
@ -93,21 +101,30 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="p-4 border-t">
|
<div class="p-4 border-t">
|
||||||
<h4 class="mb-4 title text-xl">Change remote repository linked account</h4>
|
<h4 class="mb-4 title text-xl">
|
||||||
|
Change remote repository linked account
|
||||||
|
</h4>
|
||||||
<div
|
<div
|
||||||
class="mb-4 bg-red-100 border-l-4 border-red-500 text-red-700 p-4 rounded"
|
class="mb-4 bg-red-100 border-l-4 border-red-500 text-red-700 p-4 rounded"
|
||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
<p>This operation will change the linked account associated with the project remote repository to the current user linked account</p>
|
<p>
|
||||||
|
This operation will change the linked account associated with the
|
||||||
|
project remote repository to the current user linked account
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-red" @click="updateRepoLinkedAccount()">Change</button>
|
<button class="btn btn-red" @click="updateRepoLinkedAccount()">
|
||||||
|
Change
|
||||||
|
</button>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="updateRepoLinkedAccountError"
|
v-if="updateRepoLinkedAccountError"
|
||||||
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
<span class="block sm:inline">{{ updateRepoLinkedAccountError }}</span>
|
<span class="block sm:inline">{{
|
||||||
|
updateRepoLinkedAccountError
|
||||||
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -121,21 +138,21 @@ import {
|
||||||
fetchVariables,
|
fetchVariables,
|
||||||
updateProject,
|
updateProject,
|
||||||
deleteProject,
|
deleteProject,
|
||||||
projectUpdateRepoLinkedAccount
|
projectUpdateRepoLinkedAccount,
|
||||||
} from "@/util/data.js";
|
} from '@/util/data.js';
|
||||||
|
|
||||||
import { projectGroupLink } from "@/util/link.js";
|
import { projectGroupLink } from '@/util/link.js';
|
||||||
|
|
||||||
import projectsecrets from "@/components/projectsecrets";
|
import projectsecrets from '@/components/projectsecrets';
|
||||||
import projectvars from "@/components/projectvars";
|
import projectvars from '@/components/projectvars';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { projectsecrets, projectvars },
|
components: { projectsecrets, projectvars },
|
||||||
name: "projectsettings",
|
name: 'projectsettings',
|
||||||
props: {
|
props: {
|
||||||
ownertype: String,
|
ownertype: String,
|
||||||
ownername: String,
|
ownername: String,
|
||||||
projectref: Array
|
projectref: Array,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -148,7 +165,7 @@ export default {
|
||||||
allsecrets: [],
|
allsecrets: [],
|
||||||
variables: [],
|
variables: [],
|
||||||
allvariables: [],
|
allvariables: [],
|
||||||
projectNameToDelete: ""
|
projectNameToDelete: '',
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -156,11 +173,11 @@ export default {
|
||||||
return this.projectref[this.projectref.length - 1];
|
return this.projectref[this.projectref.length - 1];
|
||||||
},
|
},
|
||||||
projectPath: function () {
|
projectPath: function () {
|
||||||
return ["", this.ownertype, this.ownername, ...this.projectref].join("/");
|
return ['', this.ownertype, this.ownername, ...this.projectref].join('/');
|
||||||
},
|
},
|
||||||
deleteButtonEnabled: function () {
|
deleteButtonEnabled: function () {
|
||||||
return this.projectNameToDelete == this.projectName;
|
return this.projectNameToDelete == this.projectName;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
resetErrors() {
|
resetErrors() {
|
||||||
|
@ -174,12 +191,12 @@ export default {
|
||||||
let projectref = [
|
let projectref = [
|
||||||
this.ownertype,
|
this.ownertype,
|
||||||
this.ownername,
|
this.ownername,
|
||||||
...this.projectref
|
...this.projectref,
|
||||||
].join("/");
|
].join('/');
|
||||||
|
|
||||||
let visibility = "public";
|
let visibility = 'public';
|
||||||
if (this.projectIsPrivate) {
|
if (this.projectIsPrivate) {
|
||||||
visibility = "private";
|
visibility = 'private';
|
||||||
}
|
}
|
||||||
let { error } = await updateProject(
|
let { error } = await updateProject(
|
||||||
projectref,
|
projectref,
|
||||||
|
@ -198,8 +215,8 @@ export default {
|
||||||
let projectref = [
|
let projectref = [
|
||||||
this.ownertype,
|
this.ownertype,
|
||||||
this.ownername,
|
this.ownername,
|
||||||
...this.projectref
|
...this.projectref,
|
||||||
].join("/");
|
].join('/');
|
||||||
|
|
||||||
if (this.projectNameToDelete == this.projectName) {
|
if (this.projectNameToDelete == this.projectName) {
|
||||||
let { error } = await deleteProject(projectref);
|
let { error } = await deleteProject(projectref);
|
||||||
|
@ -222,60 +239,59 @@ export default {
|
||||||
let projectref = [
|
let projectref = [
|
||||||
this.ownertype,
|
this.ownertype,
|
||||||
this.ownername,
|
this.ownername,
|
||||||
...this.projectref
|
...this.projectref,
|
||||||
].join("/");
|
].join('/');
|
||||||
|
|
||||||
let { error } = await projectUpdateRepoLinkedAccount(projectref);
|
let { error } = await projectUpdateRepoLinkedAccount(projectref);
|
||||||
if (error) {
|
if (error) {
|
||||||
this.updateRepoLinkedAccountError = error;
|
this.updateRepoLinkedAccountError = error;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created: async function () {
|
created: async function () {
|
||||||
let projectref = [this.ownertype, this.ownername, ...this.projectref].join(
|
let projectref = [this.ownertype, this.ownername, ...this.projectref].join(
|
||||||
"/"
|
'/'
|
||||||
);
|
);
|
||||||
|
|
||||||
let { data, error } = await fetchProject(projectref);
|
let { data, error } = await fetchProject(projectref);
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.project = data;
|
this.project = data;
|
||||||
this.projectIsPrivate = this.project.visibility == "private";
|
this.projectIsPrivate = this.project.visibility == 'private';
|
||||||
|
|
||||||
({ data, error } = await fetchSecrets("project", projectref, false));
|
({ data, error } = await fetchSecrets('project', projectref, false));
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.secrets = data;
|
this.secrets = data;
|
||||||
|
|
||||||
({ data, error } = await fetchSecrets("project", projectref, true));
|
({ data, error } = await fetchSecrets('project', projectref, true));
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.allsecrets = data;
|
this.allsecrets = data;
|
||||||
|
|
||||||
({ data, error } = await fetchVariables("project", projectref, false));
|
({ data, error } = await fetchVariables('project', projectref, false));
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.variables = data;
|
this.variables = data;
|
||||||
|
|
||||||
({ data, error } = await fetchVariables("project", projectref, true));
|
({ data, error } = await fetchVariables('project', projectref, true));
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.allvariables = data;
|
this.allvariables = data;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
|
@ -7,32 +7,34 @@
|
||||||
<hr class="my-6 border-t" />
|
<hr class="my-6 border-t" />
|
||||||
|
|
||||||
<h5 class="text-2xl">All variables (local and inherited)</h5>
|
<h5 class="text-2xl">All variables (local and inherited)</h5>
|
||||||
<vars v-if="allvariables.length" :variables="allvariables" :showparentpath="true" />
|
<vars
|
||||||
|
v-if="allvariables.length"
|
||||||
|
:variables="allvariables"
|
||||||
|
:showparentpath="true"
|
||||||
|
/>
|
||||||
<span v-else>No variables</span>
|
<span v-else>No variables</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import vars from "@/components/vars";
|
import vars from '@/components/vars';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { vars },
|
components: { vars },
|
||||||
name: "projectvars",
|
name: 'projectvars',
|
||||||
props: {
|
props: {
|
||||||
variables: Array,
|
variables: Array,
|
||||||
allvariables: Array,
|
allvariables: Array,
|
||||||
type: String
|
type: String,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
typetitle() {
|
typetitle() {
|
||||||
if (this.type == "project") return "Project";
|
if (this.type == 'project') return 'Project';
|
||||||
if (this.type == "projectgroup") return "Project group";
|
if (this.type == 'projectgroup') return 'Project group';
|
||||||
return "";
|
return '';
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,9 @@
|
||||||
@submit.prevent="$emit('login', { username })"
|
@submit.prevent="$emit('login', { username })"
|
||||||
>
|
>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label class="block text-sm font-bold mb-2" for="username">Remote Username</label>
|
<label class="block text-sm font-bold mb-2" for="username"
|
||||||
|
>Remote Username</label
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||||
id="username"
|
id="username"
|
||||||
|
@ -13,38 +15,38 @@
|
||||||
placeholder="Username"
|
placeholder="Username"
|
||||||
:disabled="true"
|
:disabled="true"
|
||||||
v-model="remoteUsername"
|
v-model="remoteUsername"
|
||||||
>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label class="block text-sm font-bold mb-2" for="username">Username</label>
|
<label class="block text-sm font-bold mb-2" for="username"
|
||||||
|
>Username</label
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||||
id="username"
|
id="username"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Username"
|
placeholder="Username"
|
||||||
v-model="username"
|
v-model="username"
|
||||||
>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-center">
|
<div class="flex justify-center">
|
||||||
<button
|
<button
|
||||||
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
|
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
|
||||||
type="submit"
|
type="submit"
|
||||||
>Register</button>
|
>
|
||||||
|
Register
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "RegisterForm",
|
name: 'RegisterForm',
|
||||||
props: {
|
props: {
|
||||||
remoteUsername: String,
|
remoteUsername: String,
|
||||||
username: String
|
username: String,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
v-bind:key="repo.id"
|
v-bind:key="repo.id"
|
||||||
@click="select(index)"
|
@click="select(index)"
|
||||||
>
|
>
|
||||||
<input type="radio" :checked="selectedrepo == index">
|
<input type="radio" :checked="selectedrepo == index" />
|
||||||
{{ repo.path }}
|
{{ repo.path }}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -18,23 +18,22 @@
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: {},
|
||||||
name: "remoterepos",
|
name: 'remoterepos',
|
||||||
props: {
|
props: {
|
||||||
remoterepos: Array
|
remoterepos: Array,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
selectedrepo: null
|
selectedrepo: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
select(index) {
|
select(index) {
|
||||||
this.selectedrepo = index;
|
this.selectedrepo = index;
|
||||||
this.$emit("reposelected", this.remoterepos[index].path);
|
this.$emit('reposelected', this.remoterepos[index].path);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
|
@ -31,15 +31,23 @@
|
||||||
<span
|
<span
|
||||||
class="mr-3 rounded px-2 py-1 text-xs"
|
class="mr-3 rounded px-2 py-1 text-xs"
|
||||||
:class="'is-' + runResultClass(run)"
|
:class="'is-' + runResultClass(run)"
|
||||||
>{{ runStatus(run) | capitalize }}</span>
|
>{{ runStatus(run) | capitalize }}</span
|
||||||
|
>
|
||||||
<span
|
<span
|
||||||
v-if="stillRunning(run)"
|
v-if="stillRunning(run)"
|
||||||
class="rounded bg-gray-500 text-white px-2 py-1 text-xs"
|
class="rounded bg-gray-500 text-white px-2 py-1 text-xs"
|
||||||
>Still running</span>
|
>Still running</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="mb-6">
|
||||||
|
{{ run.annotations.message.split(/\r?\n/)[0] }}
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-6">{{run.annotations.message.split(/\r?\n/)[0]}}</div>
|
|
||||||
<div>
|
<div>
|
||||||
<a :href="run.annotations.commit_link" class="block" target="_blank">
|
<a
|
||||||
|
:href="run.annotations.commit_link"
|
||||||
|
class="block"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
<i class="mdi mdi-source-commit mdi-rotate-90"></i>
|
<i class="mdi mdi-source-commit mdi-rotate-90"></i>
|
||||||
<span>{{ run.annotations.commit_sha.substring(0, 8) }}</span>
|
<span>{{ run.annotations.commit_sha.substring(0, 8) }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
@ -85,12 +93,18 @@
|
||||||
<div class="w-1/6 flex items-start justify-between">
|
<div class="w-1/6 flex items-start justify-between">
|
||||||
<div class="relative ml-auto mr-3">
|
<div class="relative ml-auto mr-3">
|
||||||
<div
|
<div
|
||||||
v-if="run.can_restart_from_scratch || run.can_restart_from_failed_tasks"
|
v-if="
|
||||||
|
run.can_restart_from_scratch ||
|
||||||
|
run.can_restart_from_failed_tasks
|
||||||
|
"
|
||||||
class="flex"
|
class="flex"
|
||||||
v-click-outside="() => dropdownActive = false"
|
v-click-outside="() => (dropdownActive = false)"
|
||||||
>
|
>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<button class="btn btn-blue" @click="dropdownActive = !dropdownActive">
|
<button
|
||||||
|
class="btn btn-blue"
|
||||||
|
@click="dropdownActive = !dropdownActive"
|
||||||
|
>
|
||||||
<span>Restart</span>
|
<span>Restart</span>
|
||||||
<i class="ml-3 mdi mdi-restart" aria-hidden="true"></i>
|
<i class="ml-3 mdi mdi-restart" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
|
@ -107,14 +121,16 @@
|
||||||
v-if="run.can_restart_from_scratch"
|
v-if="run.can_restart_from_scratch"
|
||||||
class="block px-4 py-2 hover:bg-blue-500 hover:text-white cursor-pointer"
|
class="block px-4 py-2 hover:bg-blue-500 hover:text-white cursor-pointer"
|
||||||
@click="restartRun(run.id, true)"
|
@click="restartRun(run.id, true)"
|
||||||
>From start</a>
|
>From start</a
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
v-if="run.can_restart_from_failed_tasks"
|
v-if="run.can_restart_from_failed_tasks"
|
||||||
class="block px-4 py-2 hover:bg-blue-500 hover:text-white cursor-pointer"
|
class="block px-4 py-2 hover:bg-blue-500 hover:text-white cursor-pointer"
|
||||||
@click="restartRun(run.id)"
|
@click="restartRun(run.id)"
|
||||||
>From failed tasks</a>
|
>From failed tasks</a
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -122,13 +138,17 @@
|
||||||
class="btn btn-red"
|
class="btn btn-red"
|
||||||
v-if="run.phase == 'queued'"
|
v-if="run.phase == 'queued'"
|
||||||
@click="cancelRun(run.id)"
|
@click="cancelRun(run.id)"
|
||||||
>Cancel</button>
|
>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
class="btn btn-red"
|
class="btn btn-red"
|
||||||
v-if="run.phase == 'running'"
|
v-if="run.phase == 'running'"
|
||||||
:disabled="run.stopping"
|
:disabled="run.stopping"
|
||||||
@click="stopRun(run.id)"
|
@click="stopRun(run.id)"
|
||||||
>Stop</button>
|
>
|
||||||
|
Stop
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -138,27 +158,27 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as vClickOutside from "v-click-outside-x";
|
import * as vClickOutside from 'v-click-outside-x';
|
||||||
|
|
||||||
import { cancelRun, stopRun, restartRun } from "@/util/data.js";
|
import { cancelRun, stopRun, restartRun } from '@/util/data.js';
|
||||||
import { userDirectRunLink, projectRunLink } from "@/util/link.js";
|
import { userDirectRunLink, projectRunLink } from '@/util/link.js';
|
||||||
import { runStatus, runResultClass } from "@/util/run.js";
|
import { runStatus, runResultClass } from '@/util/run.js';
|
||||||
|
|
||||||
import * as moment from "moment";
|
import * as moment from 'moment';
|
||||||
import momentDurationFormatSetup from "moment-duration-format";
|
import momentDurationFormatSetup from 'moment-duration-format';
|
||||||
|
|
||||||
momentDurationFormatSetup(moment);
|
momentDurationFormatSetup(moment);
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "rundetail",
|
name: 'rundetail',
|
||||||
directives: {
|
directives: {
|
||||||
clickOutside: vClickOutside.directive
|
clickOutside: vClickOutside.directive,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
ownertype: String,
|
ownertype: String,
|
||||||
ownername: String,
|
ownername: String,
|
||||||
projectref: Array,
|
projectref: Array,
|
||||||
run: Object
|
run: Object,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -166,7 +186,7 @@ export default {
|
||||||
stopRunError: null,
|
stopRunError: null,
|
||||||
cancelRunError: null,
|
cancelRunError: null,
|
||||||
restartRunError: null,
|
restartRunError: null,
|
||||||
dropdownActive: false
|
dropdownActive: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -178,14 +198,14 @@ export default {
|
||||||
this.restartRunError = null;
|
this.restartRunError = null;
|
||||||
},
|
},
|
||||||
stillRunning(run) {
|
stillRunning(run) {
|
||||||
return run.result != "unknown" && run.phase == "running";
|
return run.result != 'unknown' && run.phase == 'running';
|
||||||
},
|
},
|
||||||
taskClass(task) {
|
taskClass(task) {
|
||||||
if (task.status == "success") return "success";
|
if (task.status == 'success') return 'success';
|
||||||
if (task.status == "failed") return "failed";
|
if (task.status == 'failed') return 'failed';
|
||||||
if (task.status == "stopped") return "failed";
|
if (task.status == 'stopped') return 'failed';
|
||||||
if (task.status == "running") return "running";
|
if (task.status == 'running') return 'running';
|
||||||
return "unknown";
|
return 'unknown';
|
||||||
},
|
},
|
||||||
async stopRun(runid) {
|
async stopRun(runid) {
|
||||||
this.resetErrors();
|
this.resetErrors();
|
||||||
|
@ -207,7 +227,7 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.run.phase = "cancelled";
|
this.run.phase = 'cancelled';
|
||||||
},
|
},
|
||||||
async restartRun(runid, fromStart) {
|
async restartRun(runid, fromStart) {
|
||||||
this.dropdownActive = false;
|
this.dropdownActive = false;
|
||||||
|
@ -231,7 +251,7 @@ export default {
|
||||||
this.$router.push(runLink);
|
this.$router.push(runLink);
|
||||||
},
|
},
|
||||||
duration(run) {
|
duration(run) {
|
||||||
let formatString = "h:mm:ss[s]";
|
let formatString = 'h:mm:ss[s]';
|
||||||
let start = moment(run.start_time);
|
let start = moment(run.start_time);
|
||||||
let end = moment(run.end_time);
|
let end = moment(run.end_time);
|
||||||
|
|
||||||
|
@ -244,30 +264,29 @@ export default {
|
||||||
return moment.duration(end.diff(start)).format(formatString);
|
return moment.duration(end.diff(start)).format(formatString);
|
||||||
},
|
},
|
||||||
endTime(run) {
|
endTime(run) {
|
||||||
let formatString = "lll";
|
let formatString = 'lll';
|
||||||
let end = moment(run.end_time);
|
let end = moment(run.end_time);
|
||||||
|
|
||||||
if (run.end_time === null) {
|
if (run.end_time === null) {
|
||||||
return "";
|
return '';
|
||||||
}
|
}
|
||||||
return "Finished " + end.format(formatString);
|
return 'Finished ' + end.format(formatString);
|
||||||
},
|
},
|
||||||
endTimeHuman(run) {
|
endTimeHuman(run) {
|
||||||
let end = moment(run.end_time);
|
let end = moment(run.end_time);
|
||||||
|
|
||||||
if (run.end_time === null) {
|
if (run.end_time === null) {
|
||||||
return "";
|
return '';
|
||||||
}
|
}
|
||||||
return end.fromNow();
|
return end.fromNow();
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
window.setInterval(() => {
|
window.setInterval(() => {
|
||||||
this.now = moment();
|
this.now = moment();
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ml-6 flex w-48">
|
<div class="ml-6 flex w-48">
|
||||||
<div v-bind:class="{ 'spinner': fetchRunsLoading }"></div>
|
<div v-bind:class="{ spinner: fetchRunsLoading }"></div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="runs">
|
<div v-if="runs">
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -67,14 +67,20 @@
|
||||||
<span
|
<span
|
||||||
v-if="waitingApproval(run)"
|
v-if="waitingApproval(run)"
|
||||||
class="w-2/12 bg-gray-200 rounded-full px-3 py-1 text-sm text-center font-semibold mr-2"
|
class="w-2/12 bg-gray-200 rounded-full px-3 py-1 text-sm text-center font-semibold mr-2"
|
||||||
>Waiting Approval</span>
|
>Waiting Approval</span
|
||||||
|
>
|
||||||
<span
|
<span
|
||||||
v-if="stillRunning(run)"
|
v-if="stillRunning(run)"
|
||||||
class="w-2/12 bg-gray-200 rounded-full px-3 py-1 text-sm text-center font-semibold mr-2"
|
class="w-2/12 bg-gray-200 rounded-full px-3 py-1 text-sm text-center font-semibold mr-2"
|
||||||
>Still running</span>
|
>Still running</span
|
||||||
|
>
|
||||||
<div class="w-32">
|
<div class="w-32">
|
||||||
<span>#{{ run.counter }}</span>
|
<span>#{{ run.counter }}</span>
|
||||||
<a :href="run.annotations.commit_link" class="block" target="_blank">
|
<a
|
||||||
|
:href="run.annotations.commit_link"
|
||||||
|
class="block"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
<i class="mdi mdi-source-commit mdi-rotate-90 mr-1"></i>
|
<i class="mdi mdi-source-commit mdi-rotate-90 mr-1"></i>
|
||||||
<span>{{ run.annotations.commit_sha.substring(0, 8) }}</span>
|
<span>{{ run.annotations.commit_sha.substring(0, 8) }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
@ -97,7 +103,9 @@
|
||||||
v-if="hasMoreRuns"
|
v-if="hasMoreRuns"
|
||||||
class="bg-transparent hover:bg-blue-500 text-blue-700 font-semibold hover:text-white py-2 px-4 border border-blue-500 hover:border-transparent rounded"
|
class="bg-transparent hover:bg-blue-500 text-blue-700 font-semibold hover:text-white py-2 px-4 border border-blue-500 hover:border-transparent rounded"
|
||||||
@click="loadMoreRuns()"
|
@click="loadMoreRuns()"
|
||||||
>Load more...</button>
|
>
|
||||||
|
Load more...
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="runs && runs.length == 0" class>No runs</div>
|
<div v-if="runs && runs.length == 0" class>No runs</div>
|
||||||
|
@ -105,22 +113,22 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { fetchUser, fetchProject, fetchRuns } from "@/util/data.js";
|
import { fetchUser, fetchProject, fetchRuns } from '@/util/data.js';
|
||||||
import { userDirectRunLink, projectRunLink } from "@/util/link.js";
|
import { userDirectRunLink, projectRunLink } from '@/util/link.js';
|
||||||
import { runResultClass } from "@/util/run.js";
|
import { runResultClass } from '@/util/run.js';
|
||||||
import * as moment from "moment";
|
import * as moment from 'moment';
|
||||||
import momentDurationFormatSetup from "moment-duration-format";
|
import momentDurationFormatSetup from 'moment-duration-format';
|
||||||
|
|
||||||
momentDurationFormatSetup(moment);
|
momentDurationFormatSetup(moment);
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: {},
|
||||||
name: "runs",
|
name: 'runs',
|
||||||
props: {
|
props: {
|
||||||
ownertype: String,
|
ownertype: String,
|
||||||
ownername: String,
|
ownername: String,
|
||||||
projectref: Array,
|
projectref: Array,
|
||||||
query: String
|
query: String,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -137,7 +145,7 @@ export default {
|
||||||
wantedRunsNumber: 25,
|
wantedRunsNumber: 25,
|
||||||
hasMoreRuns: false,
|
hasMoreRuns: false,
|
||||||
project: null,
|
project: null,
|
||||||
user: null
|
user: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -145,7 +153,7 @@ export default {
|
||||||
this.runs = null;
|
this.runs = null;
|
||||||
this.hasMoreRuns = false;
|
this.hasMoreRuns = false;
|
||||||
this.update();
|
this.update();
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
projectRunLink: projectRunLink,
|
projectRunLink: projectRunLink,
|
||||||
|
@ -161,7 +169,7 @@ export default {
|
||||||
this.fetchRunsLoading = false;
|
this.fetchRunsLoading = false;
|
||||||
},
|
},
|
||||||
stillRunning(run) {
|
stillRunning(run) {
|
||||||
return run.result != "unknown" && run.phase == "running";
|
return run.result != 'unknown' && run.phase == 'running';
|
||||||
},
|
},
|
||||||
waitingApproval(run) {
|
waitingApproval(run) {
|
||||||
return run.tasks_waiting_approval.length > 0;
|
return run.tasks_waiting_approval.length > 0;
|
||||||
|
@ -183,8 +191,8 @@ export default {
|
||||||
let projectref = [
|
let projectref = [
|
||||||
this.ownertype,
|
this.ownertype,
|
||||||
this.ownername,
|
this.ownername,
|
||||||
...this.projectref
|
...this.projectref,
|
||||||
].join("/");
|
].join('/');
|
||||||
|
|
||||||
let { data, error, aborted } = await fetchProject(
|
let { data, error, aborted } = await fetchProject(
|
||||||
projectref,
|
projectref,
|
||||||
|
@ -194,7 +202,7 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.project = data;
|
this.project = data;
|
||||||
|
@ -212,7 +220,7 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.user = data;
|
this.user = data;
|
||||||
|
@ -228,17 +236,17 @@ export default {
|
||||||
let group;
|
let group;
|
||||||
let lastrun = false;
|
let lastrun = false;
|
||||||
if (this.project !== null) {
|
if (this.project !== null) {
|
||||||
if (this.query == "branches") {
|
if (this.query == 'branches') {
|
||||||
group = "/project/" + this.project.id + "/branch";
|
group = '/project/' + this.project.id + '/branch';
|
||||||
} else if (this.query == "tags") {
|
} else if (this.query == 'tags') {
|
||||||
group = "/project/" + this.project.id + "/tag";
|
group = '/project/' + this.project.id + '/tag';
|
||||||
} else if (this.query == "pullrequests") {
|
} else if (this.query == 'pullrequests') {
|
||||||
group = "/project/" + this.project.id + "/pr";
|
group = '/project/' + this.project.id + '/pr';
|
||||||
} else {
|
} else {
|
||||||
group = "/project/" + this.project.id;
|
group = '/project/' + this.project.id;
|
||||||
}
|
}
|
||||||
} else if (this.user !== null) {
|
} else if (this.user !== null) {
|
||||||
group = "/user/" + this.user.id;
|
group = '/user/' + this.user.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
let newRuns = [];
|
let newRuns = [];
|
||||||
|
@ -289,7 +297,7 @@ export default {
|
||||||
}, 2000);
|
}, 2000);
|
||||||
},
|
},
|
||||||
duration(run) {
|
duration(run) {
|
||||||
let formatString = "h:mm:ss[s]";
|
let formatString = 'h:mm:ss[s]';
|
||||||
let start = moment(run.start_time);
|
let start = moment(run.start_time);
|
||||||
let end = moment(run.end_time);
|
let end = moment(run.end_time);
|
||||||
|
|
||||||
|
@ -302,22 +310,22 @@ export default {
|
||||||
return moment.duration(end.diff(start)).format(formatString);
|
return moment.duration(end.diff(start)).format(formatString);
|
||||||
},
|
},
|
||||||
endTime(run) {
|
endTime(run) {
|
||||||
let formatString = "lll";
|
let formatString = 'lll';
|
||||||
let end = moment(run.end_time);
|
let end = moment(run.end_time);
|
||||||
|
|
||||||
if (run.end_time === null) {
|
if (run.end_time === null) {
|
||||||
return "";
|
return '';
|
||||||
}
|
}
|
||||||
return "Finished " + end.format(formatString);
|
return 'Finished ' + end.format(formatString);
|
||||||
},
|
},
|
||||||
endTimeHuman(run) {
|
endTimeHuman(run) {
|
||||||
let end = moment(run.end_time);
|
let end = moment(run.end_time);
|
||||||
|
|
||||||
if (run.end_time === null) {
|
if (run.end_time === null) {
|
||||||
return "";
|
return '';
|
||||||
}
|
}
|
||||||
return end.fromNow();
|
return end.fromNow();
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
window.setInterval(() => {
|
window.setInterval(() => {
|
||||||
|
@ -331,9 +339,8 @@ export default {
|
||||||
this.fetchAbort.abort();
|
this.fetchAbort.abort();
|
||||||
}
|
}
|
||||||
clearTimeout(this.fetchRunsSchedule);
|
clearTimeout(this.fetchRunsSchedule);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
|
@ -7,7 +7,12 @@
|
||||||
>
|
>
|
||||||
<div>{{ fetchRunError }}</div>
|
<div>{{ fetchRunError }}</div>
|
||||||
</div>
|
</div>
|
||||||
<rundetail :run="run" :ownertype="ownertype" :ownername="ownername" :projectref="projectref" />
|
<rundetail
|
||||||
|
:run="run"
|
||||||
|
:ownertype="ownertype"
|
||||||
|
:ownername="ownername"
|
||||||
|
:projectref="projectref"
|
||||||
|
/>
|
||||||
<div v-if="run">
|
<div v-if="run">
|
||||||
<div v-if="run.phase != 'setuperror'">
|
<div v-if="run.phase != 'setuperror'">
|
||||||
<div class="flex items-center my-6 justify-between">
|
<div class="flex items-center my-6 justify-between">
|
||||||
|
@ -42,7 +47,8 @@
|
||||||
class="font-mono leading-snug text-xs"
|
class="font-mono leading-snug text-xs"
|
||||||
v-for="(error, i) in run.setup_errors"
|
v-for="(error, i) in run.setup_errors"
|
||||||
v-bind:key="i"
|
v-bind:key="i"
|
||||||
>{{error}}</pre>
|
>{{ error }}</pre
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -50,21 +56,21 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { fetchRun } from "@/util/data.js";
|
import { fetchRun } from '@/util/data.js';
|
||||||
import { userDirectRunTaskLink, projectRunTaskLink } from "@/util/link.js";
|
import { userDirectRunTaskLink, projectRunTaskLink } from '@/util/link.js';
|
||||||
|
|
||||||
import rundetail from "@/components/rundetail.vue";
|
import rundetail from '@/components/rundetail.vue';
|
||||||
import tasks from "@/components/tasks.vue";
|
import tasks from '@/components/tasks.vue';
|
||||||
import tasksgraph from "@/components/tasksgraph.vue";
|
import tasksgraph from '@/components/tasksgraph.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "runsummary",
|
name: 'runsummary',
|
||||||
components: { rundetail, tasks, tasksgraph },
|
components: { rundetail, tasks, tasksgraph },
|
||||||
props: {
|
props: {
|
||||||
ownertype: String,
|
ownertype: String,
|
||||||
ownername: String,
|
ownername: String,
|
||||||
projectref: Array,
|
projectref: Array,
|
||||||
runid: String
|
runid: String,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -80,7 +86,7 @@ export default {
|
||||||
taskYSpace: 20,
|
taskYSpace: 20,
|
||||||
hoverTask: null,
|
hoverTask: null,
|
||||||
|
|
||||||
tasksDisplay: "graph"
|
tasksDisplay: 'graph',
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -93,7 +99,7 @@ export default {
|
||||||
this.fetchAbort = new AbortController();
|
this.fetchAbort = new AbortController();
|
||||||
|
|
||||||
this.fetchRun();
|
this.fetchRun();
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
runTaskLink(task) {
|
runTaskLink(task) {
|
||||||
|
@ -110,16 +116,16 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
parents(task) {
|
parents(task) {
|
||||||
return Object.keys(task.depends).map(key => {
|
return Object.keys(task.depends).map((key) => {
|
||||||
return this.run.tasks[task.depends[key].task_id].name;
|
return this.run.tasks[task.depends[key].task_id].name;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
taskClass(task) {
|
taskClass(task) {
|
||||||
if (task.status == "success") return "success";
|
if (task.status == 'success') return 'success';
|
||||||
if (task.status == "failed") return "failed";
|
if (task.status == 'failed') return 'failed';
|
||||||
if (task.status == "stopped") return "failed";
|
if (task.status == 'stopped') return 'failed';
|
||||||
if (task.status == "running") return "running";
|
if (task.status == 'running') return 'running';
|
||||||
return "unknown";
|
return 'unknown';
|
||||||
},
|
},
|
||||||
async fetchRun() {
|
async fetchRun() {
|
||||||
let { data, error, aborted } = await fetchRun(
|
let { data, error, aborted } = await fetchRun(
|
||||||
|
@ -145,9 +151,8 @@ export default {
|
||||||
let task = tasks[taskID];
|
let task = tasks[taskID];
|
||||||
task.link = this.runTaskLink(task);
|
task.link = this.runTaskLink(task);
|
||||||
task.parents = this.parents(task);
|
task.parents = this.parents(task);
|
||||||
task.waiting_approval = this.run.tasks_waiting_approval.includes(
|
task.waiting_approval =
|
||||||
taskID
|
this.run.tasks_waiting_approval.includes(taskID);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.scheduleFetchRun();
|
this.scheduleFetchRun();
|
||||||
|
@ -157,7 +162,7 @@ export default {
|
||||||
this.fetchRunSchedule = setTimeout(() => {
|
this.fetchRunSchedule = setTimeout(() => {
|
||||||
this.fetchRun();
|
this.fetchRun();
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
this.fetchAbort = new AbortController();
|
this.fetchAbort = new AbortController();
|
||||||
|
@ -168,9 +173,8 @@ export default {
|
||||||
this.fetchAbort.abort();
|
this.fetchAbort.abort();
|
||||||
}
|
}
|
||||||
clearTimeout(this.fetchRunSchedule);
|
clearTimeout(this.fetchRunSchedule);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
|
@ -6,7 +6,9 @@
|
||||||
<div class="flex" v-for="secret in secrets" v-bind:key="secret.id">
|
<div class="flex" v-for="secret in secrets" v-bind:key="secret.id">
|
||||||
<div class="w-2/12">
|
<div class="w-2/12">
|
||||||
<span class="name">{{ secret.name }}</span>
|
<span class="name">{{ secret.name }}</span>
|
||||||
<div v-if="showparentpath" class="text-sm font-light">from {{secret.parent_path}}</div>
|
<div v-if="showparentpath" class="text-sm font-light">
|
||||||
|
from {{ secret.parent_path }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -15,16 +17,12 @@
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: {},
|
||||||
name: "secrets",
|
name: 'secrets',
|
||||||
props: {
|
props: {
|
||||||
secrets: Array,
|
secrets: Array,
|
||||||
showparentpath: Boolean
|
showparentpath: Boolean,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,18 +20,24 @@
|
||||||
<div v-if="step.type == 'run'">
|
<div v-if="step.type == 'run'">
|
||||||
<div class="p-3 rounded-t bg-gray-900 text-white">
|
<div class="p-3 rounded-t bg-gray-900 text-white">
|
||||||
<span>
|
<span>
|
||||||
<span class="w-2/12 bg-gray-700 rounded-l px-3 py-1 text-center font-semibold">Shell</span>
|
<span
|
||||||
|
class="w-2/12 bg-gray-700 rounded-l px-3 py-1 text-center font-semibold"
|
||||||
|
>Shell</span
|
||||||
|
>
|
||||||
<span
|
<span
|
||||||
class="w-2/12 bg-gray-600 rounded-r px-3 py-1 text-center font-semibold mr-2"
|
class="w-2/12 bg-gray-600 rounded-r px-3 py-1 text-center font-semibold mr-2"
|
||||||
>{{ step.shell}}</span>
|
>{{ step.shell }}</span
|
||||||
|
>
|
||||||
</span>
|
</span>
|
||||||
<span v-if="step.exit_status != undefined">
|
<span v-if="step.exit_status != undefined">
|
||||||
<span
|
<span
|
||||||
class="w-2/12 bg-gray-700 rounded-l px-3 py-1 text-center font-semibold"
|
class="w-2/12 bg-gray-700 rounded-l px-3 py-1 text-center font-semibold"
|
||||||
>Exit Status</span>
|
>Exit Status</span
|
||||||
|
>
|
||||||
<span
|
<span
|
||||||
class="w-2/12 bg-gray-600 rounded-r px-3 py-1 text-center font-semibold mr-2"
|
class="w-2/12 bg-gray-600 rounded-r px-3 py-1 text-center font-semibold mr-2"
|
||||||
>{{ step.exit_status}}</span>
|
>{{ step.exit_status }}</span
|
||||||
|
>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -40,22 +46,27 @@
|
||||||
>
|
>
|
||||||
<i
|
<i
|
||||||
class="inline-block mr-1 mdi mdi-arrow-right"
|
class="inline-block mr-1 mdi mdi-arrow-right"
|
||||||
:class="{ 'arrow-down': commandActive, 'arrow-right': !commandActive }"
|
:class="{
|
||||||
|
'arrow-down': commandActive,
|
||||||
|
'arrow-right': !commandActive,
|
||||||
|
}"
|
||||||
></i>
|
></i>
|
||||||
<span>Command</span>
|
<span>Command</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-show="commandActive"
|
v-show="commandActive"
|
||||||
class="p-3 bg-gray-900 text-white overflow-x-auto"
|
class="p-3 bg-gray-900 text-white overflow-x-auto"
|
||||||
:class="{ 'rounded': step.type != 'run' }"
|
:class="{ rounded: step.type != 'run' }"
|
||||||
>
|
>
|
||||||
<pre class="font-mono text-xs">{{ step.command }}</pre>
|
<pre class="font-mono text-xs">{{ step.command }}</pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="step.type == 'run'" class="px-3 py-2 bg-gray-700 text-white">Log</div>
|
<div v-if="step.type == 'run'" class="px-3 py-2 bg-gray-700 text-white">
|
||||||
|
Log
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
class="p-3 rounded-b bg-gray-900 text-white"
|
class="p-3 rounded-b bg-gray-900 text-white"
|
||||||
:class="{ 'rounded': step.type != 'run' }"
|
:class="{ rounded: step.type != 'run' }"
|
||||||
>
|
>
|
||||||
<Log
|
<Log
|
||||||
v-bind:runid="runid"
|
v-bind:runid="runid"
|
||||||
|
@ -72,22 +83,22 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as moment from "moment";
|
import * as moment from 'moment';
|
||||||
import momentDurationFormatSetup from "moment-duration-format";
|
import momentDurationFormatSetup from 'moment-duration-format';
|
||||||
import Log from "@/components/log.vue";
|
import Log from '@/components/log.vue';
|
||||||
|
|
||||||
momentDurationFormatSetup(moment);
|
momentDurationFormatSetup(moment);
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "step",
|
name: 'step',
|
||||||
components: {
|
components: {
|
||||||
Log
|
Log,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
active: false,
|
active: false,
|
||||||
commandActive: true,
|
commandActive: true,
|
||||||
now: moment()
|
now: moment(),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
@ -95,11 +106,11 @@ export default {
|
||||||
taskid: String,
|
taskid: String,
|
||||||
setup: Boolean,
|
setup: Boolean,
|
||||||
stepnum: Number,
|
stepnum: Number,
|
||||||
step: Object
|
step: Object,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
duration() {
|
duration() {
|
||||||
let formatString = "h:mm:ss[s]";
|
let formatString = 'h:mm:ss[s]';
|
||||||
let start = moment(this.step.start_time);
|
let start = moment(this.step.start_time);
|
||||||
let end = moment(this.step.end_time);
|
let end = moment(this.step.end_time);
|
||||||
|
|
||||||
|
@ -112,12 +123,12 @@ export default {
|
||||||
return moment.duration(end.diff(start)).format(formatString);
|
return moment.duration(end.diff(start)).format(formatString);
|
||||||
},
|
},
|
||||||
stepClass() {
|
stepClass() {
|
||||||
if (this.step.phase == "success") return "success";
|
if (this.step.phase == 'success') return 'success';
|
||||||
if (this.step.phase == "failed") return "failed";
|
if (this.step.phase == 'failed') return 'failed';
|
||||||
if (this.step.phase == "stopped") return "failed";
|
if (this.step.phase == 'stopped') return 'failed';
|
||||||
if (this.step.phase == "running") return "running";
|
if (this.step.phase == 'running') return 'running';
|
||||||
return "unknown";
|
return 'unknown';
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
toggle() {
|
toggle() {
|
||||||
|
@ -125,13 +136,13 @@ export default {
|
||||||
},
|
},
|
||||||
toggleCommand() {
|
toggleCommand() {
|
||||||
this.commandActive = !this.commandActive;
|
this.commandActive = !this.commandActive;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
window.setInterval(() => {
|
window.setInterval(() => {
|
||||||
this.now = moment();
|
this.now = moment();
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="arrow">
|
<div class="arrow">
|
||||||
<svg viewBox="0 0 15 15">
|
<svg viewBox="0 0 15 15">
|
||||||
<path fill="none" stroke="#9d9d9d" d="M4.32.5l6.247 6.942L4.32 14.5"></path>
|
<path
|
||||||
|
fill="none"
|
||||||
|
stroke="#9d9d9d"
|
||||||
|
d="M4.32.5l6.247 6.942L4.32 14.5"
|
||||||
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "tabarrow"
|
name: 'tabarrow',
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="task in sortedTasks" v-bind:key="task.id">
|
<li v-for="task in sortedTasks" v-bind:key="task.id">
|
||||||
<div class="mb-2 border-l-5 rounded-l" :class="taskClass(task)">
|
<div class="mb-2 border-l-5 rounded-l" :class="taskClass(task)">
|
||||||
<div class="px-4 py-4 flex justify-between items-center border border-l-0 rounded-r">
|
<div
|
||||||
|
class="px-4 py-4 flex justify-between items-center border border-l-0 rounded-r"
|
||||||
|
>
|
||||||
<router-link class="w-1/3 font-bold" tag="a" :to="task.link">
|
<router-link class="w-1/3 font-bold" tag="a" :to="task.link">
|
||||||
<span class="w-1/3 font-bold">{{ task.name }}</span>
|
<span class="w-1/3 font-bold">{{ task.name }}</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
@ -10,16 +12,21 @@
|
||||||
<span
|
<span
|
||||||
v-if="task.waiting_approval"
|
v-if="task.waiting_approval"
|
||||||
class="w-2/12 bg-gray-200 rounded-full px-3 py-1 text-sm text-center font-semibold mr-2"
|
class="w-2/12 bg-gray-200 rounded-full px-3 py-1 text-sm text-center font-semibold mr-2"
|
||||||
>Waiting Approval</span>
|
>Waiting Approval</span
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-1/4">
|
<div class="w-1/4">
|
||||||
<span class="block text-xs" v-if="task.parents.length > 0">depends on: </span>
|
<span class="block text-xs" v-if="task.parents.length > 0"
|
||||||
|
>depends on: </span
|
||||||
|
>
|
||||||
<ul>
|
<ul>
|
||||||
<li
|
<li
|
||||||
class="font-thin text-xs text-gray-600"
|
class="font-thin text-xs text-gray-600"
|
||||||
v-for="dep in task.parents"
|
v-for="dep in task.parents"
|
||||||
v-bind:key="dep"
|
v-bind:key="dep"
|
||||||
>{{dep}}</li>
|
>
|
||||||
|
{{ dep }}
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<span class="w-16 text-right">{{ task.duration }}</span>
|
<span class="w-16 text-right">{{ task.duration }}</span>
|
||||||
|
@ -30,21 +37,21 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as moment from "moment";
|
import * as moment from 'moment';
|
||||||
import momentDurationFormatSetup from "moment-duration-format";
|
import momentDurationFormatSetup from 'moment-duration-format';
|
||||||
|
|
||||||
momentDurationFormatSetup(moment);
|
momentDurationFormatSetup(moment);
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "tasks",
|
name: 'tasks',
|
||||||
components: {},
|
components: {},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
now: moment()
|
now: moment(),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
tasks: Object
|
tasks: Object,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
sortedTasks() {
|
sortedTasks() {
|
||||||
|
@ -59,18 +66,18 @@ export default {
|
||||||
? -1
|
? -1
|
||||||
: 0
|
: 0
|
||||||
)
|
)
|
||||||
.map(k => tasks[k]);
|
.map((k) => tasks[k]);
|
||||||
|
|
||||||
for (let task of sortedTasks) {
|
for (let task of sortedTasks) {
|
||||||
task.duration = this.duration(task);
|
task.duration = this.duration(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sortedTasks;
|
return sortedTasks;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
duration(task) {
|
duration(task) {
|
||||||
let formatString = "h:mm:ss[s]";
|
let formatString = 'h:mm:ss[s]';
|
||||||
let start = moment(task.start_time);
|
let start = moment(task.start_time);
|
||||||
let end = moment(task.end_time);
|
let end = moment(task.end_time);
|
||||||
|
|
||||||
|
@ -83,18 +90,18 @@ export default {
|
||||||
return moment.duration(end.diff(start)).format(formatString);
|
return moment.duration(end.diff(start)).format(formatString);
|
||||||
},
|
},
|
||||||
taskClass(task) {
|
taskClass(task) {
|
||||||
if (task.status == "success") return "success";
|
if (task.status == 'success') return 'success';
|
||||||
if (task.status == "failed") return "failed";
|
if (task.status == 'failed') return 'failed';
|
||||||
if (task.status == "stopped") return "failed";
|
if (task.status == 'stopped') return 'failed';
|
||||||
if (task.status == "running") return "running";
|
if (task.status == 'running') return 'running';
|
||||||
if (task.status == "skipped") return "skipped";
|
if (task.status == 'skipped') return 'skipped';
|
||||||
return "unknown";
|
return 'unknown';
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
window.setInterval(() => {
|
window.setInterval(() => {
|
||||||
this.now = moment();
|
this.now = moment();
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
|
@ -64,13 +64,13 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as moment from "moment";
|
import * as moment from 'moment';
|
||||||
import momentDurationFormatSetup from "moment-duration-format";
|
import momentDurationFormatSetup from 'moment-duration-format';
|
||||||
|
|
||||||
momentDurationFormatSetup(moment);
|
momentDurationFormatSetup(moment);
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "tasksgraph",
|
name: 'tasksgraph',
|
||||||
components: {},
|
components: {},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -85,11 +85,11 @@ export default {
|
||||||
taskYSpace: 20,
|
taskYSpace: 20,
|
||||||
hoverTask: null,
|
hoverTask: null,
|
||||||
|
|
||||||
height: "400px"
|
height: '400px',
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
tasks: Object
|
tasks: Object,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
segments: function () {
|
segments: function () {
|
||||||
|
@ -107,7 +107,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(sgotti) set different colors to edges based on source task status???
|
// TODO(sgotti) set different colors to edges based on source task status???
|
||||||
let stroke = "text-dark";
|
let stroke = 'text-dark';
|
||||||
segments.push({
|
segments.push({
|
||||||
edge: edge,
|
edge: edge,
|
||||||
x1: edge.edgePoints[i].x,
|
x1: edge.edgePoints[i].x,
|
||||||
|
@ -115,7 +115,7 @@ export default {
|
||||||
x2: edge.edgePoints[i + 1].x,
|
x2: edge.edgePoints[i + 1].x,
|
||||||
y2: edge.edgePoints[i + 1].y,
|
y2: edge.edgePoints[i + 1].y,
|
||||||
strokeWidth: strokeWidth,
|
strokeWidth: strokeWidth,
|
||||||
stroke: stroke
|
stroke: stroke,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,16 +130,16 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.graphTasks;
|
return this.graphTasks;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
tasks: function (tasks) {
|
tasks: function (tasks) {
|
||||||
this.update(tasks);
|
this.update(tasks);
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
duration(task) {
|
duration(task) {
|
||||||
let formatString = "h:mm:ss[s]";
|
let formatString = 'h:mm:ss[s]';
|
||||||
let start = moment(task.start_time);
|
let start = moment(task.start_time);
|
||||||
let end = moment(task.end_time);
|
let end = moment(task.end_time);
|
||||||
|
|
||||||
|
@ -152,12 +152,12 @@ export default {
|
||||||
return moment.duration(end.diff(start)).format(formatString);
|
return moment.duration(end.diff(start)).format(formatString);
|
||||||
},
|
},
|
||||||
taskClass(task) {
|
taskClass(task) {
|
||||||
if (task.status == "success") return "success";
|
if (task.status == 'success') return 'success';
|
||||||
if (task.status == "failed") return "failed";
|
if (task.status == 'failed') return 'failed';
|
||||||
if (task.status == "stopped") return "failed";
|
if (task.status == 'stopped') return 'failed';
|
||||||
if (task.status == "running") return "running";
|
if (task.status == 'running') return 'running';
|
||||||
if (task.status == "skipped") return "skipped";
|
if (task.status == 'skipped') return 'skipped';
|
||||||
return "unknown";
|
return 'unknown';
|
||||||
},
|
},
|
||||||
update(tasks) {
|
update(tasks) {
|
||||||
// sort tasks by level
|
// sort tasks by level
|
||||||
|
@ -169,7 +169,7 @@ export default {
|
||||||
? -1
|
? -1
|
||||||
: 0
|
: 0
|
||||||
)
|
)
|
||||||
.map(k => tasks[k]);
|
.map((k) => tasks[k]);
|
||||||
|
|
||||||
this.graphTasks = graphTasks;
|
this.graphTasks = graphTasks;
|
||||||
|
|
||||||
|
@ -344,7 +344,7 @@ export default {
|
||||||
sourceTask: pTask,
|
sourceTask: pTask,
|
||||||
targetTask: curTask,
|
targetTask: curTask,
|
||||||
source: { level: pTask.level, row: pTask.row },
|
source: { level: pTask.level, row: pTask.row },
|
||||||
target: { level: curTask.level, row: curTask.row }
|
target: { level: curTask.level, row: curTask.row },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -362,30 +362,30 @@ export default {
|
||||||
|
|
||||||
edge.edgePoints.push({
|
edge.edgePoints.push({
|
||||||
x: (taskWidth + taskXSpace) * edge.source.level + taskWidth,
|
x: (taskWidth + taskXSpace) * edge.source.level + taskWidth,
|
||||||
y: (taskHeight + taskYSpace) * edge.source.row + taskHeight / 2
|
y: (taskHeight + taskYSpace) * edge.source.row + taskHeight / 2,
|
||||||
});
|
});
|
||||||
edge.edgePoints.push({
|
edge.edgePoints.push({
|
||||||
x: (taskWidth + taskXSpace) * edge.target.level - taskXSpace / 2,
|
x: (taskWidth + taskXSpace) * edge.target.level - taskXSpace / 2,
|
||||||
y: (taskHeight + taskYSpace) * edge.source.row + taskHeight / 2
|
y: (taskHeight + taskYSpace) * edge.source.row + taskHeight / 2,
|
||||||
});
|
});
|
||||||
edge.edgePoints.push({
|
edge.edgePoints.push({
|
||||||
x: (taskWidth + taskXSpace) * edge.target.level - taskXSpace / 2,
|
x: (taskWidth + taskXSpace) * edge.target.level - taskXSpace / 2,
|
||||||
y: (taskHeight + taskYSpace) * edge.target.row + taskHeight / 2
|
y: (taskHeight + taskYSpace) * edge.target.row + taskHeight / 2,
|
||||||
});
|
});
|
||||||
edge.edgePoints.push({
|
edge.edgePoints.push({
|
||||||
x: (taskWidth + taskXSpace) * edge.target.level,
|
x: (taskWidth + taskXSpace) * edge.target.level,
|
||||||
y: (taskHeight + taskYSpace) * edge.target.row + taskHeight / 2
|
y: (taskHeight + taskYSpace) * edge.target.row + taskHeight / 2,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let width = (maxlevel + 1) * (this.taskWidth + this.taskXSpace);
|
let width = (maxlevel + 1) * (this.taskWidth + this.taskXSpace);
|
||||||
this.width = width + "px";
|
this.width = width + 'px';
|
||||||
|
|
||||||
let height =
|
let height =
|
||||||
(levelsMaxRow(graphTasks, -1) + 1) *
|
(levelsMaxRow(graphTasks, -1) + 1) *
|
||||||
(this.taskHeight + this.taskYSpace);
|
(this.taskHeight + this.taskYSpace);
|
||||||
this.height = height + "px";
|
this.height = height + 'px';
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.update(this.tasks);
|
this.update(this.tasks);
|
||||||
|
@ -393,6 +393,6 @@ export default {
|
||||||
window.setInterval(() => {
|
window.setInterval(() => {
|
||||||
this.now = moment();
|
this.now = moment();
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -8,7 +8,12 @@
|
||||||
<div>Error fetching Run: {{ fetchRunError }}</div>
|
<div>Error fetching Run: {{ fetchRunError }}</div>
|
||||||
<div>Error fetching Task: {{ fetchTaskError }}</div>
|
<div>Error fetching Task: {{ fetchTaskError }}</div>
|
||||||
</div>
|
</div>
|
||||||
<rundetail :run="run" :ownertype="ownertype" :ownername="ownername" :projectref="projectref" />
|
<rundetail
|
||||||
|
:run="run"
|
||||||
|
:ownertype="ownertype"
|
||||||
|
:ownername="ownername"
|
||||||
|
:projectref="projectref"
|
||||||
|
/>
|
||||||
<div v-if="task != null">
|
<div v-if="task != null">
|
||||||
<div class="mt-8 mb-4 flex justify-between items-center">
|
<div class="mt-8 mb-4 flex justify-between items-center">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
|
@ -17,13 +22,16 @@
|
||||||
<span
|
<span
|
||||||
class="mr-3 rounded px-2 py-1 text-xs"
|
class="mr-3 rounded px-2 py-1 text-xs"
|
||||||
:class="taskClass(task)"
|
:class="taskClass(task)"
|
||||||
>{{ task.status | capitalize }}</span>
|
>{{ task.status | capitalize }}</span
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
v-if="task.waiting_approval"
|
v-if="task.waiting_approval"
|
||||||
class="btn btn-blue"
|
class="btn btn-blue"
|
||||||
@click="approveTask(run.id, task.id)"
|
@click="approveTask(run.id, task.id)"
|
||||||
>Approve</button>
|
>
|
||||||
|
Approve
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<step
|
<step
|
||||||
v-bind:runid="runid"
|
v-bind:runid="runid"
|
||||||
|
@ -44,23 +52,23 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { fetchRun, fetchTask, approveTask } from "@/util/data.js";
|
import { fetchRun, fetchTask, approveTask } from '@/util/data.js';
|
||||||
|
|
||||||
import step from "@/components/step.vue";
|
import step from '@/components/step.vue';
|
||||||
import rundetail from "@/components/rundetail.vue";
|
import rundetail from '@/components/rundetail.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
step,
|
step,
|
||||||
rundetail
|
rundetail,
|
||||||
},
|
},
|
||||||
name: "tasksummary",
|
name: 'tasksummary',
|
||||||
props: {
|
props: {
|
||||||
ownertype: String,
|
ownertype: String,
|
||||||
ownername: String,
|
ownername: String,
|
||||||
projectref: Array,
|
projectref: Array,
|
||||||
runid: String,
|
runid: String,
|
||||||
taskid: String
|
taskid: String,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -70,7 +78,7 @@ export default {
|
||||||
fetchTaskError: null,
|
fetchTaskError: null,
|
||||||
|
|
||||||
run: null,
|
run: null,
|
||||||
task: null
|
task: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -85,16 +93,16 @@ export default {
|
||||||
|
|
||||||
this.fetchRun();
|
this.fetchRun();
|
||||||
this.fetchTask();
|
this.fetchTask();
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
taskClass(task) {
|
taskClass(task) {
|
||||||
if (task.status == "success") return "is-success";
|
if (task.status == 'success') return 'is-success';
|
||||||
if (task.status == "failed") return "is-failed";
|
if (task.status == 'failed') return 'is-failed';
|
||||||
if (task.status == "stopped") return "is-failed";
|
if (task.status == 'stopped') return 'is-failed';
|
||||||
if (task.status == "running") return "is-running";
|
if (task.status == 'running') return 'is-running';
|
||||||
if (task.status == "skipped") return "is-skipped";
|
if (task.status == 'skipped') return 'is-skipped';
|
||||||
return "unknown";
|
return 'unknown';
|
||||||
},
|
},
|
||||||
async fetchRun() {
|
async fetchRun() {
|
||||||
let { data, error, aborted } = await fetchRun(
|
let { data, error, aborted } = await fetchRun(
|
||||||
|
@ -143,7 +151,7 @@ export default {
|
||||||
this.fetchTask();
|
this.fetchTask();
|
||||||
}, 2000);
|
}, 2000);
|
||||||
},
|
},
|
||||||
approveTask: approveTask
|
approveTask: approveTask,
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
this.fetchAbort = new AbortController();
|
this.fetchAbort = new AbortController();
|
||||||
|
@ -157,9 +165,8 @@ export default {
|
||||||
}
|
}
|
||||||
clearTimeout(this.fetchRunSchedule);
|
clearTimeout(this.fetchRunSchedule);
|
||||||
clearTimeout(this.fetchTaskSchedule);
|
clearTimeout(this.fetchTaskSchedule);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
|
@ -7,7 +7,10 @@
|
||||||
class="mb-4 bg-red-100 border-l-4 border-red-500 text-red-700 p-4 rounded"
|
class="mb-4 bg-red-100 border-l-4 border-red-500 text-red-700 p-4 rounded"
|
||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
<p>Removing a Linked Account will also block all the projects that uses this Linked Account to access their remote repository</p>
|
<p>
|
||||||
|
Removing a Linked Account will also block all the projects that uses
|
||||||
|
this Linked Account to access their remote repository
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<ul v-if="user.linked_accounts">
|
<ul v-if="user.linked_accounts">
|
||||||
<li
|
<li
|
||||||
|
@ -17,9 +20,13 @@
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<span class="font-bold">{{ la.remote_user_name }}</span>
|
<span class="font-bold">{{ la.remote_user_name }}</span>
|
||||||
<span class="ml-1">(on remote source {{laRemoteSourceName(la)}})</span>
|
<span class="ml-1"
|
||||||
|
>(on remote source {{ laRemoteSourceName(la) }})</span
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-red" @click="deleteLinkedAccount(la)">Delete</button>
|
<button class="btn btn-red" @click="deleteLinkedAccount(la)">
|
||||||
|
Delete
|
||||||
|
</button>
|
||||||
</li>
|
</li>
|
||||||
<div
|
<div
|
||||||
v-if="deleteLinkedAccountError"
|
v-if="deleteLinkedAccountError"
|
||||||
|
@ -40,9 +47,13 @@
|
||||||
class="block appearance-none w-full bg-white border border-gray-400 hover:border-gray-500 px-4 py-2 pr-8 rounded shadow leading-tight focus:outline-none focus:shadow-outline"
|
class="block appearance-none w-full bg-white border border-gray-400 hover:border-gray-500 px-4 py-2 pr-8 rounded shadow leading-tight focus:outline-none focus:shadow-outline"
|
||||||
v-model="selectedRemoteSourceName"
|
v-model="selectedRemoteSourceName"
|
||||||
>
|
>
|
||||||
<option v-for="rs in remotesources" v-bind:key="rs.id">{{ rs.name }}</option>
|
<option v-for="rs in remotesources" v-bind:key="rs.id">
|
||||||
|
{{ rs.name }}
|
||||||
|
</option>
|
||||||
</select>
|
</select>
|
||||||
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2">
|
<div
|
||||||
|
class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2"
|
||||||
|
>
|
||||||
<svg
|
<svg
|
||||||
class="fill-current h-4 w-4"
|
class="fill-current h-4 w-4"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
@ -56,7 +67,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button class="ml-3 btn btn-blue" @click="addLinkedAccount()">Add Linked Account</button>
|
<button class="ml-3 btn btn-blue" @click="addLinkedAccount()">
|
||||||
|
Add Linked Account
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -70,7 +83,9 @@
|
||||||
v-bind:key="token"
|
v-bind:key="token"
|
||||||
>
|
>
|
||||||
<span class="font-bold">{{ token }}</span>
|
<span class="font-bold">{{ token }}</span>
|
||||||
<button class="btn btn-red" @click="deleteUserToken(token)">Delete</button>
|
<button class="btn btn-red" @click="deleteUserToken(token)">
|
||||||
|
Delete
|
||||||
|
</button>
|
||||||
</li>
|
</li>
|
||||||
<div
|
<div
|
||||||
v-if="deleteUserTokenError"
|
v-if="deleteUserTokenError"
|
||||||
|
@ -102,7 +117,9 @@
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p class="font-bold">User token created. Copy it now since it won't be showed again</p>
|
<p class="font-bold">
|
||||||
|
User token created. Copy it now since it won't be showed again
|
||||||
|
</p>
|
||||||
<p class="text-sm">{{ token }}</p>
|
<p class="text-sm">{{ token }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -130,8 +147,10 @@
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Token name"
|
placeholder="Token name"
|
||||||
v-model="newtokenname"
|
v-model="newtokenname"
|
||||||
>
|
/>
|
||||||
<button class="ml-3 btn btn-blue" @click="createUserToken()">Create Token</button>
|
<button class="ml-3 btn btn-blue" @click="createUserToken()">
|
||||||
|
Create Token
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="createUserTokenError"
|
v-if="createUserTokenError"
|
||||||
|
@ -151,14 +170,14 @@ import {
|
||||||
fetchRemoteSources,
|
fetchRemoteSources,
|
||||||
createUserToken,
|
createUserToken,
|
||||||
deleteUserToken,
|
deleteUserToken,
|
||||||
deleteLinkedAccount
|
deleteLinkedAccount,
|
||||||
} from "@/util/data.js";
|
} from '@/util/data.js';
|
||||||
|
|
||||||
import { userAddLinkedAccountLink } from "@/util/link.js";
|
import { userAddLinkedAccountLink } from '@/util/link.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: {},
|
||||||
name: "usersettings",
|
name: 'usersettings',
|
||||||
props: {},
|
props: {},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -169,7 +188,7 @@ export default {
|
||||||
remotesources: [],
|
remotesources: [],
|
||||||
token: null,
|
token: null,
|
||||||
newtokenname: null,
|
newtokenname: null,
|
||||||
selectedRemoteSourceName: null
|
selectedRemoteSourceName: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -181,7 +200,7 @@ export default {
|
||||||
async fetchCurrentUser() {
|
async fetchCurrentUser() {
|
||||||
let { data, error } = await fetchCurrentUser();
|
let { data, error } = await fetchCurrentUser();
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.user = data;
|
this.user = data;
|
||||||
|
@ -189,7 +208,7 @@ export default {
|
||||||
async fetchRemoteSources() {
|
async fetchRemoteSources() {
|
||||||
let { data, error } = await fetchRemoteSources();
|
let { data, error } = await fetchRemoteSources();
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.remotesources = data;
|
this.remotesources = data;
|
||||||
|
@ -249,15 +268,13 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.fetchCurrentUser();
|
this.fetchCurrentUser();
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
this.fetchCurrentUser();
|
this.fetchCurrentUser();
|
||||||
this.fetchRemoteSources();
|
this.fetchRemoteSources();
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
|
@ -19,16 +19,17 @@
|
||||||
<div class="flex" v-for="variable in variables" v-bind:key="variable.id">
|
<div class="flex" v-for="variable in variables" v-bind:key="variable.id">
|
||||||
<div class="w-2/12">
|
<div class="w-2/12">
|
||||||
<span class="name">{{ variable.name }}</span>
|
<span class="name">{{ variable.name }}</span>
|
||||||
<div v-if="showparentpath" class="text-sm font-light">from {{variable.parent_path}}</div>
|
<div v-if="showparentpath" class="text-sm font-light">
|
||||||
|
from {{ variable.parent_path }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-10/12">
|
<div class="w-10/12">
|
||||||
<div class="flex" v-for="val in variable.values" v-bind:key="val.id">
|
<div class="flex" v-for="val in variable.values" v-bind:key="val.id">
|
||||||
<div class="w-2/12">
|
<div class="w-2/12">
|
||||||
<span>{{ val.secret_name }}</span>
|
<span>{{ val.secret_name }}</span>
|
||||||
<div
|
<div v-if="val.matching_secret_parent_path" class="text-sm">
|
||||||
v-if="val.matching_secret_parent_path"
|
using secret from {{ val.matching_secret_parent_path }}
|
||||||
class="text-sm"
|
</div>
|
||||||
>using secret from {{val.matching_secret_parent_path}}</div>
|
|
||||||
<div v-else class="text-sm text-red-600">no matching secret</div>
|
<div v-else class="text-sm text-red-600">no matching secret</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-2/12">
|
<div class="w-2/12">
|
||||||
|
@ -43,12 +44,18 @@
|
||||||
<span>{{ type }}</span>
|
<span>{{ type }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-1/3">
|
<div class="w-1/3">
|
||||||
<div v-for="include in val.when[type].include" v-bind:key="include.match">
|
<div
|
||||||
|
v-for="include in val.when[type].include"
|
||||||
|
v-bind:key="include.match"
|
||||||
|
>
|
||||||
<div>{{ include.match }}</div>
|
<div>{{ include.match }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-1/3">
|
<div class="w-1/3">
|
||||||
<div v-for="exclude in val.when[type].exclude" v-bind:key="exclude.match">
|
<div
|
||||||
|
v-for="exclude in val.when[type].exclude"
|
||||||
|
v-bind:key="exclude.match"
|
||||||
|
>
|
||||||
<div>{{ exclude.match }}</div>
|
<div>{{ exclude.match }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -66,15 +73,12 @@
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: {},
|
||||||
name: "vars",
|
name: 'vars',
|
||||||
props: {
|
props: {
|
||||||
variables: Array,
|
variables: Array,
|
||||||
showparentpath: Boolean
|
showparentpath: Boolean,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
@tailwind base;
|
@tailwind base;
|
||||||
@tailwind components;
|
@tailwind components;
|
||||||
|
|
||||||
@import "@/css/_ansi.scss";
|
@import '@/css/_ansi.scss';
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
@apply font-bold py-2 px-4 rounded;
|
@apply font-bold py-2 px-4 rounded;
|
||||||
|
@ -119,7 +119,7 @@
|
||||||
border-radius: 290486px;
|
border-radius: 290486px;
|
||||||
border-right-color: transparent;
|
border-right-color: transparent;
|
||||||
border-top-color: transparent;
|
border-top-color: transparent;
|
||||||
content: "";
|
content: '';
|
||||||
display: block;
|
display: block;
|
||||||
width: 1em;
|
width: 1em;
|
||||||
height: 1em;
|
height: 1em;
|
||||||
|
|
24
src/main.js
24
src/main.js
|
@ -1,11 +1,11 @@
|
||||||
import "@/css/tailwind.scss";
|
import '@/css/tailwind.scss';
|
||||||
import { getUser } from "@/util/auth";
|
import { getUser } from '@/util/auth';
|
||||||
import "@mdi/font/css/materialdesignicons.css";
|
import '@mdi/font/css/materialdesignicons.css';
|
||||||
import Vue from "vue";
|
import Vue from 'vue';
|
||||||
import Vue2Filters from "vue2-filters";
|
import Vue2Filters from 'vue2-filters';
|
||||||
import App from "./App.vue";
|
import App from './App.vue';
|
||||||
import router from "./router";
|
import router from './router';
|
||||||
import store from "./store";
|
import store from './store';
|
||||||
|
|
||||||
Vue.use(Vue2Filters);
|
Vue.use(Vue2Filters);
|
||||||
|
|
||||||
|
@ -16,9 +16,9 @@ new Vue({
|
||||||
created: function () {
|
created: function () {
|
||||||
let user = getUser();
|
let user = getUser();
|
||||||
if (user) {
|
if (user) {
|
||||||
store.dispatch("setUser", user);
|
store.dispatch('setUser', user);
|
||||||
}
|
}
|
||||||
store.dispatch("setRegisterUser", null);
|
store.dispatch('setRegisterUser', null);
|
||||||
},
|
},
|
||||||
render: h => h(App)
|
render: (h) => h(App),
|
||||||
}).$mount("#app");
|
}).$mount('#app');
|
||||||
|
|
557
src/router.js
557
src/router.js
|
@ -1,249 +1,348 @@
|
||||||
import Vue from "vue";
|
import Vue from 'vue';
|
||||||
import VueRouter from "vue-router";
|
import VueRouter from 'vue-router';
|
||||||
import Home from "./views/Home.vue";
|
import Home from './views/Home.vue';
|
||||||
import User from "./views/User.vue";
|
import User from './views/User.vue';
|
||||||
import Org from "./views/Org.vue";
|
import Org from './views/Org.vue';
|
||||||
import Project from "./views/Project.vue";
|
import Project from './views/Project.vue';
|
||||||
import ProjectGroup from "./views/ProjectGroup.vue";
|
import ProjectGroup from './views/ProjectGroup.vue';
|
||||||
import AddLinkedAccount from "./views/AddLinkedAccount.vue";
|
import AddLinkedAccount from './views/AddLinkedAccount.vue';
|
||||||
import usersettings from "./components/usersettings.vue";
|
import usersettings from './components/usersettings.vue';
|
||||||
import projects from "./components/projects.vue";
|
import projects from './components/projects.vue';
|
||||||
import projectsettings from "./components/projectsettings.vue";
|
import projectsettings from './components/projectsettings.vue';
|
||||||
import projectgroupsettings from "./components/projectgroupsettings.vue";
|
import projectgroupsettings from './components/projectgroupsettings.vue';
|
||||||
import createproject from "./components/createproject.vue";
|
import createproject from './components/createproject.vue';
|
||||||
import createprojectgroup from "./components/createprojectgroup.vue";
|
import createprojectgroup from './components/createprojectgroup.vue';
|
||||||
import createorganization from "./components/createorganization.vue";
|
import createorganization from './components/createorganization.vue';
|
||||||
import orgmembers from "./components/orgmembers.vue";
|
import orgmembers from './components/orgmembers.vue';
|
||||||
import runs from "./components/runs.vue";
|
import runs from './components/runs.vue';
|
||||||
import runsummary from "./components/runsummary.vue";
|
import runsummary from './components/runsummary.vue';
|
||||||
import tasksummary from "./components/tasksummary.vue";
|
import tasksummary from './components/tasksummary.vue';
|
||||||
import Oauth2 from "./views/Oauth2.vue";
|
import Oauth2 from './views/Oauth2.vue';
|
||||||
import Register from "./views/Register.vue";
|
import Register from './views/Register.vue';
|
||||||
import Login from "./views/Login.vue";
|
import Login from './views/Login.vue';
|
||||||
import Logout from "./views/Logout.vue";
|
import Logout from './views/Logout.vue';
|
||||||
import CreateSource from "./views/CreateSource.vue";
|
import CreateSource from './views/CreateSource.vue';
|
||||||
|
|
||||||
import { parseRef, projectRunLink } from "@/util/link.js";
|
import { parseRef, projectRunLink } from '@/util/link.js';
|
||||||
import { fetchProject } from "@/util/data.js";
|
import { fetchProject } from '@/util/data.js';
|
||||||
|
|
||||||
import store from "./store";
|
import store from './store';
|
||||||
|
|
||||||
Vue.use(VueRouter);
|
Vue.use(VueRouter);
|
||||||
|
|
||||||
const router = new VueRouter({
|
const router = new VueRouter({
|
||||||
mode: "history",
|
mode: 'history',
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
path: "/register",
|
path: '/register',
|
||||||
name: "register",
|
name: 'register',
|
||||||
component: Register,
|
component: Register,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/newsource",
|
path: '/newsource',
|
||||||
name: "newsource",
|
name: 'newsource',
|
||||||
component: CreateSource,
|
component: CreateSource,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/login",
|
path: '/login',
|
||||||
name: "login",
|
name: 'login',
|
||||||
component: Login
|
component: Login,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/logout",
|
path: '/logout',
|
||||||
name: "logout",
|
name: 'logout',
|
||||||
component: Logout
|
component: Logout,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/oauth2/callback",
|
path: '/oauth2/callback',
|
||||||
name: "oauth2callback",
|
name: 'oauth2callback',
|
||||||
component: Oauth2
|
component: Oauth2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/",
|
path: '/',
|
||||||
name: "home",
|
name: 'home',
|
||||||
component: Home
|
component: Home,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/neworganization",
|
path: '/neworganization',
|
||||||
component: createorganization,
|
component: createorganization,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/user/:username",
|
path: '/user/:username',
|
||||||
component: User,
|
component: User,
|
||||||
props: (route) => ({ username: route.params.username }),
|
props: (route) => ({ username: route.params.username }),
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: "",
|
path: '',
|
||||||
name: "user",
|
name: 'user',
|
||||||
component: projects,
|
component: projects,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "projects",
|
path: 'projects',
|
||||||
name: "user projects",
|
name: 'user projects',
|
||||||
component: projects,
|
component: projects,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "runs",
|
path: 'runs',
|
||||||
name: "user direct runs",
|
name: 'user direct runs',
|
||||||
component: runs,
|
component: runs,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "runs/:runid",
|
path: 'runs/:runid',
|
||||||
name: "user direct run",
|
name: 'user direct run',
|
||||||
component: runsummary,
|
component: runsummary,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, runid: route.params.runid })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
runid: route.params.runid,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "runs/:runid/tasks/:taskid",
|
path: 'runs/:runid/tasks/:taskid',
|
||||||
name: "user direct run task",
|
name: 'user direct run task',
|
||||||
component: tasksummary,
|
component: tasksummary,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, runid: route.params.runid, taskid: route.params.taskid })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
runid: route.params.runid,
|
||||||
|
taskid: route.params.taskid,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "settings",
|
path: 'settings',
|
||||||
name: "user settings",
|
name: 'user settings',
|
||||||
component: usersettings,
|
component: usersettings,
|
||||||
props: (route) => ({ username: route.params.username }),
|
props: (route) => ({ username: route.params.username }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "linkedaccounts/add/:remotesource",
|
path: 'linkedaccounts/add/:remotesource',
|
||||||
name: "user add linked account",
|
name: 'user add linked account',
|
||||||
component: AddLinkedAccount,
|
component: AddLinkedAccount,
|
||||||
props: (route) => ({ username: route.params.username, remoteSourceName: route.params.remotesource })
|
props: (route) => ({
|
||||||
|
username: route.params.username,
|
||||||
|
remoteSourceName: route.params.remotesource,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "createprojectgroup",
|
path: 'createprojectgroup',
|
||||||
name: "user create project group",
|
name: 'user create project group',
|
||||||
component: createprojectgroup,
|
component: createprojectgroup,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "createproject",
|
path: 'createproject',
|
||||||
name: "user create project",
|
name: 'user create project',
|
||||||
component: createproject,
|
component: createproject,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/user/:username/projects/:projectref(.*\\.proj)",
|
path: '/user/:username/projects/:projectref(.*\\.proj)',
|
||||||
component: Project,
|
component: Project,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectref: parseRef(route.params.projectref) }),
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
}),
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: "",
|
path: '',
|
||||||
name: "user project",
|
name: 'user project',
|
||||||
component: runs,
|
component: runs,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectref: parseRef(route.params.projectref) })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "runs",
|
path: 'runs',
|
||||||
name: "user project runs",
|
name: 'user project runs',
|
||||||
component: runs,
|
component: runs,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectref: parseRef(route.params.projectref) })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "branches",
|
path: 'branches',
|
||||||
name: "user project branches runs",
|
name: 'user project branches runs',
|
||||||
component: runs,
|
component: runs,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectref: parseRef(route.params.projectref), query: "branches" })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
query: 'branches',
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "tags",
|
path: 'tags',
|
||||||
name: "user project tags runs",
|
name: 'user project tags runs',
|
||||||
component: runs,
|
component: runs,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectref: parseRef(route.params.projectref), query: "tags" })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
query: 'tags',
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "pullrequests",
|
path: 'pullrequests',
|
||||||
name: "user project pull requests runs",
|
name: 'user project pull requests runs',
|
||||||
component: runs,
|
component: runs,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectref: parseRef(route.params.projectref), query: "pullrequests" })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
query: 'pullrequests',
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "runs/:runid",
|
path: 'runs/:runid',
|
||||||
name: "user project run",
|
name: 'user project run',
|
||||||
component: runsummary,
|
component: runsummary,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectref: parseRef(route.params.projectref), runid: route.params.runid })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
runid: route.params.runid,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "runs/:runid/tasks/:taskid",
|
path: 'runs/:runid/tasks/:taskid',
|
||||||
name: "user project run task",
|
name: 'user project run task',
|
||||||
component: tasksummary,
|
component: tasksummary,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectref: parseRef(route.params.projectref), runid: route.params.runid, taskid: route.params.taskid })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
runid: route.params.runid,
|
||||||
|
taskid: route.params.taskid,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "settings",
|
path: 'settings',
|
||||||
name: "user project settings",
|
name: 'user project settings',
|
||||||
component: projectsettings,
|
component: projectsettings,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectref: parseRef(route.params.projectref) })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
path: "/user/:username/projectgroups/:projectgroupref(.*\\.proj)",
|
path: '/user/:username/projectgroups/:projectgroupref(.*\\.proj)',
|
||||||
component: ProjectGroup,
|
component: ProjectGroup,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectgroupref: parseRef(route.params.projectgroupref) }),
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectgroupref: parseRef(route.params.projectgroupref),
|
||||||
|
}),
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: "",
|
path: '',
|
||||||
name: "user project group",
|
name: 'user project group',
|
||||||
component: projects,
|
component: projects,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectgroupref: parseRef(route.params.projectgroupref) }),
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectgroupref: parseRef(route.params.projectgroupref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "projects",
|
path: 'projects',
|
||||||
name: "user project group projects",
|
name: 'user project group projects',
|
||||||
component: projects,
|
component: projects,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectgroupref: parseRef(route.params.projectgroupref) })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectgroupref: parseRef(route.params.projectgroupref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "settings",
|
path: 'settings',
|
||||||
name: "user project group settings",
|
name: 'user project group settings',
|
||||||
component: projectgroupsettings,
|
component: projectgroupsettings,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectgroupref: parseRef(route.params.projectgroupref) })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectgroupref: parseRef(route.params.projectgroupref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "createprojectgroup",
|
path: 'createprojectgroup',
|
||||||
name: "user project group create project group",
|
name: 'user project group create project group',
|
||||||
component: createprojectgroup,
|
component: createprojectgroup,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectgroupref: parseRef(route.params.projectgroupref) })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectgroupref: parseRef(route.params.projectgroupref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "createproject",
|
path: 'createproject',
|
||||||
name: "user project group create project",
|
name: 'user project group create project',
|
||||||
component: createproject,
|
component: createproject,
|
||||||
props: (route) => ({ ownertype: "user", ownername: route.params.username, projectgroupref: parseRef(route.params.projectgroupref) })
|
props: (route) => ({
|
||||||
|
ownertype: 'user',
|
||||||
|
ownername: route.params.username,
|
||||||
|
projectgroupref: parseRef(route.params.projectgroupref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
path: "/org/:orgname",
|
path: '/org/:orgname',
|
||||||
component: Org,
|
component: Org,
|
||||||
props: (route) => ({ orgname: route.params.orgname }),
|
props: (route) => ({ orgname: route.params.orgname }),
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: "",
|
path: '',
|
||||||
name: "org",
|
name: 'org',
|
||||||
component: projects,
|
component: projects,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "projects",
|
path: 'projects',
|
||||||
name: "org projects",
|
name: 'org projects',
|
||||||
component: projects,
|
component: projects,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "members",
|
path: 'members',
|
||||||
name: "org members",
|
name: 'org members',
|
||||||
component: orgmembers,
|
component: orgmembers,
|
||||||
props: (route) => ({ orgname: route.params.orgname })
|
props: (route) => ({ orgname: route.params.orgname }),
|
||||||
},
|
},
|
||||||
/* {
|
/* {
|
||||||
path: "settings",
|
path: "settings",
|
||||||
|
@ -252,141 +351,213 @@ const router = new VueRouter({
|
||||||
props: (route) => ({ username: route.params.username }),
|
props: (route) => ({ username: route.params.username }),
|
||||||
}, */
|
}, */
|
||||||
{
|
{
|
||||||
path: "createprojectgroup",
|
path: 'createprojectgroup',
|
||||||
name: "org create project group",
|
name: 'org create project group',
|
||||||
component: createprojectgroup,
|
component: createprojectgroup,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "createproject",
|
path: 'createproject',
|
||||||
name: "org create project",
|
name: 'org create project',
|
||||||
component: createproject,
|
component: createproject,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
path: "/org/:orgname/projects/:projectref(.*\\.proj)",
|
path: '/org/:orgname/projects/:projectref(.*\\.proj)',
|
||||||
component: Project,
|
component: Project,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectref: parseRef(route.params.projectref) }),
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
}),
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: "",
|
path: '',
|
||||||
name: "org project",
|
name: 'org project',
|
||||||
component: runs,
|
component: runs,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectref: parseRef(route.params.projectref) })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "runs",
|
path: 'runs',
|
||||||
name: "org project runs",
|
name: 'org project runs',
|
||||||
component: runs,
|
component: runs,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectref: parseRef(route.params.projectref) })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "branches",
|
path: 'branches',
|
||||||
name: "org project branches runs",
|
name: 'org project branches runs',
|
||||||
component: runs,
|
component: runs,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectref: parseRef(route.params.projectref), query: "branches" })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
query: 'branches',
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "tags",
|
path: 'tags',
|
||||||
name: "org project tags runs",
|
name: 'org project tags runs',
|
||||||
component: runs,
|
component: runs,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectref: parseRef(route.params.projectref), query: "tags" })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
query: 'tags',
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "pullrequests",
|
path: 'pullrequests',
|
||||||
name: "org project pull requests runs",
|
name: 'org project pull requests runs',
|
||||||
component: runs,
|
component: runs,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectref: parseRef(route.params.projectref), query: "pullrequests" })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
query: 'pullrequests',
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "runs/:runid",
|
path: 'runs/:runid',
|
||||||
name: "org project run",
|
name: 'org project run',
|
||||||
component: runsummary,
|
component: runsummary,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectref: parseRef(route.params.projectref), runid: route.params.runid })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
runid: route.params.runid,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "runs/:runid/tasks/:taskid",
|
path: 'runs/:runid/tasks/:taskid',
|
||||||
name: "org project run task",
|
name: 'org project run task',
|
||||||
component: tasksummary,
|
component: tasksummary,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectref: parseRef(route.params.projectref), runid: route.params.runid, taskid: route.params.taskid })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
runid: route.params.runid,
|
||||||
|
taskid: route.params.taskid,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "settings",
|
path: 'settings',
|
||||||
name: "org project settings",
|
name: 'org project settings',
|
||||||
component: projectsettings,
|
component: projectsettings,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectref: parseRef(route.params.projectref) })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectref: parseRef(route.params.projectref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
path: "/org/:orgname/projectgroups/:projectgroupref(.*\\.proj)",
|
path: '/org/:orgname/projectgroups/:projectgroupref(.*\\.proj)',
|
||||||
component: ProjectGroup,
|
component: ProjectGroup,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectgroupref: parseRef(route.params.projectgroupref) }),
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectgroupref: parseRef(route.params.projectgroupref),
|
||||||
|
}),
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: "",
|
path: '',
|
||||||
name: "org project group",
|
name: 'org project group',
|
||||||
component: projects,
|
component: projects,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectgroupref: parseRef(route.params.projectgroupref) }),
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectgroupref: parseRef(route.params.projectgroupref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "projects",
|
path: 'projects',
|
||||||
name: "org project group projects",
|
name: 'org project group projects',
|
||||||
component: projects,
|
component: projects,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectgroupref: parseRef(route.params.projectgroupref) })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectgroupref: parseRef(route.params.projectgroupref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "settings",
|
path: 'settings',
|
||||||
name: "org project group settings",
|
name: 'org project group settings',
|
||||||
component: projectgroupsettings,
|
component: projectgroupsettings,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectgroupref: parseRef(route.params.projectgroupref) })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectgroupref: parseRef(route.params.projectgroupref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "createprojectgroup",
|
path: 'createprojectgroup',
|
||||||
name: "org project group create project group",
|
name: 'org project group create project group',
|
||||||
component: createprojectgroup,
|
component: createprojectgroup,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectgroupref: parseRef(route.params.projectgroupref) })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectgroupref: parseRef(route.params.projectgroupref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "createproject",
|
path: 'createproject',
|
||||||
name: "org project group create project",
|
name: 'org project group create project',
|
||||||
component: createproject,
|
component: createproject,
|
||||||
props: (route) => ({ ownertype: "org", ownername: route.params.orgname, projectgroupref: parseRef(route.params.projectgroupref) })
|
props: (route) => ({
|
||||||
|
ownertype: 'org',
|
||||||
|
ownername: route.params.orgname,
|
||||||
|
projectgroupref: parseRef(route.params.projectgroupref),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
router.beforeEach(async (to, from, next) => {
|
router.beforeEach(async (to, from, next) => {
|
||||||
store.dispatch("setError", null);
|
store.dispatch('setError', null);
|
||||||
|
|
||||||
const { path, query } = to
|
const { path, query } = to;
|
||||||
|
|
||||||
if (path == "/run") {
|
if (path == '/run') {
|
||||||
// generic run handler by projectref and runid
|
// generic run handler by projectref and runid
|
||||||
let projectref = query.projectref
|
let projectref = query.projectref;
|
||||||
let runid = query.runid
|
let runid = query.runid;
|
||||||
|
|
||||||
let { data, error } = await fetchProject(projectref);
|
let { data, error } = await fetchProject(projectref);
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let project = data;
|
let project = data;
|
||||||
|
|
||||||
let parts = project.path.split("/")
|
let parts = project.path.split('/');
|
||||||
let nextPath = projectRunLink(parts[0], parts[1], parts.slice(2), runid)
|
let nextPath = projectRunLink(parts[0], parts[1], parts.slice(2), runid);
|
||||||
|
|
||||||
next({ path: nextPath.path, replace: true })
|
next({ path: nextPath.path, replace: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
next()
|
next();
|
||||||
})
|
});
|
||||||
|
|
||||||
export default router
|
export default router;
|
||||||
|
|
47
src/store.js
47
src/store.js
|
@ -1,55 +1,54 @@
|
||||||
import Vue from 'vue'
|
import Vue from 'vue';
|
||||||
import Vuex from 'vuex'
|
import Vuex from 'vuex';
|
||||||
|
|
||||||
Vue.use(Vuex)
|
Vue.use(Vuex);
|
||||||
|
|
||||||
const state = {
|
const state = {
|
||||||
error: null,
|
error: null,
|
||||||
user: null,
|
user: null,
|
||||||
registeruser: null,
|
registeruser: null,
|
||||||
}
|
};
|
||||||
|
|
||||||
const getters = {
|
const getters = {
|
||||||
// global error
|
// global error
|
||||||
error: state => {
|
error: (state) => {
|
||||||
return state.error
|
return state.error;
|
||||||
},
|
},
|
||||||
user: state => {
|
user: (state) => {
|
||||||
return state.user
|
return state.user;
|
||||||
},
|
},
|
||||||
registeruser: state => {
|
registeruser: (state) => {
|
||||||
return state.registeruser
|
return state.registeruser;
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
const mutations = {
|
const mutations = {
|
||||||
setError(state, error) {
|
setError(state, error) {
|
||||||
state.error = error
|
state.error = error;
|
||||||
},
|
},
|
||||||
setUser(state, user) {
|
setUser(state, user) {
|
||||||
state.user = user
|
state.user = user;
|
||||||
},
|
},
|
||||||
setRegisterUser(state, user) {
|
setRegisterUser(state, user) {
|
||||||
state.registeruser = user
|
state.registeruser = user;
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
const actions = {
|
const actions = {
|
||||||
setError({ commit }, error) {
|
setError({ commit }, error) {
|
||||||
commit('setError', error)
|
commit('setError', error);
|
||||||
},
|
},
|
||||||
setUser({ commit }, user) {
|
setUser({ commit }, user) {
|
||||||
commit('setUser', user)
|
commit('setUser', user);
|
||||||
},
|
},
|
||||||
setRegisterUser({ commit }, user) {
|
setRegisterUser({ commit }, user) {
|
||||||
commit('setRegisterUser', user)
|
commit('setRegisterUser', user);
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
export default new Vuex.Store({
|
export default new Vuex.Store({
|
||||||
state,
|
state,
|
||||||
getters,
|
getters,
|
||||||
actions,
|
actions,
|
||||||
mutations,
|
mutations,
|
||||||
})
|
});
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import store from "@/store";
|
import store from '@/store';
|
||||||
|
|
||||||
const ID_TOKEN_KEY = "id_token";
|
const ID_TOKEN_KEY = 'id_token';
|
||||||
const USER_KEY = "user";
|
const USER_KEY = 'user';
|
||||||
const LOGIN_REDIRECT_KEY = "login_redirect";
|
const LOGIN_REDIRECT_KEY = 'login_redirect';
|
||||||
|
|
||||||
let API_URL = window.CONFIG.API_URL;
|
let API_URL = window.CONFIG.API_URL;
|
||||||
let API_BASE_PATH = window.CONFIG.API_BASE_PATH;
|
let API_BASE_PATH = window.CONFIG.API_BASE_PATH;
|
||||||
|
@ -10,20 +10,20 @@ let API_BASE_PATH = window.CONFIG.API_BASE_PATH;
|
||||||
export function setLoggedUser(token, user) {
|
export function setLoggedUser(token, user) {
|
||||||
setIdToken(token);
|
setIdToken(token);
|
||||||
setUser(user);
|
setUser(user);
|
||||||
store.dispatch("setUser", user);
|
store.dispatch('setUser', user);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function doLogout() {
|
export function doLogout() {
|
||||||
unsetIdToken();
|
unsetIdToken();
|
||||||
unsetUser();
|
unsetUser();
|
||||||
store.dispatch("setUser", null);
|
store.dispatch('setUser', null);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function apiurlwithtoken(path) {
|
export function apiurlwithtoken(path) {
|
||||||
let u = new URL(API_URL + API_BASE_PATH + path);
|
let u = new URL(API_URL + API_BASE_PATH + path);
|
||||||
let idToken = getIdToken();
|
let idToken = getIdToken();
|
||||||
if (idToken) {
|
if (idToken) {
|
||||||
u.searchParams.append("access_token", idToken);
|
u.searchParams.append('access_token', idToken);
|
||||||
}
|
}
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
|
@ -33,19 +33,19 @@ export function apiurl(path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function loginurl() {
|
export function loginurl() {
|
||||||
return apiurl("/auth/login");
|
return apiurl('/auth/login');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function authorizeurl() {
|
export function authorizeurl() {
|
||||||
return apiurl("/auth/authorize");
|
return apiurl('/auth/authorize');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function registerurl() {
|
export function registerurl() {
|
||||||
return new apiurl("/auth/register");
|
return new apiurl('/auth/register');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function oauth2callbackurl() {
|
export function oauth2callbackurl() {
|
||||||
return new apiurl("/auth/oauth2/callback");
|
return new apiurl('/auth/oauth2/callback');
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loginapi(init) {
|
export async function loginapi(init) {
|
||||||
|
@ -64,19 +64,19 @@ export async function registerapi(init) {
|
||||||
return await window.fetch(registerurl(), init);
|
return await window.fetch(registerurl(), init);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetch(url, init, signal, token, tokenType = "bearer") {
|
export async function fetch(url, init, signal, token, tokenType = 'bearer') {
|
||||||
if (!init) {
|
if (!init) {
|
||||||
init = {};
|
init = {};
|
||||||
}
|
}
|
||||||
if (init.headers === undefined) {
|
if (init.headers === undefined) {
|
||||||
init["headers"] = {};
|
init['headers'] = {};
|
||||||
}
|
}
|
||||||
if (signal) {
|
if (signal) {
|
||||||
init["signal"] = signal;
|
init['signal'] = signal;
|
||||||
}
|
}
|
||||||
let idToken = token || getIdToken();
|
let idToken = token || getIdToken();
|
||||||
if (idToken) {
|
if (idToken) {
|
||||||
init.headers["Authorization"] = tokenType + " " + idToken;
|
init.headers['Authorization'] = tokenType + ' ' + idToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await window.fetch(url, init);
|
return await window.fetch(url, init);
|
||||||
|
|
233
src/util/data.js
233
src/util/data.js
|
@ -1,8 +1,9 @@
|
||||||
import router from "@/router";
|
import router from '@/router';
|
||||||
import { apiurl, fetch as authfetch, loginapi, registerapi } from "@/util/auth";
|
import { apiurl, fetch as authfetch, loginapi, registerapi } from '@/util/auth';
|
||||||
|
|
||||||
export const GITHUB_API_URL = "https://api.github.com";
|
export const GITHUB_API_URL = 'https://api.github.com';
|
||||||
export const GITHUB_SSH_KEY = "github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==";
|
export const GITHUB_SSH_KEY =
|
||||||
|
'github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==';
|
||||||
|
|
||||||
export async function fetch(url, init, signal, token, tokenType) {
|
export async function fetch(url, init, signal, token, tokenType) {
|
||||||
try {
|
try {
|
||||||
|
@ -10,8 +11,8 @@ export async function fetch(url, init, signal, token, tokenType) {
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
if (res.status === 401) {
|
if (res.status === 401) {
|
||||||
router.push({
|
router.push({
|
||||||
name: "login",
|
name: 'login',
|
||||||
query: { redirect: router.currentRoute.fullPath }
|
query: { redirect: router.currentRoute.fullPath },
|
||||||
});
|
});
|
||||||
// if we return a response containing an error what happens is
|
// if we return a response containing an error what happens is
|
||||||
// that router.push mounts the login view before the calling
|
// that router.push mounts the login view before the calling
|
||||||
|
@ -36,21 +37,21 @@ export async function fetch(url, init, signal, token, tokenType) {
|
||||||
return { data: await res.json(), error: null };
|
return { data: await res.json(), error: null };
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.name == "AbortError") {
|
if (e.name == 'AbortError') {
|
||||||
return { data: null, error: null, aborted: true };
|
return { data: null, error: null, aborted: true };
|
||||||
}
|
}
|
||||||
return { data: null, error: "api call failed: " + e.message };
|
return { data: null, error: 'api call failed: ' + e.message };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function login(username, password, remotesourcename) {
|
export async function login(username, password, remotesourcename) {
|
||||||
let init = {
|
let init = {
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
remote_source_name: remotesourcename,
|
remote_source_name: remotesourcename,
|
||||||
login_name: username,
|
login_name: username,
|
||||||
password: password
|
password: password,
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -62,7 +63,7 @@ export async function login(username, password, remotesourcename) {
|
||||||
return { data: await res.json(), error: null };
|
return { data: await res.json(), error: null };
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return { data: null, error: "api call failed: " + e.message };
|
return { data: null, error: 'api call failed: ' + e.message };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,13 +74,13 @@ export async function register(
|
||||||
remotepassword
|
remotepassword
|
||||||
) {
|
) {
|
||||||
let init = {
|
let init = {
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
username: username,
|
username: username,
|
||||||
remote_source_name: remotesourcename,
|
remote_source_name: remotesourcename,
|
||||||
remote_source_login_name: remoteloginname,
|
remote_source_login_name: remoteloginname,
|
||||||
remote_source_login_password: remotepassword
|
remote_source_login_password: remotepassword,
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -91,111 +92,122 @@ export async function register(
|
||||||
return { data: await res.json(), error: null };
|
return { data: await res.json(), error: null };
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return { data: null, error: "api call failed: " + e.message };
|
return { data: null, error: 'api call failed: ' + e.message };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchCurrentUser(signal) {
|
export async function fetchCurrentUser(signal) {
|
||||||
let path = "/user";
|
let path = '/user';
|
||||||
return await fetch(apiurl(path), null, signal);
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchOrgMembers(orgref, signal) {
|
export async function fetchOrgMembers(orgref, signal) {
|
||||||
let path = "/orgs/" + orgref + "/members";
|
let path = '/orgs/' + orgref + '/members';
|
||||||
return await fetch(apiurl(path), null, signal);
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchRuns(group, startRunID, lastrun, signal) {
|
export async function fetchRuns(group, startRunID, lastrun, signal) {
|
||||||
let u = apiurl("/runs");
|
let u = apiurl('/runs');
|
||||||
if (group) {
|
if (group) {
|
||||||
u.searchParams.append("group", group);
|
u.searchParams.append('group', group);
|
||||||
}
|
}
|
||||||
if (lastrun) {
|
if (lastrun) {
|
||||||
u.searchParams.append("lastrun", true);
|
u.searchParams.append('lastrun', true);
|
||||||
}
|
}
|
||||||
if (startRunID) {
|
if (startRunID) {
|
||||||
u.searchParams.append("start", startRunID);
|
u.searchParams.append('start', startRunID);
|
||||||
}
|
}
|
||||||
|
|
||||||
return await fetch(u, null, signal);
|
return await fetch(u, null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchRun(runid, signal) {
|
export async function fetchRun(runid, signal) {
|
||||||
return await fetch(apiurl("/runs/" + runid), null, signal);
|
return await fetch(apiurl('/runs/' + runid), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchTask(runid, taskid, signal) {
|
export async function fetchTask(runid, taskid, signal) {
|
||||||
return await fetch(apiurl("/runs/" + runid + "/tasks/" + taskid), signal);
|
return await fetch(apiurl('/runs/' + runid + '/tasks/' + taskid), signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchUser(username, signal) {
|
export async function fetchUser(username, signal) {
|
||||||
let path = "/users/" + username;
|
let path = '/users/' + username;
|
||||||
return await fetch(apiurl(path), null, signal);
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchProjectGroup(projectgroupref, signal) {
|
export async function fetchProjectGroup(projectgroupref, signal) {
|
||||||
let path = "/projectgroups/" + encodeURIComponent(projectgroupref);
|
let path = '/projectgroups/' + encodeURIComponent(projectgroupref);
|
||||||
|
|
||||||
return await fetch(apiurl(path), null, signal);
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchProjectGroupSubgroups(projectgroupref, signal) {
|
export async function fetchProjectGroupSubgroups(projectgroupref, signal) {
|
||||||
let path = "/projectgroups/" + encodeURIComponent(projectgroupref);
|
let path = '/projectgroups/' + encodeURIComponent(projectgroupref);
|
||||||
path += "/subgroups";
|
path += '/subgroups';
|
||||||
|
|
||||||
return await fetch(apiurl(path), null, signal);
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchProjectGroupProjects(projectgroupref, signal) {
|
export async function fetchProjectGroupProjects(projectgroupref, signal) {
|
||||||
let path = "/projectgroups/" + encodeURIComponent(projectgroupref);
|
let path = '/projectgroups/' + encodeURIComponent(projectgroupref);
|
||||||
path += "/projects";
|
path += '/projects';
|
||||||
|
|
||||||
return await fetch(apiurl(path), null, signal);
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchProject(ref, signal) {
|
export async function fetchProject(ref, signal) {
|
||||||
let path = "/projects/" + encodeURIComponent(ref);
|
let path = '/projects/' + encodeURIComponent(ref);
|
||||||
|
|
||||||
return await fetch(apiurl(path), null, signal);
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchSecrets(ownertype, ref, all, signal) {
|
export async function fetchSecrets(ownertype, ref, all, signal) {
|
||||||
let path;
|
let path;
|
||||||
if (ownertype == "project") {
|
if (ownertype == 'project') {
|
||||||
path = "/projects/";
|
path = '/projects/';
|
||||||
} else if (ownertype == "projectgroup") {
|
} else if (ownertype == 'projectgroup') {
|
||||||
path = "/projectgroups/";
|
path = '/projectgroups/';
|
||||||
}
|
}
|
||||||
path += encodeURIComponent(ref);
|
path += encodeURIComponent(ref);
|
||||||
path += "/secrets";
|
path += '/secrets';
|
||||||
if (all) {
|
if (all) {
|
||||||
path += "?tree&removeoverridden";
|
path += '?tree&removeoverridden';
|
||||||
}
|
}
|
||||||
return await fetch(apiurl(path), null, signal);
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchVariables(ownertype, ref, all, signal) {
|
export async function fetchVariables(ownertype, ref, all, signal) {
|
||||||
let path;
|
let path;
|
||||||
if (ownertype == "project") {
|
if (ownertype == 'project') {
|
||||||
path = "/projects/";
|
path = '/projects/';
|
||||||
} else if (ownertype == "projectgroup") {
|
} else if (ownertype == 'projectgroup') {
|
||||||
path = "/projectgroups/";
|
path = '/projectgroups/';
|
||||||
}
|
}
|
||||||
path += encodeURIComponent(ref);
|
path += encodeURIComponent(ref);
|
||||||
path += "/variables";
|
path += '/variables';
|
||||||
if (all) {
|
if (all) {
|
||||||
path += "?tree&removeoverridden";
|
path += '?tree&removeoverridden';
|
||||||
}
|
}
|
||||||
return await fetch(apiurl(path), null, signal);
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createRemoteSource(
|
export async function createRemoteSource(
|
||||||
token, type, name, clientID, clientSecret, apiURL, authType, skipVerify,
|
token,
|
||||||
sshHostKey, skipSshHostKeyCheck, registrationEnabled, loginEnabled, signal,
|
type,
|
||||||
|
name,
|
||||||
|
clientID,
|
||||||
|
clientSecret,
|
||||||
|
apiURL,
|
||||||
|
authType,
|
||||||
|
skipVerify,
|
||||||
|
sshHostKey,
|
||||||
|
skipSshHostKeyCheck,
|
||||||
|
registrationEnabled,
|
||||||
|
loginEnabled,
|
||||||
|
signal
|
||||||
) {
|
) {
|
||||||
let path = "/remotesources";
|
let path = '/remotesources';
|
||||||
let init = {
|
let init = {
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
name,
|
name,
|
||||||
apiurl: apiURL,
|
apiurl: apiURL,
|
||||||
|
@ -208,38 +220,38 @@ export async function createRemoteSource(
|
||||||
oauth_2_client_secret: clientSecret,
|
oauth_2_client_secret: clientSecret,
|
||||||
registration_enabled: registrationEnabled,
|
registration_enabled: registrationEnabled,
|
||||||
login_enabled: loginEnabled,
|
login_enabled: loginEnabled,
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal, token, "token");
|
return await fetch(apiurl(path), init, signal, token, 'token');
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createOrganization(orgname, visibility, signal) {
|
export async function createOrganization(orgname, visibility, signal) {
|
||||||
let path = "/orgs";
|
let path = '/orgs';
|
||||||
let init = {
|
let init = {
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
name: orgname,
|
name: orgname,
|
||||||
visibility: visibility
|
visibility: visibility,
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createUserToken(username, tokenname, signal) {
|
export async function createUserToken(username, tokenname, signal) {
|
||||||
let path = "/users/" + username + "/tokens";
|
let path = '/users/' + username + '/tokens';
|
||||||
let init = {
|
let init = {
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
token_name: tokenname
|
token_name: tokenname,
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteUserToken(username, tokenname, signal) {
|
export async function deleteUserToken(username, tokenname, signal) {
|
||||||
let path = "/users/" + username + "/tokens/" + tokenname;
|
let path = '/users/' + username + '/tokens/' + tokenname;
|
||||||
let init = {
|
let init = {
|
||||||
method: "DELETE"
|
method: 'DELETE',
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
@ -251,90 +263,90 @@ export async function createUserLinkedAccount(
|
||||||
password,
|
password,
|
||||||
signal
|
signal
|
||||||
) {
|
) {
|
||||||
let path = "/users/" + username + "/linkedaccounts";
|
let path = '/users/' + username + '/linkedaccounts';
|
||||||
let init = {
|
let init = {
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
remote_source_name: remotesourcename,
|
remote_source_name: remotesourcename,
|
||||||
remote_source_login_name: loginname,
|
remote_source_login_name: loginname,
|
||||||
remote_source_login_password: password
|
remote_source_login_password: password,
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteLinkedAccount(username, laid, signal) {
|
export async function deleteLinkedAccount(username, laid, signal) {
|
||||||
let path = "/users/" + username + "/linkedaccounts/" + laid;
|
let path = '/users/' + username + '/linkedaccounts/' + laid;
|
||||||
let init = {
|
let init = {
|
||||||
method: "DELETE"
|
method: 'DELETE',
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function restartRun(runid, fromStart, signal) {
|
export async function restartRun(runid, fromStart, signal) {
|
||||||
let path = "/runs/" + runid + "/actions";
|
let path = '/runs/' + runid + '/actions';
|
||||||
let init = {
|
let init = {
|
||||||
method: "PUT",
|
method: 'PUT',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
action_type: "restart",
|
action_type: 'restart',
|
||||||
from_start: fromStart
|
from_start: fromStart,
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function cancelRun(runid, signal) {
|
export async function cancelRun(runid, signal) {
|
||||||
let path = "/runs/" + runid + "/actions";
|
let path = '/runs/' + runid + '/actions';
|
||||||
let init = {
|
let init = {
|
||||||
method: "PUT",
|
method: 'PUT',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
action_type: "cancel"
|
action_type: 'cancel',
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function stopRun(runid, signal) {
|
export async function stopRun(runid, signal) {
|
||||||
let path = "/runs/" + runid + "/actions";
|
let path = '/runs/' + runid + '/actions';
|
||||||
let init = {
|
let init = {
|
||||||
method: "PUT",
|
method: 'PUT',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
action_type: "stop"
|
action_type: 'stop',
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function approveTask(runid, taskid, signal) {
|
export async function approveTask(runid, taskid, signal) {
|
||||||
let path = "/runs/" + runid + "/tasks/" + taskid + "/actions";
|
let path = '/runs/' + runid + '/tasks/' + taskid + '/actions';
|
||||||
let init = {
|
let init = {
|
||||||
method: "PUT",
|
method: 'PUT',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
action_type: "approve"
|
action_type: 'approve',
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchRemoteSources(signal) {
|
export async function fetchRemoteSources(signal) {
|
||||||
let path = "/remotesources";
|
let path = '/remotesources';
|
||||||
return await fetch(apiurl(path), null, signal);
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function userRemoteRepos(remotesourceid, signal) {
|
export async function userRemoteRepos(remotesourceid, signal) {
|
||||||
let path = "/user/remoterepos/" + remotesourceid;
|
let path = '/user/remoterepos/' + remotesourceid;
|
||||||
return await fetch(apiurl(path, null, signal));
|
return await fetch(apiurl(path, null, signal));
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createProjectGroup(parentref, name, visibility, signal) {
|
export async function createProjectGroup(parentref, name, visibility, signal) {
|
||||||
let path = "/projectgroups";
|
let path = '/projectgroups';
|
||||||
let init = {
|
let init = {
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
name: name,
|
name: name,
|
||||||
parent_ref: parentref,
|
parent_ref: parentref,
|
||||||
visibility: visibility
|
visibility: visibility,
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
@ -345,13 +357,13 @@ export async function updateProjectGroup(
|
||||||
visibility,
|
visibility,
|
||||||
signal
|
signal
|
||||||
) {
|
) {
|
||||||
let path = "/projectgroups/" + encodeURIComponent(projectgroupref);
|
let path = '/projectgroups/' + encodeURIComponent(projectgroupref);
|
||||||
let init = {
|
let init = {
|
||||||
method: "PUT",
|
method: 'PUT',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
name: name,
|
name: name,
|
||||||
visibility: visibility
|
visibility: visibility,
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
@ -365,56 +377,61 @@ export async function createProject(
|
||||||
passvarstoforkedpr,
|
passvarstoforkedpr,
|
||||||
signal
|
signal
|
||||||
) {
|
) {
|
||||||
let path = "/projects";
|
let path = '/projects';
|
||||||
let init = {
|
let init = {
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
name: name,
|
name: name,
|
||||||
parent_ref: parentref,
|
parent_ref: parentref,
|
||||||
visibility: visibility,
|
visibility: visibility,
|
||||||
remote_source_name: remotesourcename,
|
remote_source_name: remotesourcename,
|
||||||
repo_path: remoterepopath,
|
repo_path: remoterepopath,
|
||||||
pass_vars_to_forked_pr: passvarstoforkedpr
|
pass_vars_to_forked_pr: passvarstoforkedpr,
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updateProject(projectref, name, visibility, passvarstoforkedpr, signal) {
|
export async function updateProject(
|
||||||
let path = "/projects/" + encodeURIComponent(projectref);
|
projectref,
|
||||||
|
name,
|
||||||
|
visibility,
|
||||||
|
passvarstoforkedpr,
|
||||||
|
signal
|
||||||
|
) {
|
||||||
|
let path = '/projects/' + encodeURIComponent(projectref);
|
||||||
let init = {
|
let init = {
|
||||||
method: "PUT",
|
method: 'PUT',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
name: name,
|
name: name,
|
||||||
visibility: visibility,
|
visibility: visibility,
|
||||||
pass_vars_to_forked_pr: passvarstoforkedpr
|
pass_vars_to_forked_pr: passvarstoforkedpr,
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteProject(projectref, signal) {
|
export async function deleteProject(projectref, signal) {
|
||||||
let path = "/projects/" + encodeURIComponent(projectref);
|
let path = '/projects/' + encodeURIComponent(projectref);
|
||||||
let init = {
|
let init = {
|
||||||
method: "DELETE"
|
method: 'DELETE',
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function projectUpdateRepoLinkedAccount(projectref, signal) {
|
export async function projectUpdateRepoLinkedAccount(projectref, signal) {
|
||||||
let path =
|
let path =
|
||||||
"/projects/" + encodeURIComponent(projectref) + "/updaterepolinkedaccount";
|
'/projects/' + encodeURIComponent(projectref) + '/updaterepolinkedaccount';
|
||||||
let init = {
|
let init = {
|
||||||
method: "PUT"
|
method: 'PUT',
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteProjectGroup(projectgroupref, signal) {
|
export async function deleteProjectGroup(projectgroupref, signal) {
|
||||||
let path = "/projectgroups/" + encodeURIComponent(projectgroupref);
|
let path = '/projectgroups/' + encodeURIComponent(projectgroupref);
|
||||||
let init = {
|
let init = {
|
||||||
method: "DELETE"
|
method: 'DELETE',
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
153
src/util/link.js
153
src/util/link.js
|
@ -1,130 +1,173 @@
|
||||||
export function parseRef(ref) {
|
export function parseRef(ref) {
|
||||||
ref = ref.replace(/\.proj/, "")
|
ref = ref.replace(/\.proj/, '');
|
||||||
// return empty array or split return an array with the empty element
|
// return empty array or split return an array with the empty element
|
||||||
if (!ref) {
|
if (!ref) {
|
||||||
return []
|
return [];
|
||||||
}
|
}
|
||||||
return ref.split("/")
|
return ref.split('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ownerLink(ownertype, ownername) {
|
export function ownerLink(ownertype, ownername) {
|
||||||
if (ownertype == "user") {
|
if (ownertype == 'user') {
|
||||||
return { name: ownertype, params: { username: ownername } }
|
return { name: ownertype, params: { username: ownername } };
|
||||||
} else if (ownertype == "org") {
|
} else if (ownertype == 'org') {
|
||||||
return { name: ownertype, params: { orgname: ownername } }
|
return { name: ownertype, params: { orgname: ownername } };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ownerProjectsLink(ownertype, ownername) {
|
export function ownerProjectsLink(ownertype, ownername) {
|
||||||
return { name: ownertype + " projects", params: { ownername: ownername } }
|
return { name: ownertype + ' projects', params: { ownername: ownername } };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ownerSettingsLink(ownertype, ownername) {
|
export function ownerSettingsLink(ownertype, ownername) {
|
||||||
if (ownertype == "user") {
|
if (ownertype == 'user') {
|
||||||
return { name: ownertype + " settings", params: { username: ownername } }
|
return { name: ownertype + ' settings', params: { username: ownername } };
|
||||||
} else if (ownertype == "org") {
|
} else if (ownertype == 'org') {
|
||||||
return { name: ownertype + " settings", params: { orgname: ownername } }
|
return { name: ownertype + ' settings', params: { orgname: ownername } };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function userDirectRunsLink(username) {
|
export function userDirectRunsLink(username) {
|
||||||
return { name: "user direct runs", params: { username: username } }
|
return { name: 'user direct runs', params: { username: username } };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function userDirectRunLink(username, runid) {
|
export function userDirectRunLink(username, runid) {
|
||||||
return { name: "user direct run", params: { username: username, runid: runid } }
|
return {
|
||||||
|
name: 'user direct run',
|
||||||
|
params: { username: username, runid: runid },
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function userDirectRunTaskLink(username, runid, taskid) {
|
export function userDirectRunTaskLink(username, runid, taskid) {
|
||||||
return { name: "user direct run task", params: { username: username, runid: runid, taskid: taskid } }
|
return {
|
||||||
|
name: 'user direct run task',
|
||||||
|
params: { username: username, runid: runid, taskid: taskid },
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function userAddLinkedAccountLink(username, remotesourcename) {
|
export function userAddLinkedAccountLink(username, remotesourcename) {
|
||||||
return { name: "user add linked account", params: { username: username, remotesource: remotesourcename } }
|
return {
|
||||||
|
name: 'user add linked account',
|
||||||
|
params: { username: username, remotesource: remotesourcename },
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function orgMembersLink(orgname) {
|
export function orgMembersLink(orgname) {
|
||||||
return { name: "org members", params: { orgname: orgname } }
|
return { name: 'org members', params: { orgname: orgname } };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note, when creating a router link containing a project/projectgroup ref (a
|
// Note, when creating a router link containing a project/projectgroup ref (a
|
||||||
// path), unfortunately, we cannot use route name and params since it will path
|
// path), unfortunately, we cannot use route name and params since it will path
|
||||||
// escape it
|
// escape it
|
||||||
export function projectGroupPath(ownertype, ownername, projectgroupref) {
|
export function projectGroupPath(ownertype, ownername, projectgroupref) {
|
||||||
let path = `/${ownertype}/${ownername}`
|
let path = `/${ownertype}/${ownername}`;
|
||||||
// root project group will have a .proj without a name
|
// root project group will have a .proj without a name
|
||||||
let projectgrouppath = (projectgroupref.join("/") + ".proj")
|
let projectgrouppath = projectgroupref.join('/') + '.proj';
|
||||||
path = `${path}/projectgroups/${projectgrouppath}`
|
path = `${path}/projectgroups/${projectgrouppath}`;
|
||||||
return path
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function projectPath(ownertype, ownername, projectref) {
|
export function projectPath(ownertype, ownername, projectref) {
|
||||||
let path = `/${ownertype}/${ownername}`
|
let path = `/${ownertype}/${ownername}`;
|
||||||
let projectpath = (projectref.join("/") + ".proj")
|
let projectpath = projectref.join('/') + '.proj';
|
||||||
path = `${path}/projects/${projectpath}`
|
path = `${path}/projects/${projectpath}`;
|
||||||
return path
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function projectGroupLink(ownertype, ownername, projectgroupref) {
|
export function projectGroupLink(ownertype, ownername, projectgroupref) {
|
||||||
return { path: projectGroupPath(ownertype, ownername, projectgroupref) }
|
return { path: projectGroupPath(ownertype, ownername, projectgroupref) };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function projectGroupProjectsLink(ownertype, ownername, projectgroupref) {
|
export function projectGroupProjectsLink(
|
||||||
let projectgrouppath = (projectgroupref.join("/") + ".proj")
|
ownertype,
|
||||||
return { path: `/${ownertype}/${ownername}/projectgroups/${projectgrouppath}/projects` }
|
ownername,
|
||||||
|
projectgroupref
|
||||||
|
) {
|
||||||
|
let projectgrouppath = projectgroupref.join('/') + '.proj';
|
||||||
|
return {
|
||||||
|
path: `/${ownertype}/${ownername}/projectgroups/${projectgrouppath}/projects`,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function projectLink(ownertype, ownername, projectref) {
|
export function projectLink(ownertype, ownername, projectref) {
|
||||||
let projectpath = (projectref.join("/") + ".proj")
|
let projectpath = projectref.join('/') + '.proj';
|
||||||
return { path: `/${ownertype}/${ownername}/projects/${projectpath}` }
|
return { path: `/${ownertype}/${ownername}/projects/${projectpath}` };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function projectRunsLink(ownertype, ownername, projectref) {
|
export function projectRunsLink(ownertype, ownername, projectref) {
|
||||||
let projectpath = (projectref.join("/") + ".proj")
|
let projectpath = projectref.join('/') + '.proj';
|
||||||
return { path: `/${ownertype}/${ownername}/projects/${projectpath}/runs` }
|
return { path: `/${ownertype}/${ownername}/projects/${projectpath}/runs` };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function projectBranchesRunsLink(ownertype, ownername, projectref) {
|
export function projectBranchesRunsLink(ownertype, ownername, projectref) {
|
||||||
let projectpath = (projectref.join("/") + ".proj")
|
let projectpath = projectref.join('/') + '.proj';
|
||||||
return { path: `/${ownertype}/${ownername}/projects/${projectpath}/branches` }
|
return {
|
||||||
|
path: `/${ownertype}/${ownername}/projects/${projectpath}/branches`,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function projectTagsRunsLink(ownertype, ownername, projectref) {
|
export function projectTagsRunsLink(ownertype, ownername, projectref) {
|
||||||
let projectpath = (projectref.join("/") + ".proj")
|
let projectpath = projectref.join('/') + '.proj';
|
||||||
return { path: `/${ownertype}/${ownername}/projects/${projectpath}/tags` }
|
return { path: `/${ownertype}/${ownername}/projects/${projectpath}/tags` };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function projectPRsRunsLink(ownertype, ownername, projectref) {
|
export function projectPRsRunsLink(ownertype, ownername, projectref) {
|
||||||
let projectpath = (projectref.join("/") + ".proj")
|
let projectpath = projectref.join('/') + '.proj';
|
||||||
return { path: `/${ownertype}/${ownername}/projects/${projectpath}/pullrequests` }
|
return {
|
||||||
|
path: `/${ownertype}/${ownername}/projects/${projectpath}/pullrequests`,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function projectRunLink(ownertype, ownername, projectref, runid) {
|
export function projectRunLink(ownertype, ownername, projectref, runid) {
|
||||||
let projectpath = (projectref.join("/") + ".proj")
|
let projectpath = projectref.join('/') + '.proj';
|
||||||
return { path: `/${ownertype}/${ownername}/projects/${projectpath}/runs/${runid}` }
|
return {
|
||||||
|
path: `/${ownertype}/${ownername}/projects/${projectpath}/runs/${runid}`,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function projectRunTaskLink(ownertype, ownername, projectref, runid, taskid) {
|
export function projectRunTaskLink(
|
||||||
let projectpath = (projectref.join("/") + ".proj")
|
ownertype,
|
||||||
return { path: `/${ownertype}/${ownername}/projects/${projectpath}/runs/${runid}/tasks/${taskid}` }
|
ownername,
|
||||||
|
projectref,
|
||||||
|
runid,
|
||||||
|
taskid
|
||||||
|
) {
|
||||||
|
let projectpath = projectref.join('/') + '.proj';
|
||||||
|
return {
|
||||||
|
path: `/${ownertype}/${ownername}/projects/${projectpath}/runs/${runid}/tasks/${taskid}`,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function projectGroupSettingsLink(ownertype, ownername, projectgroupref) {
|
export function projectGroupSettingsLink(
|
||||||
let path = projectGroupPath(ownertype, ownername, projectgroupref)
|
ownertype,
|
||||||
return { path: `${path}/settings` }
|
ownername,
|
||||||
|
projectgroupref
|
||||||
|
) {
|
||||||
|
let path = projectGroupPath(ownertype, ownername, projectgroupref);
|
||||||
|
return { path: `${path}/settings` };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function projectSettingsLink(ownertype, ownername, projectref) {
|
export function projectSettingsLink(ownertype, ownername, projectref) {
|
||||||
let projectpath = (projectref.join("/") + ".proj")
|
let projectpath = projectref.join('/') + '.proj';
|
||||||
return { path: `/${ownertype}/${ownername}/projects/${projectpath}/settings` }
|
return {
|
||||||
|
path: `/${ownertype}/${ownername}/projects/${projectpath}/settings`,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function projectGroupCreateProjectGroupLink(ownertype, ownername, projectgroupref) {
|
export function projectGroupCreateProjectGroupLink(
|
||||||
let path = projectGroupPath(ownertype, ownername, projectgroupref)
|
ownertype,
|
||||||
return { path: `${path}/createprojectgroup` }
|
ownername,
|
||||||
|
projectgroupref
|
||||||
|
) {
|
||||||
|
let path = projectGroupPath(ownertype, ownername, projectgroupref);
|
||||||
|
return { path: `${path}/createprojectgroup` };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function projectGroupCreateProjectLink(ownertype, ownername, projectgroupref) {
|
export function projectGroupCreateProjectLink(
|
||||||
let path = projectGroupPath(ownertype, ownername, projectgroupref)
|
ownertype,
|
||||||
return { path: `${path}/createproject` }
|
ownername,
|
||||||
|
projectgroupref
|
||||||
|
) {
|
||||||
|
let path = projectGroupPath(ownertype, ownername, projectgroupref);
|
||||||
|
return { path: `${path}/createproject` };
|
||||||
}
|
}
|
|
@ -1,11 +1,10 @@
|
||||||
|
|
||||||
export function runStatus(run) {
|
export function runStatus(run) {
|
||||||
// * if the run has a result then return the result
|
// * if the run has a result then return the result
|
||||||
// * if stopping return "stopping"
|
// * if stopping return "stopping"
|
||||||
// * return the phase
|
// * return the phase
|
||||||
if (run.result != "unknown") return run.result;
|
if (run.result != 'unknown') return run.result;
|
||||||
if (run.stopping) return "stopping";
|
if (run.stopping) return 'stopping';
|
||||||
if (run.phase != "finished") return run.phase;
|
if (run.phase != 'finished') return run.phase;
|
||||||
|
|
||||||
return run.result;
|
return run.result;
|
||||||
}
|
}
|
||||||
|
@ -13,13 +12,13 @@ export function runStatus(run) {
|
||||||
export function runResultClass(run) {
|
export function runResultClass(run) {
|
||||||
let status = runStatus(run);
|
let status = runStatus(run);
|
||||||
|
|
||||||
if (status == "setuperror") return "setuperror";
|
if (status == 'setuperror') return 'setuperror';
|
||||||
if (status == "queued") return "unknown";
|
if (status == 'queued') return 'unknown';
|
||||||
if (status == "cancelled") return "failed";
|
if (status == 'cancelled') return 'failed';
|
||||||
if (status == "running") return "running";
|
if (status == 'running') return 'running';
|
||||||
if (status == "stopping") return "failed";
|
if (status == 'stopping') return 'failed';
|
||||||
if (status == "stopped") return "failed";
|
if (status == 'stopped') return 'failed';
|
||||||
if (status == "success") return "success";
|
if (status == 'success') return 'success';
|
||||||
if (status == "failed") return "failed";
|
if (status == 'failed') return 'failed';
|
||||||
return "unknown";
|
return 'unknown';
|
||||||
}
|
}
|
|
@ -13,36 +13,44 @@
|
||||||
v-if="remotesource.auth_type == 'password'"
|
v-if="remotesource.auth_type == 'password'"
|
||||||
action="Add Linked Account"
|
action="Add Linked Account"
|
||||||
:name="remotesource.name"
|
:name="remotesource.name"
|
||||||
v-on:login="doAddLinkedAccount(remotesource.name, $event.username, $event.password)"
|
v-on:login="
|
||||||
|
doAddLinkedAccount(
|
||||||
|
remotesource.name,
|
||||||
|
$event.username,
|
||||||
|
$event.password
|
||||||
|
)
|
||||||
|
"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
v-else
|
v-else
|
||||||
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
|
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
|
||||||
@click="doAddLinkedAccount(remotesource.name)"
|
@click="doAddLinkedAccount(remotesource.name)"
|
||||||
>Add Linked Account with {{remotesource.name}}</button>
|
>
|
||||||
|
Add Linked Account with {{ remotesource.name }}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import LoginForm from "@/components/loginform";
|
import LoginForm from '@/components/loginform';
|
||||||
|
|
||||||
import { fetchRemoteSources, createUserLinkedAccount } from "@/util/data";
|
import { fetchRemoteSources, createUserLinkedAccount } from '@/util/data';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "AddLinkedAccount",
|
name: 'AddLinkedAccount',
|
||||||
props: {
|
props: {
|
||||||
username: String,
|
username: String,
|
||||||
remoteSourceName: String
|
remoteSourceName: String,
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
LoginForm
|
LoginForm,
|
||||||
},
|
},
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
addLinkedAccountError: null,
|
addLinkedAccountError: null,
|
||||||
remotesource: null
|
remotesource: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -52,7 +60,7 @@ export default {
|
||||||
async fetchRemoteSources() {
|
async fetchRemoteSources() {
|
||||||
let { data, error } = await fetchRemoteSources();
|
let { data, error } = await fetchRemoteSources();
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (var i = 0; i < data.length; i++) {
|
for (var i = 0; i < data.length; i++) {
|
||||||
|
@ -79,17 +87,13 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
name: "user settings",
|
name: 'user settings',
|
||||||
params: { username: this.username }
|
params: { username: this.username },
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
this.fetchRemoteSources();
|
this.fetchRemoteSources();
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,12 +9,8 @@
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div class="flex justify-center items-center w-max">
|
||||||
class="flex justify-center items-center w-max"
|
<CreateSourceForm v-on:createSource="createSource($event)" />
|
||||||
>
|
|
||||||
<CreateSourceForm
|
|
||||||
v-on:createSource="createSource($event)"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -22,15 +18,14 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import CreateSourceForm from '@/components/createsourceform';
|
||||||
import CreateSourceForm from "@/components/createsourceform";
|
import { createRemoteSource } from '@/util/data.js';
|
||||||
import { createRemoteSource } from "@/util/data.js";
|
import router from '@/router';
|
||||||
import router from "@/router";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "CreateSource",
|
name: 'CreateSource',
|
||||||
components: {
|
components: {
|
||||||
CreateSourceForm
|
CreateSourceForm,
|
||||||
},
|
},
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
|
@ -39,23 +34,37 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async createSource({
|
async createSource({
|
||||||
token, name, type, clientId, clientSecret, url, skipVerify, sshHostKey,
|
token,
|
||||||
|
name,
|
||||||
|
type,
|
||||||
|
clientId,
|
||||||
|
clientSecret,
|
||||||
|
url,
|
||||||
|
skipVerify,
|
||||||
|
sshHostKey,
|
||||||
skipSshHostKeyCheck,
|
skipSshHostKeyCheck,
|
||||||
}) {
|
}) {
|
||||||
const res = await createRemoteSource(
|
const res = await createRemoteSource(
|
||||||
token, type, name, clientId, clientSecret, url, "oauth2", skipVerify,
|
token,
|
||||||
sshHostKey, skipSshHostKeyCheck, true, true, undefined,
|
type,
|
||||||
|
name,
|
||||||
|
clientId,
|
||||||
|
clientSecret,
|
||||||
|
url,
|
||||||
|
'oauth2',
|
||||||
|
skipVerify,
|
||||||
|
sshHostKey,
|
||||||
|
skipSshHostKeyCheck,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
undefined
|
||||||
);
|
);
|
||||||
if (res.error)
|
if (res.error) this.$store.dispatch('setError', res.error);
|
||||||
this.$store.dispatch("setError", res.error);
|
else router.push({ name: 'login' });
|
||||||
else
|
},
|
||||||
router.push({name: "login"});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
mounted: function () {
|
mounted: function () {
|
||||||
this.$store.dispatch("setError", null);
|
this.$store.dispatch('setError', null);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,25 +1,15 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="home flex flex-col items-center">
|
<div class="home flex flex-col items-center">
|
||||||
<img
|
<img class="w-64 h-64" src="/img/agola-logo-name.svg" alt="agola logo" />
|
||||||
class="w-64 h-64"
|
|
||||||
src="/img/agola-logo-name.svg" alt="agola logo"
|
|
||||||
/>
|
|
||||||
<h1 class="text-2xl">CI/CD redefined</h1>
|
<h1 class="text-2xl">CI/CD redefined</h1>
|
||||||
<div class="m-8">
|
<div class="m-8">
|
||||||
<h1 class="text-lg">
|
<h1 class="text-lg">
|
||||||
Hi, you are almost ready to go! Just
|
Hi, you are almost ready to go! Just
|
||||||
<router-link
|
<router-link class="underline text-blue-600" to="/login">
|
||||||
class="underline text-blue-600"
|
|
||||||
to="/login"
|
|
||||||
>
|
|
||||||
login
|
login
|
||||||
</router-link>
|
</router-link>
|
||||||
into your account
|
into your account or create a
|
||||||
or create a
|
<router-link class="underline text-blue-600" to="/register">
|
||||||
<router-link
|
|
||||||
class="underline text-blue-600"
|
|
||||||
to="/register"
|
|
||||||
>
|
|
||||||
new one
|
new one
|
||||||
</router-link>
|
</router-link>
|
||||||
</h1>
|
</h1>
|
||||||
|
@ -28,22 +18,22 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters } from "vuex";
|
import { mapGetters } from 'vuex';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Home",
|
name: 'Home',
|
||||||
components: {},
|
components: {},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(["user"])
|
...mapGetters(['user']),
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
let user = this.$store.getters.user;
|
let user = this.$store.getters.user;
|
||||||
if (user) {
|
if (user) {
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
name: "user",
|
name: 'user',
|
||||||
params: { username: this.user.username }
|
params: { username: this.user.username },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -13,13 +13,8 @@
|
||||||
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
||||||
>
|
>
|
||||||
No remote sources defined
|
No remote sources defined
|
||||||
<router-link
|
<router-link class="underline text-blue-600 block" to="/newsource">
|
||||||
class="underline text-blue-600 block"
|
<button class="btn btn-blue">Create one</button>
|
||||||
to="/newsource"
|
|
||||||
>
|
|
||||||
<button class="btn btn-blue">
|
|
||||||
Create one
|
|
||||||
</button>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -61,25 +56,25 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { fetchRemoteSources, login } from "@/util/data";
|
import { fetchRemoteSources, login } from '@/util/data';
|
||||||
import {
|
import {
|
||||||
setLoggedUser,
|
setLoggedUser,
|
||||||
unsetLoginRedirect,
|
unsetLoginRedirect,
|
||||||
setLoginRedirect,
|
setLoginRedirect,
|
||||||
doLogout
|
doLogout,
|
||||||
} from "@/util/auth";
|
} from '@/util/auth';
|
||||||
|
|
||||||
import LoginForm from "@/components/loginform";
|
import LoginForm from '@/components/loginform';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Login",
|
name: 'Login',
|
||||||
components: {
|
components: {
|
||||||
LoginForm
|
LoginForm,
|
||||||
},
|
},
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
error: null,
|
error: null,
|
||||||
remotesources: null
|
remotesources: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -96,20 +91,20 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async fetchRemoteSources() {
|
async fetchRemoteSources() {
|
||||||
let { data, error } = await fetchRemoteSources();
|
let { data, error } = await fetchRemoteSources();
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.remotesources = data;
|
this.remotesources = data;
|
||||||
},
|
},
|
||||||
async doLogin(username, password, remotesourcename) {
|
async doLogin(username, password, remotesourcename) {
|
||||||
unsetLoginRedirect();
|
unsetLoginRedirect();
|
||||||
let redirect = this.$route.query["redirect"];
|
let redirect = this.$route.query['redirect'];
|
||||||
|
|
||||||
this.error = null;
|
this.error = null;
|
||||||
|
|
||||||
|
@ -131,18 +126,16 @@ export default {
|
||||||
unsetLoginRedirect();
|
unsetLoginRedirect();
|
||||||
this.$router.push(redirect);
|
this.$router.push(redirect);
|
||||||
} else {
|
} else {
|
||||||
this.$router.push({ name: "home" });
|
this.$router.push({ name: 'home' });
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
},
|
||||||
mounted: function () {
|
mounted: function () {
|
||||||
this.$store.dispatch("setError", null);
|
this.$store.dispatch('setError', null);
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
doLogout();
|
doLogout();
|
||||||
this.fetchRemoteSources();
|
this.fetchRemoteSources();
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
<script>
|
<script>
|
||||||
import { doLogout } from "@/util/auth";
|
import { doLogout } from '@/util/auth';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Logout",
|
name: 'Logout',
|
||||||
created: function () {
|
created: function () {
|
||||||
doLogout();
|
doLogout();
|
||||||
this.$router.push("/");
|
this.$router.push('/');
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,32 +11,32 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { fetch } from "@/util/data";
|
import { fetch } from '@/util/data';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
oauth2callbackurl,
|
oauth2callbackurl,
|
||||||
setLoggedUser,
|
setLoggedUser,
|
||||||
unsetLoginRedirect,
|
unsetLoginRedirect,
|
||||||
getLoginRedirect
|
getLoginRedirect,
|
||||||
} from "@/util/auth";
|
} from '@/util/auth';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: {},
|
||||||
name: "Oauth2",
|
name: 'Oauth2',
|
||||||
props: {},
|
props: {},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
error: null,
|
error: null,
|
||||||
run: null,
|
run: null,
|
||||||
code: this.$route.query.code,
|
code: this.$route.query.code,
|
||||||
username: null
|
username: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async doOauth2() {
|
async doOauth2() {
|
||||||
let u = oauth2callbackurl();
|
let u = oauth2callbackurl();
|
||||||
u.searchParams.append("code", this.$route.query.code);
|
u.searchParams.append('code', this.$route.query.code);
|
||||||
u.searchParams.append("state", this.$route.query.state);
|
u.searchParams.append('state', this.$route.query.state);
|
||||||
let { data, error } = await fetch(u);
|
let { data, error } = await fetch(u);
|
||||||
if (error) {
|
if (error) {
|
||||||
// set local login error on failed oauth2.
|
// set local login error on failed oauth2.
|
||||||
|
@ -44,29 +44,28 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.request_type === "loginuser") {
|
if (data.request_type === 'loginuser') {
|
||||||
setLoggedUser(data.response.token, data.response.user);
|
setLoggedUser(data.response.token, data.response.user);
|
||||||
let redirect = getLoginRedirect(redirect);
|
let redirect = getLoginRedirect(redirect);
|
||||||
if (redirect) {
|
if (redirect) {
|
||||||
unsetLoginRedirect();
|
unsetLoginRedirect();
|
||||||
this.$router.push(redirect);
|
this.$router.push(redirect);
|
||||||
} else {
|
} else {
|
||||||
this.$router.push({ name: "home" });
|
this.$router.push({ name: 'home' });
|
||||||
}
|
}
|
||||||
} else if (data.request_type === "authorize") {
|
} else if (data.request_type === 'authorize') {
|
||||||
this.$store.dispatch("setRegisterUser", data.response);
|
this.$store.dispatch('setRegisterUser', data.response);
|
||||||
this.$router.push("/register");
|
this.$router.push('/register');
|
||||||
} else if (data.request_type === "createuserla") {
|
} else if (data.request_type === 'createuserla') {
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
name: "user settings",
|
name: 'user settings',
|
||||||
params: { username: this.username }
|
params: { username: this.username },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
this.doOauth2();
|
this.doOauth2();
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,9 @@
|
||||||
<span class="mx-2">/</span>
|
<span class="mx-2">/</span>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<router-link :to="ownerLink('org', orgname)">{{orgname}}</router-link>
|
<router-link :to="ownerLink('org', orgname)">{{
|
||||||
|
orgname
|
||||||
|
}}</router-link>
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
</nav>
|
</nav>
|
||||||
|
@ -23,7 +25,12 @@
|
||||||
<ul class="flex-grow tab">
|
<ul class="flex-grow tab">
|
||||||
<li
|
<li
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
:class="[{ 'tab-element-selected': $route.name === 'org projects' || $route.name === 'org' }]"
|
:class="[
|
||||||
|
{
|
||||||
|
'tab-element-selected':
|
||||||
|
$route.name === 'org projects' || $route.name === 'org',
|
||||||
|
},
|
||||||
|
]"
|
||||||
>
|
>
|
||||||
<router-link :to="ownerProjectsLink('org', orgname)">
|
<router-link :to="ownerProjectsLink('org', orgname)">
|
||||||
<i class="mr-1 mdi mdi-home" />
|
<i class="mr-1 mdi mdi-home" />
|
||||||
|
@ -42,7 +49,13 @@
|
||||||
<li
|
<li
|
||||||
v-if="$route.name.endsWith('org project group settings')"
|
v-if="$route.name.endsWith('org project group settings')"
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
:class="[{ 'tab-element-selected': $route.name.endsWith('org project group settings') }]"
|
:class="[
|
||||||
|
{
|
||||||
|
'tab-element-selected': $route.name.endsWith(
|
||||||
|
'org project group settings'
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]"
|
||||||
>
|
>
|
||||||
<router-link :to="projectGroupSettingsLink('org', orgname, [])">
|
<router-link :to="projectGroupSettingsLink('org', orgname, [])">
|
||||||
<i class="mr-1 mdi mdi-settings" />
|
<i class="mr-1 mdi mdi-settings" />
|
||||||
|
@ -52,7 +65,9 @@
|
||||||
<li
|
<li
|
||||||
v-if="$route.name.endsWith('org settings')"
|
v-if="$route.name.endsWith('org settings')"
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
:class="[{ 'tab-element-selected': $route.name.endsWith('org settings') }]"
|
:class="[
|
||||||
|
{ 'tab-element-selected': $route.name.endsWith('org settings') },
|
||||||
|
]"
|
||||||
>
|
>
|
||||||
<router-link :to="ownerSettingsLink('org', orgname)">
|
<router-link :to="ownerSettingsLink('org', orgname)">
|
||||||
<i class="mr-1 mdi mdi-settings" />
|
<i class="mr-1 mdi mdi-settings" />
|
||||||
|
@ -65,7 +80,7 @@
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<div
|
<div
|
||||||
class="flex -mt-3"
|
class="flex -mt-3"
|
||||||
v-click-outside="() => dropdownActive = false"
|
v-click-outside="() => (dropdownActive = false)"
|
||||||
@click="dropdownActive = !dropdownActive"
|
@click="dropdownActive = !dropdownActive"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
|
@ -108,9 +123,8 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as vClickOutside from "v-click-outside-x";
|
import * as vClickOutside from 'v-click-outside-x';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ownerLink,
|
ownerLink,
|
||||||
|
@ -119,23 +133,23 @@ import {
|
||||||
orgMembersLink,
|
orgMembersLink,
|
||||||
projectGroupCreateProjectGroupLink,
|
projectGroupCreateProjectGroupLink,
|
||||||
projectGroupCreateProjectLink,
|
projectGroupCreateProjectLink,
|
||||||
projectGroupSettingsLink
|
projectGroupSettingsLink,
|
||||||
} from "@/util/link.js";
|
} from '@/util/link.js';
|
||||||
|
|
||||||
import createprojectbutton from "@/components/createprojectbutton.vue";
|
import createprojectbutton from '@/components/createprojectbutton.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Org",
|
name: 'Org',
|
||||||
components: { createprojectbutton },
|
components: { createprojectbutton },
|
||||||
directives: {
|
directives: {
|
||||||
clickOutside: vClickOutside.directive
|
clickOutside: vClickOutside.directive,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
orgname: String
|
orgname: String,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
dropdownActive: false
|
dropdownActive: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -147,19 +161,18 @@ export default {
|
||||||
projectGroupCreateProjectLink: projectGroupCreateProjectLink,
|
projectGroupCreateProjectLink: projectGroupCreateProjectLink,
|
||||||
projectGroupSettingsLink: projectGroupSettingsLink,
|
projectGroupSettingsLink: projectGroupSettingsLink,
|
||||||
goToCreate(type) {
|
goToCreate(type) {
|
||||||
if (type == "project") {
|
if (type == 'project') {
|
||||||
this.$router.push(
|
this.$router.push(
|
||||||
projectGroupCreateProjectLink("org", this.orgname, [])
|
projectGroupCreateProjectLink('org', this.orgname, [])
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.$router.push(
|
this.$router.push(
|
||||||
projectGroupCreateProjectGroupLink("org", this.orgname, [])
|
projectGroupCreateProjectGroupLink('org', this.orgname, [])
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<projbreadcrumbs :ownertype="ownertype" :ownername="ownername" :projectref="projectref" />
|
<projbreadcrumbs
|
||||||
|
:ownertype="ownertype"
|
||||||
|
:ownername="ownername"
|
||||||
|
:projectref="projectref"
|
||||||
|
/>
|
||||||
|
|
||||||
<div class="mb-8">
|
<div class="mb-8">
|
||||||
<span class="text-3xl">{{ projectName() }}</span>
|
<span class="text-3xl">{{ projectName() }}</span>
|
||||||
|
@ -17,7 +21,13 @@
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
:class="[{ 'tab-element-selected': $route.name.match('project runs') || $route.name.endsWith('project') }]"
|
:class="[
|
||||||
|
{
|
||||||
|
'tab-element-selected':
|
||||||
|
$route.name.match('project runs') ||
|
||||||
|
$route.name.endsWith('project'),
|
||||||
|
},
|
||||||
|
]"
|
||||||
>
|
>
|
||||||
<router-link :to="projectRunsLink(ownertype, ownername, projectref)">
|
<router-link :to="projectRunsLink(ownertype, ownername, projectref)">
|
||||||
<i class="mr-1 mdi mdi-asterisk" />
|
<i class="mr-1 mdi mdi-asterisk" />
|
||||||
|
@ -26,42 +36,81 @@
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
:class="[{ 'tab-element-selected': $route.name.match('project branches runs') }]"
|
:class="[
|
||||||
|
{
|
||||||
|
'tab-element-selected': $route.name.match(
|
||||||
|
'project branches runs'
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
:to="projectBranchesRunsLink(ownertype, ownername, projectref)"
|
||||||
>
|
>
|
||||||
<router-link :to="projectBranchesRunsLink(ownertype, ownername, projectref)">
|
|
||||||
<i class="mr-1 mdi mdi-source-branch" />
|
<i class="mr-1 mdi mdi-source-branch" />
|
||||||
<span>Branches</span>
|
<span>Branches</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
:class="[{ 'tab-element-selected': $route.name.match('project tags runs') }]"
|
:class="[
|
||||||
|
{ 'tab-element-selected': $route.name.match('project tags runs') },
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
:to="projectTagsRunsLink(ownertype, ownername, projectref)"
|
||||||
>
|
>
|
||||||
<router-link :to="projectTagsRunsLink(ownertype, ownername, projectref)">
|
|
||||||
<i class="mr-1 mdi mdi-tag" />
|
<i class="mr-1 mdi mdi-tag" />
|
||||||
<span>Tags</span>
|
<span>Tags</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
:class="[{ 'tab-element-selected': $route.name.match('project pull requests runs') }]"
|
:class="[
|
||||||
|
{
|
||||||
|
'tab-element-selected': $route.name.match(
|
||||||
|
'project pull requests runs'
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
:to="projectPRsRunsLink(ownertype, ownername, projectref)"
|
||||||
>
|
>
|
||||||
<router-link :to="projectPRsRunsLink(ownertype, ownername, projectref)">
|
|
||||||
<i class="mr-1 mdi mdi-source-pull" />
|
<i class="mr-1 mdi mdi-source-pull" />
|
||||||
<span>Pull Requests</span>
|
<span>Pull Requests</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
v-if="run && ($route.name.endsWith('project run') || $route.name.endsWith('project run task'))"
|
v-if="
|
||||||
|
run &&
|
||||||
|
($route.name.endsWith('project run') ||
|
||||||
|
$route.name.endsWith('project run task'))
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<tabarrow />
|
<tabarrow />
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
v-if="run && ($route.name.endsWith('project run') || $route.name.endsWith('project run task'))"
|
v-if="
|
||||||
:class="[{ 'tab-element-selected': $route.name.endsWith('project run') }]"
|
run &&
|
||||||
|
($route.name.endsWith('project run') ||
|
||||||
|
$route.name.endsWith('project run task'))
|
||||||
|
"
|
||||||
|
:class="[
|
||||||
|
{ 'tab-element-selected': $route.name.endsWith('project run') },
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
:to="
|
||||||
|
projectRunLink(
|
||||||
|
ownertype,
|
||||||
|
ownername,
|
||||||
|
projectref,
|
||||||
|
$route.params.runid
|
||||||
|
)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<router-link :to="projectRunLink(ownertype, ownername, projectref, $route.params.runid)">
|
|
||||||
<p>
|
<p>
|
||||||
Run
|
Run
|
||||||
<strong>#{{ run.counter }}</strong>
|
<strong>#{{ run.counter }}</strong>
|
||||||
|
@ -74,10 +123,22 @@
|
||||||
<li
|
<li
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
v-if="run && $route.name.endsWith('project run task')"
|
v-if="run && $route.name.endsWith('project run task')"
|
||||||
:class="[{ 'tab-element-selected': $route.name.endsWith('project run task') }]"
|
:class="[
|
||||||
|
{
|
||||||
|
'tab-element-selected': $route.name.endsWith('project run task'),
|
||||||
|
},
|
||||||
|
]"
|
||||||
>
|
>
|
||||||
<router-link
|
<router-link
|
||||||
:to="projectRunTaskLink(ownertype, ownername, projectref, $route.params.runid, $route.params.taskid)"
|
:to="
|
||||||
|
projectRunTaskLink(
|
||||||
|
ownertype,
|
||||||
|
ownername,
|
||||||
|
projectref,
|
||||||
|
$route.params.runid,
|
||||||
|
$route.params.taskid
|
||||||
|
)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<p>
|
<p>
|
||||||
Task
|
Task
|
||||||
|
@ -88,9 +149,15 @@
|
||||||
<li
|
<li
|
||||||
v-if="$route.name.endsWith('project settings')"
|
v-if="$route.name.endsWith('project settings')"
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
:class="[{ 'tab-element-selected': $route.name.endsWith('project settings') }]"
|
:class="[
|
||||||
|
{
|
||||||
|
'tab-element-selected': $route.name.endsWith('project settings'),
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
:to="projectSettingsLink(ownertype, ownername, projectref)"
|
||||||
>
|
>
|
||||||
<router-link :to="projectSettingsLink(ownertype, ownername, projectref)">
|
|
||||||
<i class="mr-1 mdi mdi-settings" />
|
<i class="mr-1 mdi mdi-settings" />
|
||||||
<span>Project Settings</span>
|
<span>Project Settings</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
@ -101,7 +168,7 @@
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<div
|
<div
|
||||||
class="flex -mt-3"
|
class="flex -mt-3"
|
||||||
v-click-outside="() => dropdownActive = false"
|
v-click-outside="() => (dropdownActive = false)"
|
||||||
@click="dropdownActive = !dropdownActive"
|
@click="dropdownActive = !dropdownActive"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
|
@ -135,9 +202,8 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as vClickOutside from "v-click-outside-x";
|
import * as vClickOutside from 'v-click-outside-x';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
projectLink,
|
projectLink,
|
||||||
|
@ -147,31 +213,31 @@ import {
|
||||||
projectPRsRunsLink,
|
projectPRsRunsLink,
|
||||||
projectRunLink,
|
projectRunLink,
|
||||||
projectRunTaskLink,
|
projectRunTaskLink,
|
||||||
projectSettingsLink
|
projectSettingsLink,
|
||||||
} from "@/util/link.js";
|
} from '@/util/link.js';
|
||||||
|
|
||||||
import { fetchRun } from "@/util/data.js";
|
import { fetchRun } from '@/util/data.js';
|
||||||
|
|
||||||
import projbreadcrumbs from "@/components/projbreadcrumbs.vue";
|
import projbreadcrumbs from '@/components/projbreadcrumbs.vue';
|
||||||
import tabarrow from "@/components/tabarrow.vue";
|
import tabarrow from '@/components/tabarrow.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Project",
|
name: 'Project',
|
||||||
components: { projbreadcrumbs, tabarrow },
|
components: { projbreadcrumbs, tabarrow },
|
||||||
directives: {
|
directives: {
|
||||||
clickOutside: vClickOutside.directive
|
clickOutside: vClickOutside.directive,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
ownertype: String,
|
ownertype: String,
|
||||||
ownername: String,
|
ownername: String,
|
||||||
projectref: Array
|
projectref: Array,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
fetchAbort: null,
|
fetchAbort: null,
|
||||||
|
|
||||||
dropdownActive: false,
|
dropdownActive: false,
|
||||||
run: null
|
run: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -191,12 +257,12 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.run = data;
|
this.run = data;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
projectLink: projectLink,
|
projectLink: projectLink,
|
||||||
|
@ -209,7 +275,7 @@ export default {
|
||||||
projectSettingsLink: projectSettingsLink,
|
projectSettingsLink: projectSettingsLink,
|
||||||
projectName() {
|
projectName() {
|
||||||
return this.projectref[this.projectref.length - 1];
|
return this.projectref[this.projectref.length - 1];
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created: async function () {
|
created: async function () {
|
||||||
this.fetchAbort = new AbortController();
|
this.fetchAbort = new AbortController();
|
||||||
|
@ -223,7 +289,7 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.run = data;
|
this.run = data;
|
||||||
|
@ -233,9 +299,8 @@ export default {
|
||||||
if (this.fetchAbort) {
|
if (this.fetchAbort) {
|
||||||
this.fetchAbort.abort();
|
this.fetchAbort.abort();
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<projbreadcrumbs
|
<projbreadcrumbs
|
||||||
|
@ -16,9 +15,19 @@
|
||||||
<ul class="flex-grow tab">
|
<ul class="flex-grow tab">
|
||||||
<li
|
<li
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
:class="[{ 'tab-element-selected': $route.name.match('project group project') || $route.name.endsWith('project group') }]"
|
:class="[
|
||||||
|
{
|
||||||
|
'tab-element-selected':
|
||||||
|
$route.name.match('project group project') ||
|
||||||
|
$route.name.endsWith('project group'),
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
:to="
|
||||||
|
projectGroupProjectsLink(ownertype, ownername, projectgroupref)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<router-link :to="projectGroupProjectsLink(ownertype, ownername, projectgroupref)">
|
|
||||||
<i class="mdi mdi-home" />
|
<i class="mdi mdi-home" />
|
||||||
<span>Projects</span>
|
<span>Projects</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
@ -26,9 +35,19 @@
|
||||||
<li
|
<li
|
||||||
v-if="$route.name.endsWith('project group settings')"
|
v-if="$route.name.endsWith('project group settings')"
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
:class="[{ 'tab-element-selected': $route.name.endsWith('project group settings') }]"
|
:class="[
|
||||||
|
{
|
||||||
|
'tab-element-selected': $route.name.endsWith(
|
||||||
|
'project group settings'
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
:to="
|
||||||
|
projectGroupSettingsLink(ownertype, ownername, projectgroupref)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<router-link :to="projectGroupSettingsLink(ownertype, ownername, projectgroupref)">
|
|
||||||
<i class="mdi mdi-settings" />
|
<i class="mdi mdi-settings" />
|
||||||
<span>Project Group Settings</span>
|
<span>Project Group Settings</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
@ -39,7 +58,7 @@
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<div
|
<div
|
||||||
class="flex -mt-3"
|
class="flex -mt-3"
|
||||||
v-click-outside="() => dropdownActive = false"
|
v-click-outside="() => (dropdownActive = false)"
|
||||||
@click="dropdownActive = !dropdownActive"
|
@click="dropdownActive = !dropdownActive"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
|
@ -57,7 +76,13 @@
|
||||||
<li>
|
<li>
|
||||||
<router-link
|
<router-link
|
||||||
class="block px-4 py-2 hover:bg-blue-500 hover:text-white"
|
class="block px-4 py-2 hover:bg-blue-500 hover:text-white"
|
||||||
:to="projectGroupSettingsLink(ownertype, ownername, projectgroupref)"
|
:to="
|
||||||
|
projectGroupSettingsLink(
|
||||||
|
ownertype,
|
||||||
|
ownername,
|
||||||
|
projectgroupref
|
||||||
|
)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<i class="mdi mdi-settings" />
|
<i class="mdi mdi-settings" />
|
||||||
<span>Project Group Settings</span>
|
<span>Project Group Settings</span>
|
||||||
|
@ -73,34 +98,33 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as vClickOutside from "v-click-outside-x";
|
import * as vClickOutside from 'v-click-outside-x';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
projectGroupProjectsLink,
|
projectGroupProjectsLink,
|
||||||
projectGroupSettingsLink,
|
projectGroupSettingsLink,
|
||||||
projectGroupCreateProjectGroupLink,
|
projectGroupCreateProjectGroupLink,
|
||||||
projectGroupCreateProjectLink
|
projectGroupCreateProjectLink,
|
||||||
} from "@/util/link.js";
|
} from '@/util/link.js';
|
||||||
|
|
||||||
import projbreadcrumbs from "@/components/projbreadcrumbs.vue";
|
import projbreadcrumbs from '@/components/projbreadcrumbs.vue';
|
||||||
import createprojectbutton from "@/components/createprojectbutton.vue";
|
import createprojectbutton from '@/components/createprojectbutton.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ProjectGroup",
|
name: 'ProjectGroup',
|
||||||
components: { projbreadcrumbs, createprojectbutton },
|
components: { projbreadcrumbs, createprojectbutton },
|
||||||
directives: {
|
directives: {
|
||||||
clickOutside: vClickOutside.directive
|
clickOutside: vClickOutside.directive,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
ownertype: String,
|
ownertype: String,
|
||||||
ownername: String,
|
ownername: String,
|
||||||
projectgroupref: Array
|
projectgroupref: Array,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
dropdownActive: false
|
dropdownActive: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -110,12 +134,12 @@ export default {
|
||||||
projectGroupCreateProjectLink: projectGroupCreateProjectLink,
|
projectGroupCreateProjectLink: projectGroupCreateProjectLink,
|
||||||
projectGroupName() {
|
projectGroupName() {
|
||||||
if (!this.projectgroupref.length) {
|
if (!this.projectgroupref.length) {
|
||||||
return "Root Project Group";
|
return 'Root Project Group';
|
||||||
}
|
}
|
||||||
return this.projectgroupref[this.projectgroupref.length - 1];
|
return this.projectgroupref[this.projectgroupref.length - 1];
|
||||||
},
|
},
|
||||||
goToCreate(type) {
|
goToCreate(type) {
|
||||||
if (type == "project") {
|
if (type == 'project') {
|
||||||
this.$router.push(
|
this.$router.push(
|
||||||
projectGroupCreateProjectLink(
|
projectGroupCreateProjectLink(
|
||||||
this.ownertype,
|
this.ownertype,
|
||||||
|
@ -132,10 +156,9 @@ export default {
|
||||||
this.projectgroupref
|
this.projectgroupref
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
|
@ -28,13 +28,8 @@
|
||||||
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
||||||
>
|
>
|
||||||
No remote sources defined
|
No remote sources defined
|
||||||
<router-link
|
<router-link class="underline text-blue-600 block" to="/newsource">
|
||||||
class="underline text-blue-600 block"
|
<button class="btn btn-blue">Create one</button>
|
||||||
to="/newsource"
|
|
||||||
>
|
|
||||||
<button class="btn btn-blue">
|
|
||||||
Create one
|
|
||||||
</button>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -75,29 +70,29 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters } from "vuex";
|
import { mapGetters } from 'vuex';
|
||||||
|
|
||||||
import LoginForm from "@/components/loginform";
|
import LoginForm from '@/components/loginform';
|
||||||
import RegisterForm from "@/components/registerform";
|
import RegisterForm from '@/components/registerform';
|
||||||
|
|
||||||
import { fetchRemoteSources, register } from "@/util/data";
|
import { fetchRemoteSources, register } from '@/util/data';
|
||||||
|
|
||||||
import { authorizeurl, fetch, doLogout } from "@/util/auth";
|
import { authorizeurl, fetch, doLogout } from '@/util/auth';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Register",
|
name: 'Register',
|
||||||
components: {
|
components: {
|
||||||
LoginForm,
|
LoginForm,
|
||||||
RegisterForm
|
RegisterForm,
|
||||||
},
|
},
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
error: null,
|
error: null,
|
||||||
remotesources: null
|
remotesources: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(["registeruser"]),
|
...mapGetters(['registeruser']),
|
||||||
|
|
||||||
hasRemoteSources() {
|
hasRemoteSources() {
|
||||||
if (this.remotesources) {
|
if (this.remotesources) {
|
||||||
|
@ -112,13 +107,13 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async fetchRemoteSources() {
|
async fetchRemoteSources() {
|
||||||
let { data, error } = await fetchRemoteSources();
|
let { data, error } = await fetchRemoteSources();
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.remotesources = data;
|
this.remotesources = data;
|
||||||
|
@ -127,12 +122,12 @@ export default {
|
||||||
let u = authorizeurl();
|
let u = authorizeurl();
|
||||||
let res = await (
|
let res = await (
|
||||||
await fetch(u, {
|
await fetch(u, {
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
remote_source_name: remotesourcename,
|
remote_source_name: remotesourcename,
|
||||||
login_name: username,
|
login_name: username,
|
||||||
password: password
|
password: password,
|
||||||
})
|
}),
|
||||||
})
|
})
|
||||||
).json();
|
).json();
|
||||||
|
|
||||||
|
@ -140,11 +135,11 @@ export default {
|
||||||
window.location = res.oauth2_redirect;
|
window.location = res.oauth2_redirect;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.$store.dispatch("setRegisterUser", {
|
this.$store.dispatch('setRegisterUser', {
|
||||||
remote_user_info: res.remote_user_info,
|
remote_user_info: res.remote_user_info,
|
||||||
remote_source_name: res.remote_source_name,
|
remote_source_name: res.remote_source_name,
|
||||||
remote_source_login_name: username,
|
remote_source_login_name: username,
|
||||||
remote_source_login_password: password
|
remote_source_login_password: password,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
async doRegister(
|
async doRegister(
|
||||||
|
@ -170,18 +165,15 @@ export default {
|
||||||
window.location = data.oauth2_redirect;
|
window.location = data.oauth2_redirect;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.$router.push({ name: "home" });
|
this.$router.push({ name: 'home' });
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
mounted: function () {
|
mounted: function () {
|
||||||
this.$store.dispatch("setError", null);
|
this.$store.dispatch('setError', null);
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
doLogout();
|
doLogout();
|
||||||
this.fetchRemoteSources();
|
this.fetchRemoteSources();
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,9 @@
|
||||||
<span class="mx-2">/</span>
|
<span class="mx-2">/</span>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<router-link :to="ownerLink('user', username)">{{username}}</router-link>
|
<router-link :to="ownerLink('user', username)">{{
|
||||||
|
username
|
||||||
|
}}</router-link>
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
</nav>
|
</nav>
|
||||||
|
@ -23,7 +25,12 @@
|
||||||
<ul class="flex-grow tab">
|
<ul class="flex-grow tab">
|
||||||
<li
|
<li
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
:class="[{ 'tab-element-selected': $route.name === 'user projects' || $route.name === 'user' }]"
|
:class="[
|
||||||
|
{
|
||||||
|
'tab-element-selected':
|
||||||
|
$route.name === 'user projects' || $route.name === 'user',
|
||||||
|
},
|
||||||
|
]"
|
||||||
>
|
>
|
||||||
<router-link :to="ownerProjectsLink('user', username)">
|
<router-link :to="ownerProjectsLink('user', username)">
|
||||||
<i class="mr-1 mdi mdi-home" />
|
<i class="mr-1 mdi mdi-home" />
|
||||||
|
@ -32,7 +39,9 @@
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
:class="[{ 'tab-element-selected': $route.name === 'user direct runs' }]"
|
:class="[
|
||||||
|
{ 'tab-element-selected': $route.name === 'user direct runs' },
|
||||||
|
]"
|
||||||
>
|
>
|
||||||
<router-link :to="userDirectRunsLink(username)">
|
<router-link :to="userDirectRunsLink(username)">
|
||||||
<i class="mr-1 mdi mdi-run-fast" />
|
<i class="mr-1 mdi mdi-run-fast" />
|
||||||
|
@ -40,14 +49,24 @@
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
v-if="run && ($route.name === 'user direct run' || $route.name == 'user direct run task')"
|
v-if="
|
||||||
|
run &&
|
||||||
|
($route.name === 'user direct run' ||
|
||||||
|
$route.name == 'user direct run task')
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<tabarrow />
|
<tabarrow />
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
v-if="run && ($route.name === 'user direct run' || $route.name == 'user direct run task')"
|
v-if="
|
||||||
:class="[{ 'tab-element-selected': $route.name === 'user direct run' }]"
|
run &&
|
||||||
|
($route.name === 'user direct run' ||
|
||||||
|
$route.name == 'user direct run task')
|
||||||
|
"
|
||||||
|
:class="[
|
||||||
|
{ 'tab-element-selected': $route.name === 'user direct run' },
|
||||||
|
]"
|
||||||
>
|
>
|
||||||
<router-link :to="userDirectRunLink(username, $route.params.runid)">
|
<router-link :to="userDirectRunLink(username, $route.params.runid)">
|
||||||
<span>
|
<span>
|
||||||
|
@ -62,10 +81,18 @@
|
||||||
<li
|
<li
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
v-if="run && $route.name == 'user direct run task'"
|
v-if="run && $route.name == 'user direct run task'"
|
||||||
:class="[{ 'tab-element-selected': $route.name === 'user direct run task' }]"
|
:class="[
|
||||||
|
{ 'tab-element-selected': $route.name === 'user direct run task' },
|
||||||
|
]"
|
||||||
>
|
>
|
||||||
<router-link
|
<router-link
|
||||||
:to="userDirectRunTaskLink(username, $route.params.runid, $route.params.taskid)"
|
:to="
|
||||||
|
userDirectRunTaskLink(
|
||||||
|
username,
|
||||||
|
$route.params.runid,
|
||||||
|
$route.params.taskid
|
||||||
|
)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
Task
|
Task
|
||||||
|
@ -76,7 +103,13 @@
|
||||||
<li
|
<li
|
||||||
v-if="$route.name.endsWith('user project group settings')"
|
v-if="$route.name.endsWith('user project group settings')"
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
:class="[{ 'tab-element-selected': $route.name.endsWith('user project group settings') }]"
|
:class="[
|
||||||
|
{
|
||||||
|
'tab-element-selected': $route.name.endsWith(
|
||||||
|
'user project group settings'
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]"
|
||||||
>
|
>
|
||||||
<router-link :to="projectGroupSettingsLink('user', username, [])">
|
<router-link :to="projectGroupSettingsLink('user', username, [])">
|
||||||
<i class="mr-1 mdi mdi-settings" />
|
<i class="mr-1 mdi mdi-settings" />
|
||||||
|
@ -86,7 +119,9 @@
|
||||||
<li
|
<li
|
||||||
v-if="$route.name.endsWith('user settings')"
|
v-if="$route.name.endsWith('user settings')"
|
||||||
class="tab-element"
|
class="tab-element"
|
||||||
:class="[{ 'tab-element-selected': $route.name.endsWith('user settings') }]"
|
:class="[
|
||||||
|
{ 'tab-element-selected': $route.name.endsWith('user settings') },
|
||||||
|
]"
|
||||||
>
|
>
|
||||||
<router-link :to="ownerSettingsLink('user', username)">
|
<router-link :to="ownerSettingsLink('user', username)">
|
||||||
<i class="mr-1 mdi mdi-settings" />
|
<i class="mr-1 mdi mdi-settings" />
|
||||||
|
@ -99,7 +134,7 @@
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<div
|
<div
|
||||||
class="flex -mt-3"
|
class="flex -mt-3"
|
||||||
v-click-outside="() => dropdownActive = false"
|
v-click-outside="() => (dropdownActive = false)"
|
||||||
@click="dropdownActive = !dropdownActive"
|
@click="dropdownActive = !dropdownActive"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
|
@ -134,7 +169,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as vClickOutside from "v-click-outside-x";
|
import * as vClickOutside from 'v-click-outside-x';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ownerLink,
|
ownerLink,
|
||||||
|
@ -145,29 +180,29 @@ import {
|
||||||
ownerSettingsLink,
|
ownerSettingsLink,
|
||||||
projectGroupCreateProjectGroupLink,
|
projectGroupCreateProjectGroupLink,
|
||||||
projectGroupCreateProjectLink,
|
projectGroupCreateProjectLink,
|
||||||
projectGroupSettingsLink
|
projectGroupSettingsLink,
|
||||||
} from "@/util/link.js";
|
} from '@/util/link.js';
|
||||||
|
|
||||||
import { fetchRun } from "@/util/data.js";
|
import { fetchRun } from '@/util/data.js';
|
||||||
|
|
||||||
import createprojectbutton from "@/components/createprojectbutton.vue";
|
import createprojectbutton from '@/components/createprojectbutton.vue';
|
||||||
import tabarrow from "@/components/tabarrow.vue";
|
import tabarrow from '@/components/tabarrow.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "User",
|
name: 'User',
|
||||||
components: { createprojectbutton, tabarrow },
|
components: { createprojectbutton, tabarrow },
|
||||||
directives: {
|
directives: {
|
||||||
clickOutside: vClickOutside.directive
|
clickOutside: vClickOutside.directive,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
username: String
|
username: String,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
fetchAbort: null,
|
fetchAbort: null,
|
||||||
|
|
||||||
dropdownActive: false,
|
dropdownActive: false,
|
||||||
run: null
|
run: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -187,12 +222,12 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.run = data;
|
this.run = data;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
ownerLink: ownerLink,
|
ownerLink: ownerLink,
|
||||||
|
@ -205,16 +240,16 @@ export default {
|
||||||
projectGroupCreateProjectLink: projectGroupCreateProjectLink,
|
projectGroupCreateProjectLink: projectGroupCreateProjectLink,
|
||||||
projectGroupSettingsLink: projectGroupSettingsLink,
|
projectGroupSettingsLink: projectGroupSettingsLink,
|
||||||
goToCreate(type) {
|
goToCreate(type) {
|
||||||
if (type == "project") {
|
if (type == 'project') {
|
||||||
this.$router.push(
|
this.$router.push(
|
||||||
projectGroupCreateProjectLink("user", this.username, [])
|
projectGroupCreateProjectLink('user', this.username, [])
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.$router.push(
|
this.$router.push(
|
||||||
projectGroupCreateProjectGroupLink("user", this.username, [])
|
projectGroupCreateProjectGroupLink('user', this.username, [])
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created: async function () {
|
created: async function () {
|
||||||
this.fetchAbort = new AbortController();
|
this.fetchAbort = new AbortController();
|
||||||
|
@ -228,7 +263,7 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch('setError', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.run = data;
|
this.run = data;
|
||||||
|
@ -238,9 +273,8 @@ export default {
|
||||||
if (this.fetchAbort) {
|
if (this.fetchAbort) {
|
||||||
this.fetchAbort.abort();
|
this.fetchAbort.abort();
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|
75
tailwind.js
75
tailwind.js
|
@ -6,43 +6,54 @@ module.exports = {
|
||||||
padding: '2rem',
|
padding: '2rem',
|
||||||
},
|
},
|
||||||
fontFamily: {
|
fontFamily: {
|
||||||
'sans': ['Segoe UI', 'Roboto', 'Helvetica Neue', 'Arial', 'Noto Sans', 'sans-serif', 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji']
|
sans: [
|
||||||
|
'Segoe UI',
|
||||||
|
'Roboto',
|
||||||
|
'Helvetica Neue',
|
||||||
|
'Arial',
|
||||||
|
'Noto Sans',
|
||||||
|
'sans-serif',
|
||||||
|
'Apple Color Emoji',
|
||||||
|
'Segoe UI Emoji',
|
||||||
|
'Segoe UI Symbol',
|
||||||
|
'Noto Color Emoji',
|
||||||
|
],
|
||||||
},
|
},
|
||||||
borderWidth: {
|
borderWidth: {
|
||||||
default: '1px',
|
default: '1px',
|
||||||
'0': '0',
|
0: '0',
|
||||||
'2': '2px',
|
2: '2px',
|
||||||
'4': '4px',
|
4: '4px',
|
||||||
'5': '5px',
|
5: '5px',
|
||||||
'6': '6px',
|
6: '6px',
|
||||||
},
|
},
|
||||||
spacing: {
|
spacing: {
|
||||||
px: '1px',
|
px: '1px',
|
||||||
'2px': '2px',
|
'2px': '2px',
|
||||||
'3px': '3px',
|
'3px': '3px',
|
||||||
'0': '0',
|
0: '0',
|
||||||
'1': '0.25rem',
|
1: '0.25rem',
|
||||||
'2': '0.5rem',
|
2: '0.5rem',
|
||||||
'3': '0.75rem',
|
3: '0.75rem',
|
||||||
'4': '1rem',
|
4: '1rem',
|
||||||
'5': '1.25rem',
|
5: '1.25rem',
|
||||||
'6': '1.5rem',
|
6: '1.5rem',
|
||||||
'8': '2rem',
|
8: '2rem',
|
||||||
'10': '2.5rem',
|
10: '2.5rem',
|
||||||
'12': '3rem',
|
12: '3rem',
|
||||||
'16': '4rem',
|
16: '4rem',
|
||||||
'20': '5rem',
|
20: '5rem',
|
||||||
'24': '6rem',
|
24: '6rem',
|
||||||
'32': '8rem',
|
32: '8rem',
|
||||||
'40': '10rem',
|
40: '10rem',
|
||||||
'48': '12rem',
|
48: '12rem',
|
||||||
'56': '14rem',
|
56: '14rem',
|
||||||
'64': '16rem',
|
64: '16rem',
|
||||||
},
|
},
|
||||||
colors: {
|
colors: {
|
||||||
dark: '#4a4a4a',
|
dark: '#4a4a4a',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
variants: {
|
variants: {
|
||||||
backgroundColor: ['responsive', 'hover', 'focus', 'disabled'],
|
backgroundColor: ['responsive', 'hover', 'focus', 'disabled'],
|
||||||
|
@ -56,9 +67,9 @@ module.exports = {
|
||||||
function ({ addVariant, e }) {
|
function ({ addVariant, e }) {
|
||||||
addVariant('disabled', ({ modifySelectors, separator }) => {
|
addVariant('disabled', ({ modifySelectors, separator }) => {
|
||||||
modifySelectors(({ className }) => {
|
modifySelectors(({ className }) => {
|
||||||
return `.${e(`disabled${separator}${className}`)}:disabled`
|
return `.${e(`disabled${separator}${className}`)}:disabled`;
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const path = require("path");
|
const path = require('path');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
css: {
|
css: {
|
||||||
sourceMap: true
|
sourceMap: true,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue