createproject: improve remote repos selection
Use a select to choose the remote source and fetch remote repos only for that remote source
This commit is contained in:
parent
5b13083861
commit
26d5247846
|
@ -15,27 +15,49 @@
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h4 class="text-xl">Available remote repositories</h4>
|
<div class="mb-3 flex items-center">
|
||||||
<div v-for="remoteSource in remoteSources" v-bind:key="remoteSource.id">
|
<div class="flex relative w-64">
|
||||||
<remoterepos
|
<select
|
||||||
class="remoterepos"
|
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"
|
||||||
:remotesource="remoteSource"
|
v-model="selectedRemoteSourceIndex"
|
||||||
:selected="selectedRemoteSource && selectedRemoteSource.id == remoteSource.id"
|
>
|
||||||
v-on:reposelected="repoSelected(remoteSource, $event)"
|
<option :value="null" disabled>Select the remote source</option>
|
||||||
/>
|
<option
|
||||||
|
v-for="(rs, index) in remoteSources"
|
||||||
|
v-bind:key="rs.id"
|
||||||
|
:value="index"
|
||||||
|
>{{ rs.name }}</option>
|
||||||
|
</select>
|
||||||
|
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2">
|
||||||
|
<svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
|
||||||
|
<path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
class="ml-3 btn btn-blue"
|
||||||
|
v-bind:class="{ 'spinner': fetchRemoteReposLoading }"
|
||||||
|
:disabled="selectedRemoteSourceIndex == null"
|
||||||
|
@click="fetchRemoteRepos()"
|
||||||
|
>Fetch remote repositories</button>
|
||||||
</div>
|
</div>
|
||||||
<button
|
|
||||||
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
|
<div v-if="remoteRepos.length">
|
||||||
v-bind:class="{ 'spinner': createProjectLoading }"
|
<h4 class="text-xl">Available remote repositories</h4>
|
||||||
:disabled="!createProjectButtonEnabled"
|
<remoterepos :remoterepos="remoteRepos" v-on:reposelected="repoSelected($event)"/>
|
||||||
@click="createProject()"
|
<button
|
||||||
>Create Project</button>
|
class="btn btn-blue"
|
||||||
<div
|
v-bind:class="{ 'spinner': createProjectLoading }"
|
||||||
v-if="createProjectError"
|
:disabled="!createProjectButtonEnabled"
|
||||||
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
@click="createProject()"
|
||||||
role="alert"
|
>Create Project</button>
|
||||||
>
|
<div
|
||||||
<span class="block sm:inline">{{ createProjectError }}</span>
|
v-if="createProjectError"
|
||||||
|
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
||||||
|
role="alert"
|
||||||
|
>
|
||||||
|
<span class="block sm:inline">{{ createProjectError }}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -44,7 +66,8 @@
|
||||||
import {
|
import {
|
||||||
fetchCurrentUser,
|
fetchCurrentUser,
|
||||||
fetchRemoteSources,
|
fetchRemoteSources,
|
||||||
createProject
|
createProject,
|
||||||
|
userRemoteRepos
|
||||||
} from "@/util/data.js";
|
} from "@/util/data.js";
|
||||||
|
|
||||||
import { projectLink } from "@/util/link.js";
|
import { projectLink } from "@/util/link.js";
|
||||||
|
@ -62,26 +85,38 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
createProjectError: null,
|
createProjectError: null,
|
||||||
|
fetchRemoteReposLoading: false,
|
||||||
|
fetchRemoteReposLoadingTimeout: false,
|
||||||
createProjectLoading: false,
|
createProjectLoading: false,
|
||||||
createProjectLoadingTimeout: null,
|
createProjectLoadingTimeout: null,
|
||||||
user: null,
|
user: null,
|
||||||
remoteSources: null,
|
remoteSources: null,
|
||||||
remoteRepos: [],
|
remoteRepos: [],
|
||||||
|
selectedRemoteSourceIndex: null,
|
||||||
projectName: "",
|
projectName: "",
|
||||||
projectIsPrivate: false,
|
projectIsPrivate: false,
|
||||||
remoteRepoPath: null,
|
remoteRepoPath: null
|
||||||
selectedRemoteSource: null
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
createProjectButtonEnabled: function() {
|
createProjectButtonEnabled: function() {
|
||||||
return this.projectName.length && this.selectedRemoteSource;
|
return this.projectName.length && this.remoteRepoPath;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
watch: {},
|
||||||
methods: {
|
methods: {
|
||||||
resetErrors() {
|
resetErrors() {
|
||||||
this.createProjectError = null;
|
this.createProjectError = null;
|
||||||
},
|
},
|
||||||
|
startFetchRemoteReposLoading() {
|
||||||
|
this.fetchRemoteReposLoadingTimeout = setTimeout(() => {
|
||||||
|
this.fetchRemoteReposLoading = true;
|
||||||
|
}, 300);
|
||||||
|
},
|
||||||
|
stopFetchRemoteReposLoading() {
|
||||||
|
clearTimeout(this.fetchRemoteReposLoadingTimeout);
|
||||||
|
this.fetchRemoteReposLoading = false;
|
||||||
|
},
|
||||||
startProjectLoading() {
|
startProjectLoading() {
|
||||||
this.createProjectLoadingTimeout = setTimeout(() => {
|
this.createProjectLoadingTimeout = setTimeout(() => {
|
||||||
this.createProjectLoading = true;
|
this.createProjectLoading = true;
|
||||||
|
@ -91,10 +126,23 @@ export default {
|
||||||
clearTimeout(this.createProjectLoadingTimeout);
|
clearTimeout(this.createProjectLoadingTimeout);
|
||||||
this.createProjectLoading = false;
|
this.createProjectLoading = false;
|
||||||
},
|
},
|
||||||
repoSelected(remoteSource, repoPath) {
|
repoSelected(repoPath) {
|
||||||
this.selectedRemoteSource = remoteSource;
|
|
||||||
this.remoteRepoPath = repoPath;
|
this.remoteRepoPath = repoPath;
|
||||||
},
|
},
|
||||||
|
async fetchRemoteRepos() {
|
||||||
|
this.remoteRepos = [];
|
||||||
|
this.remoteRepoPath = null;
|
||||||
|
|
||||||
|
this.startFetchRemoteReposLoading();
|
||||||
|
let remoteSource = this.remoteSources[this.selectedRemoteSourceIndex];
|
||||||
|
let { data, error } = await userRemoteRepos(remoteSource.id);
|
||||||
|
this.stopFetchRemoteReposLoading();
|
||||||
|
if (error) {
|
||||||
|
this.$store.dispatch("setError", error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.remoteRepos = data;
|
||||||
|
},
|
||||||
async createProject() {
|
async createProject() {
|
||||||
this.resetErrors();
|
this.resetErrors();
|
||||||
|
|
||||||
|
@ -109,12 +157,14 @@ export default {
|
||||||
visibility = "private";
|
visibility = "private";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let remoteSource = this.remoteSources[this.selectedRemoteSourceIndex];
|
||||||
|
|
||||||
this.startProjectLoading();
|
this.startProjectLoading();
|
||||||
let { error } = await createProject(
|
let { error } = await createProject(
|
||||||
parentref,
|
parentref,
|
||||||
this.projectName,
|
this.projectName,
|
||||||
visibility,
|
visibility,
|
||||||
this.selectedRemoteSource.name,
|
remoteSource.name,
|
||||||
this.remoteRepoPath
|
this.remoteRepoPath
|
||||||
);
|
);
|
||||||
this.stopProjectLoading();
|
this.stopProjectLoading();
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="mb-2 border-solid border-gray-300 rounded border shadow-sm">
|
<div class="mb-2 border-solid border-gray-300 rounded border shadow-sm">
|
||||||
<p class="bg-gray-200 px-4 py-3 border-solid border-gray-300 border-b">
|
|
||||||
repositories from
|
|
||||||
<strong>{{ remotesource.name }}</strong>
|
|
||||||
</p>
|
|
||||||
<div v-if="remoterepos.length > 0">
|
<div v-if="remoterepos.length > 0">
|
||||||
<label
|
<label
|
||||||
class="block px-4 py-2 border-b"
|
class="block px-4 py-2 border-b"
|
||||||
|
@ -11,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 && selected">
|
<input type="radio" :checked="selectedrepo == index">
|
||||||
{{repo.path}}
|
{{repo.path}}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -20,37 +16,22 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { userRemoteRepos } from "@/util/data.js";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: {},
|
||||||
name: "remoterepos",
|
name: "remoterepos",
|
||||||
props: {
|
props: {
|
||||||
remotesource: Object,
|
remoterepos: Array
|
||||||
selected: Boolean
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
selectedrepo: null,
|
selectedrepo: null
|
||||||
remoterepos: []
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
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);
|
||||||
},
|
|
||||||
async fetchRemoteRepos(remotesourceid) {
|
|
||||||
let { data, error } = await userRemoteRepos(remotesourceid);
|
|
||||||
if (error) {
|
|
||||||
this.$store.dispatch("setError", error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.remoterepos = data;
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
created: function() {
|
|
||||||
this.fetchRemoteRepos(this.remotesource.id);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Reference in New Issue