mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2025-04-26 21:44:44 +00:00
Allow editing all environment variables in pipeline popups (#3314)
This commit is contained in:
parent
6785806873
commit
147137c7bb
3 changed files with 106 additions and 82 deletions
|
@ -38,7 +38,7 @@
|
||||||
"trigger": "Run pipeline",
|
"trigger": "Run pipeline",
|
||||||
"select_branch": "Select branch",
|
"select_branch": "Select branch",
|
||||||
"variables": {
|
"variables": {
|
||||||
"add": "Add variable",
|
"delete": "Delete variable",
|
||||||
"title": "Additional pipeline variables",
|
"title": "Additional pipeline variables",
|
||||||
"desc": "Specify additional variables to use in your pipeline. Variables with the same name will be overwritten.",
|
"desc": "Specify additional variables to use in your pipeline. Variables with the same name will be overwritten.",
|
||||||
"name": "Variable name",
|
"name": "Variable name",
|
||||||
|
@ -50,7 +50,7 @@
|
||||||
"enter_target": "Target deployment environment",
|
"enter_target": "Target deployment environment",
|
||||||
"trigger": "Deploy",
|
"trigger": "Deploy",
|
||||||
"variables": {
|
"variables": {
|
||||||
"add": "Add variable",
|
"delete": "Delete variable",
|
||||||
"title": "Additional pipeline variables",
|
"title": "Additional pipeline variables",
|
||||||
"desc": "Specify additional variables to use in your pipeline. Variables with the same name will be overwritten.",
|
"desc": "Specify additional variables to use in your pipeline. Variables with the same name will be overwritten.",
|
||||||
"name": "Variable name",
|
"name": "Variable name",
|
||||||
|
|
|
@ -11,35 +11,29 @@
|
||||||
<InputField v-slot="{ id }" :label="$t('repo.deploy_pipeline.variables.title')">
|
<InputField v-slot="{ id }" :label="$t('repo.deploy_pipeline.variables.title')">
|
||||||
<span class="text-sm text-wp-text-alt-100 mb-2">{{ $t('repo.deploy_pipeline.variables.desc') }}</span>
|
<span class="text-sm text-wp-text-alt-100 mb-2">{{ $t('repo.deploy_pipeline.variables.desc') }}</span>
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<div v-for="(value, name) in payload.variables" :key="name" class="flex gap-4">
|
<div v-for="(_, i) in payload.variables" :key="i" class="flex gap-4">
|
||||||
<TextField :id="id" :model-value="name" disabled />
|
<TextField
|
||||||
<TextField :id="id" :model-value="value" disabled />
|
:id="id"
|
||||||
<div class="w-34 flex-shrink-0">
|
v-model="payload.variables[i].name"
|
||||||
<Button color="red" class="ml-auto" @click="deleteVar(name)">
|
:placeholder="$t('repo.deploy_pipeline.variables.name')"
|
||||||
|
/>
|
||||||
|
<TextField
|
||||||
|
:id="id"
|
||||||
|
v-model="payload.variables[i].value"
|
||||||
|
:placeholder="$t('repo.deploy_pipeline.variables.value')"
|
||||||
|
/>
|
||||||
|
<div class="w-10 flex-shrink-0">
|
||||||
|
<Button
|
||||||
|
v-if="i !== payload.variables.length - 1"
|
||||||
|
color="red"
|
||||||
|
class="ml-auto"
|
||||||
|
:title="$t('repo.deploy_pipeline.variables.delete')"
|
||||||
|
@click="deleteVar(i)"
|
||||||
|
>
|
||||||
<i-la-times />
|
<i-la-times />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form class="flex gap-4" @submit.prevent="addPipelineVariable">
|
|
||||||
<TextField
|
|
||||||
:id="id"
|
|
||||||
v-model="newPipelineVariable.name"
|
|
||||||
:placeholder="$t('repo.deploy_pipeline.variables.name')"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
<TextField
|
|
||||||
:id="id"
|
|
||||||
v-model="newPipelineVariable.value"
|
|
||||||
:placeholder="$t('repo.deploy_pipeline.variables.value')"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
class="w-34 flex-shrink-0"
|
|
||||||
start-icon="plus"
|
|
||||||
type="submit"
|
|
||||||
:text="$t('repo.deploy_pipeline.variables.add')"
|
|
||||||
/>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
</InputField>
|
</InputField>
|
||||||
<Button type="submit" :text="$t('repo.deploy_pipeline.trigger')" />
|
<Button type="submit" :text="$t('repo.deploy_pipeline.trigger')" />
|
||||||
|
@ -49,7 +43,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, ref, toRef } from 'vue';
|
import { computed, onMounted, ref, toRef, watch } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
import Button from '~/components/atomic/Button.vue';
|
import Button from '~/components/atomic/Button.vue';
|
||||||
|
@ -75,35 +69,53 @@ const repo = inject('repo');
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const payload = ref<{ id: string; environment: string; variables: Record<string, string> }>({
|
const payload = ref<{ id: string; environment: string; variables: { name: string; value: string }[] }>({
|
||||||
id: '',
|
id: '',
|
||||||
environment: '',
|
environment: '',
|
||||||
variables: {},
|
variables: [
|
||||||
|
{
|
||||||
|
name: '',
|
||||||
|
value: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const pipelineOptions = computed(() => {
|
||||||
|
const variables = Object.fromEntries(
|
||||||
|
payload.value.variables.filter((e) => e.name !== '').map((item) => [item.name, item.value]),
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
...payload.value,
|
||||||
|
variables,
|
||||||
|
};
|
||||||
});
|
});
|
||||||
const newPipelineVariable = ref<{ name: string; value: string }>({ name: '', value: '' });
|
|
||||||
|
|
||||||
const loading = ref(true);
|
const loading = ref(true);
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
function addPipelineVariable() {
|
watch(
|
||||||
if (!newPipelineVariable.value.name || !newPipelineVariable.value.value) {
|
payload,
|
||||||
return;
|
() => {
|
||||||
}
|
if (payload.value.variables[payload.value.variables.length - 1].name !== '') {
|
||||||
payload.value.variables[newPipelineVariable.value.name] = newPipelineVariable.value.value;
|
payload.value.variables.push({
|
||||||
newPipelineVariable.value.name = '';
|
name: '',
|
||||||
newPipelineVariable.value.value = '';
|
value: '',
|
||||||
}
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ deep: true },
|
||||||
|
);
|
||||||
|
|
||||||
function deleteVar(key: string) {
|
function deleteVar(index: number) {
|
||||||
delete payload.value.variables[key];
|
payload.value.variables.splice(index, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const pipelineNumber = toRef(props, 'pipelineNumber');
|
const pipelineNumber = toRef(props, 'pipelineNumber');
|
||||||
async function triggerDeployPipeline() {
|
async function triggerDeployPipeline() {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
const newPipeline = await apiClient.deployPipeline(repo.value.id, pipelineNumber.value, payload.value);
|
const newPipeline = await apiClient.deployPipeline(repo.value.id, pipelineNumber.value, pipelineOptions.value);
|
||||||
|
|
||||||
emit('close');
|
emit('close');
|
||||||
|
|
||||||
|
|
|
@ -9,35 +9,29 @@
|
||||||
<InputField v-slot="{ id }" :label="$t('repo.manual_pipeline.variables.title')">
|
<InputField v-slot="{ id }" :label="$t('repo.manual_pipeline.variables.title')">
|
||||||
<span class="text-sm text-wp-text-alt-100 mb-2">{{ $t('repo.manual_pipeline.variables.desc') }}</span>
|
<span class="text-sm text-wp-text-alt-100 mb-2">{{ $t('repo.manual_pipeline.variables.desc') }}</span>
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<div v-for="(value, name) in payload.variables" :key="name" class="flex gap-4">
|
<div v-for="(_, i) in payload.variables" :key="i" class="flex gap-4">
|
||||||
<TextField :id="id" :model-value="name" disabled />
|
<TextField
|
||||||
<TextField :id="id" :model-value="value" disabled />
|
:id="id"
|
||||||
<div class="w-34 flex-shrink-0">
|
v-model="payload.variables[i].name"
|
||||||
<Button color="red" class="ml-auto" @click="deleteVar(name)">
|
:placeholder="$t('repo.manual_pipeline.variables.name')"
|
||||||
|
/>
|
||||||
|
<TextField
|
||||||
|
:id="id"
|
||||||
|
v-model="payload.variables[i].value"
|
||||||
|
:placeholder="$t('repo.manual_pipeline.variables.value')"
|
||||||
|
/>
|
||||||
|
<div class="w-10 flex-shrink-0">
|
||||||
|
<Button
|
||||||
|
v-if="i !== payload.variables.length - 1"
|
||||||
|
color="red"
|
||||||
|
class="ml-auto"
|
||||||
|
:title="$t('repo.manual_pipeline.variables.delete')"
|
||||||
|
@click="deleteVar(i)"
|
||||||
|
>
|
||||||
<i-la-times />
|
<i-la-times />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form class="flex gap-4" @submit.prevent="addPipelineVariable">
|
|
||||||
<TextField
|
|
||||||
:id="id"
|
|
||||||
v-model="newPipelineVariable.name"
|
|
||||||
:placeholder="$t('repo.manual_pipeline.variables.name')"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
<TextField
|
|
||||||
:id="id"
|
|
||||||
v-model="newPipelineVariable.value"
|
|
||||||
:placeholder="$t('repo.manual_pipeline.variables.value')"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
class="w-34 flex-shrink-0"
|
|
||||||
start-icon="plus"
|
|
||||||
type="submit"
|
|
||||||
:text="$t('repo.manual_pipeline.variables.add')"
|
|
||||||
/>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
</InputField>
|
</InputField>
|
||||||
<Button type="submit" :text="$t('repo.manual_pipeline.trigger')" />
|
<Button type="submit" :text="$t('repo.manual_pipeline.trigger')" />
|
||||||
|
@ -47,7 +41,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, ref } from 'vue';
|
import { computed, onMounted, ref, watch } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
import Button from '~/components/atomic/Button.vue';
|
import Button from '~/components/atomic/Button.vue';
|
||||||
|
@ -74,11 +68,25 @@ const repo = inject('repo');
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const branches = ref<{ text: string; value: string }[]>([]);
|
const branches = ref<{ text: string; value: string }[]>([]);
|
||||||
const payload = ref<{ branch: string; variables: Record<string, string> }>({
|
const payload = ref<{ branch: string; variables: { name: string; value: string }[] }>({
|
||||||
branch: 'main',
|
branch: 'main',
|
||||||
variables: {},
|
variables: [
|
||||||
|
{
|
||||||
|
name: '',
|
||||||
|
value: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const pipelineOptions = computed(() => {
|
||||||
|
const variables = Object.fromEntries(
|
||||||
|
payload.value.variables.filter((e) => e.name !== '').map((item) => [item.name, item.value]),
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
...payload.value,
|
||||||
|
variables,
|
||||||
|
};
|
||||||
});
|
});
|
||||||
const newPipelineVariable = ref<{ name: string; value: string }>({ name: '', value: '' });
|
|
||||||
|
|
||||||
const loading = ref(true);
|
const loading = ref(true);
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
@ -90,22 +98,26 @@ onMounted(async () => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
function addPipelineVariable() {
|
watch(
|
||||||
if (!newPipelineVariable.value.name || !newPipelineVariable.value.value) {
|
payload,
|
||||||
return;
|
() => {
|
||||||
}
|
if (payload.value.variables[payload.value.variables.length - 1].name !== '') {
|
||||||
payload.value.variables[newPipelineVariable.value.name] = newPipelineVariable.value.value;
|
payload.value.variables.push({
|
||||||
newPipelineVariable.value.name = '';
|
name: '',
|
||||||
newPipelineVariable.value.value = '';
|
value: '',
|
||||||
}
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ deep: true },
|
||||||
|
);
|
||||||
|
|
||||||
function deleteVar(key: string) {
|
function deleteVar(index: number) {
|
||||||
delete payload.value.variables[key];
|
payload.value.variables.splice(index, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function triggerManualPipeline() {
|
async function triggerManualPipeline() {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
const pipeline = await apiClient.createPipeline(repo.value.id, payload.value);
|
const pipeline = await apiClient.createPipeline(repo.value.id, pipelineOptions.value);
|
||||||
|
|
||||||
emit('close');
|
emit('close');
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue