Hide unsupported forge options (#5465)

Co-authored-by: qwerty287 <qwerty287@posteo.de>
Co-authored-by: qwerty287 <80460567+qwerty287@users.noreply.github.com>
This commit is contained in:
Robert Kaussow
2025-08-27 08:21:50 +02:00
committed by GitHub
parent 7886f4a71f
commit 1bee41ddea
3 changed files with 148 additions and 96 deletions

View File

@@ -566,10 +566,13 @@
"edit_forge": "Edit forge",
"delete_forge": "Delete forge",
"no_forges": "There are no forges yet.",
"use_this_redirect_uri_to_create": "Use this redirect URI to create or update the OAuth application. Go to {0} and setup the OAuth application.",
"developer_settings": "Developer settings",
"use_this_redirect_url_to_create": "Use this redirect URL to create or update the OAuth application.",
"developer_settings_to_create": "Go to the {0} and set up the OAuth application.",
"developer_settings": "developer settings",
"public_url_for_oauth_if": "Public URL for OAuth if different from URL ({0})",
"forge_saved": "Forge saved",
"fullscreen": "Fullscreen",
"exit_fullscreen": "Exit fullscreen"
"exit_fullscreen": "Exit fullscreen",
"help_translating": "You can help translate Woodpecker into your language on {0}.",
"weblate": "our Weblate"
}

View File

@@ -3,38 +3,28 @@
<Warning v-if="!isNew && forge.id === 1" :text="$t('forge_managed_by_env')" />
<InputField v-slot="{ id }" :label="$t('forge_type')">
<SelectField
:id="id"
v-model="forgeType"
:options="[
{ value: 'github', text: $t('github') },
{ value: 'gitlab', text: $t('gitlab') },
{ value: 'gitea', text: $t('gitea') },
{ value: 'forgejo', text: $t('forgejo') },
{ value: 'bitbucket', text: $t('bitbucket') },
{ value: 'bitbucket-dc', text: $t('bitbucket_dc') },
{ value: 'addon', text: $t('addon') },
]"
required
/>
<SelectField :id="id" v-model="forgeType" :options="forgeTypeOptions" required />
</InputField>
<InputField v-slot="{ id }" :label="$t('url')">
<InputField v-if="forge.type !== 'bitbucket'" v-slot="{ id }" :label="$t('url')">
<TextField :id="id" v-model="forge.url" required />
</InputField>
<template v-if="forge.type && forge.url">
<hr class="my-4 border-gray-800" />
<InputField v-slot="{ id }" :label="$t('oauth_redirect_url')">
<i18n-t keypath="use_this_redirect_uri_to_create" tag="p" class="mb-2">
<InputField :label="$t('oauth_redirect_url')" description="foo">
<template #default="{ id }">
<TextField :id="id" class="mt-2" :model-value="redirectUri" disabled />
</template>
<template #description>
{{ $t('use_this_redirect_url_to_create') }}
<i18n-t v-if="forge.type !== 'addon'" keypath="developer_settings_to_create" tag="span">
<a rel="noopener noreferrer" :href="oauthAppForgeUrl" target="_blank" class="underline">{{
$t('developer_settings')
}}</a>
</i18n-t>
<TextField :id="id" :model-value="redirectUri" disabled />
</InputField>
</template>
</InputField>
<template v-if="forge.type !== 'addon'">
<InputField v-slot="{ id }" :label="$t('oauth_client_id')">
<TextField :id="id" v-model="forge.client" required />
</InputField>
@@ -47,78 +37,86 @@
:required="isNew"
/>
</InputField>
</template>
<Panel collapsable collapsed-by-default :title="$t('advanced_options')" class="mb-4">
<InputField v-slot="{ id }" :label="$t('oauth_host')">
<TextField :id="id" v-model="forge.oauth_host" :placeholder="$t('public_url_for_oauth_if', [forge.url])" />
</InputField>
<template v-else>
<InputField v-slot="{ id }" :label="$t('executable')">
<p>{{ $t('executable_desc') }}</p>
<TextField
:id="id"
:model-value="getAdditionalOptions('addon', 'executable')"
@update:model-value="setAdditionalOptions('addon', 'executable', $event)"
/>
</InputField>
</template>
<template v-if="forge.type === 'github'">
<InputField :label="$t('merge_ref')">
<Checkbox
:label="$t('merge_ref_desc')"
:model-value="getAdditionalOptions('github', 'merge-ref') ?? false"
@update:model-value="setAdditionalOptions('github', 'merge-ref', $event)"
/>
</InputField>
<Panel
v-if="forge.type !== 'bitbucket'"
collapsable
collapsed-by-default
:title="$t('advanced_options')"
class="mb-4"
>
<InputField v-slot="{ id }" :label="$t('oauth_host')">
<TextField :id="id" v-model="forge.oauth_host" :placeholder="$t('public_url_for_oauth_if', [forge.url])" />
</InputField>
<InputField :label="$t('public_only')">
<Checkbox
:label="$t('public_only_desc')"
:model-value="getAdditionalOptions('github', 'public-only') ?? false"
@update:model-value="setAdditionalOptions('github', 'public-only', $event)"
/>
</InputField>
</template>
<template v-if="forge.type === 'bitbucket-dc'">
<InputField v-slot="{ id }" :label="$t('git_username')">
<p>{{ $t('git_username_desc') }}</p>
<TextField
:id="id"
:model-value="getAdditionalOptions('bitbucket-dc', 'git-username')"
@update:model-value="setAdditionalOptions('bitbucket-dc', 'git-username', $event)"
/>
</InputField>
<InputField v-slot="{ id }" :label="$t('git_password')">
<p>{{ $t('git_password_desc') }}</p>
<TextField
:id="id"
:model-value="getAdditionalOptions('bitbucket-dc', 'git-password')"
@update:model-value="setAdditionalOptions('bitbucket-dc', 'git-password', $event)"
/>
</InputField>
</template>
<template v-if="forge.type === 'addon'">
<InputField v-slot="{ id }" :label="$t('executable')">
<p>{{ $t('executable_desc') }}</p>
<TextField
:id="id"
:model-value="getAdditionalOptions('addon', 'executable')"
@update:model-value="setAdditionalOptions('addon', 'executable', $event)"
/>
</InputField>
</template>
<InputField :label="$t('skip_verify')">
<template v-if="forge.type === 'github'">
<InputField :label="$t('merge_ref')">
<Checkbox
:label="$t('skip_verify_desc')"
:model-value="forge.skip_verify || false"
@update:model-value="forge!.skip_verify = $event"
:label="$t('merge_ref_desc')"
:model-value="getAdditionalOptions('github', 'merge-ref') ?? false"
@update:model-value="setAdditionalOptions('github', 'merge-ref', $event)"
/>
</InputField>
</Panel>
<div class="flex gap-2">
<Button :text="$t('cancel')" :to="{ name: 'admin-settings-forges' }" />
<InputField :label="$t('public_only')">
<Checkbox
:label="$t('public_only_desc')"
:model-value="getAdditionalOptions('github', 'public-only') ?? false"
@update:model-value="setAdditionalOptions('github', 'public-only', $event)"
/>
</InputField>
</template>
<template v-if="forge.type === 'bitbucket-dc'">
<InputField v-slot="{ id }" :label="$t('git_username')">
<p>{{ $t('git_username_desc') }}</p>
<TextField
:id="id"
:model-value="getAdditionalOptions('bitbucket-dc', 'git-username')"
@update:model-value="setAdditionalOptions('bitbucket-dc', 'git-username', $event)"
/>
</InputField>
<InputField v-slot="{ id }" :label="$t('git_password')">
<p>{{ $t('git_password_desc') }}</p>
<TextField
:id="id"
:model-value="getAdditionalOptions('bitbucket-dc', 'git-password')"
@update:model-value="setAdditionalOptions('bitbucket-dc', 'git-password', $event)"
/>
</InputField>
</template>
<Button :is-loading="isSaving" type="submit" color="green" :text="isNew ? $t('add') : $t('save')" />
</div>
</template>
<InputField :label="$t('skip_verify')">
<Checkbox
:label="$t('skip_verify_desc')"
:model-value="forge.skip_verify || false"
@update:model-value="forge!.skip_verify = $event"
/>
</InputField>
</Panel>
<div class="flex gap-2">
<Button :text="$t('cancel')" :to="{ name: 'admin-settings-forges' }" />
<Button :is-loading="isSaving" type="submit" color="green" :text="isNew ? $t('add') : $t('save')" />
</div>
</form>
</template>
<script lang="ts" setup>
import { computed } from 'vue';
import { useI18n } from 'vue-i18n';
import Button from '~/components/atomic/Button.vue';
import Warning from '~/components/atomic/Warning.vue';
@@ -139,12 +137,51 @@ const emit = defineEmits<{
(e: 'submit'): void;
}>();
const { t } = useI18n();
const config = useConfig();
const forge = defineModel<Partial<Forge>>('forge', {
required: true,
});
// Define forge type options
const forgeTypeOptions = [
{ value: 'github', text: t('github') },
{ value: 'gitlab', text: t('gitlab') },
{ value: 'gitea', text: t('gitea') },
{ value: 'forgejo', text: t('forgejo') },
{ value: 'bitbucket', text: t('bitbucket') },
{ value: 'bitbucket-dc', text: t('bitbucket_dc') },
{ value: 'addon', text: t('addon') },
];
// Function to get default URL for a forge type
function getDefaultUrl(forgeType: ForgeType): string {
switch (forgeType) {
case 'github':
return 'github.com';
case 'gitlab':
return 'gitlab.com';
case 'bitbucket':
return 'bitbucket.org';
default:
return '';
}
}
// Initialize forge type to have a default value (first option)
if (!forge.value.type) {
const defaultType = forgeTypeOptions[0].value as ForgeType;
forge.value.type = defaultType;
forge.value.url = forge.value.url || getDefaultUrl(defaultType);
}
// Initialize forge type to have a default value
if (!forge.value.type) {
forge.value.type = 'github';
}
interface GitHubAdditionOptions {
'merge-ref'?: boolean;
'public-only'?: boolean;
@@ -235,19 +272,16 @@ const oauthAppForgeUrl = computed(() => {
});
const forgeType = computed({
get: () => forge.value?.type ?? '',
get: () => forge.value?.type ?? forgeTypeOptions[0].value,
set: (value) => {
let url = forge.value?.url || '';
const newUrl = getDefaultUrl(value as ForgeType);
if (value === 'github') {
url = url || 'github.com';
} else if (value === 'gitlab') {
url = url || 'gitlab.com';
} else if (value === 'bitbucket') {
url = url || 'bitbucket.org';
// Only update URL if it hasn't been customized or is empty
if (!forge.value?.url || forge.value.url === getDefaultUrl(forge.value.type as ForgeType)) {
forge.value = { ...forge.value, url: newUrl, type: value as ForgeType };
} else {
forge.value = { ...forge.value, type: value as ForgeType };
}
forge.value = { ...forge.value, url, type: value as ForgeType };
},
});

View File

@@ -1,8 +1,23 @@
<template>
<Settings :title="$t('user.settings.general.general')">
<InputField v-slot="{ id }" :label="$t('user.settings.general.language')">
<SelectField :id="id" v-model="selectedLocale" :options="localeOptions" />
<InputField :label="$t('user.settings.general.language')">
<template #default="{ id }">
<SelectField :id="id" v-model="selectedLocale" class="mt-2" :options="localeOptions" />
</template>
<template #description>
<i18n-t keypath="help_translating" tag="p">
<a
rel="noopener noreferrer"
href="https://translate.woodpecker-ci.org/projects/woodpecker-ci/ui/"
target="_blank"
class="underline"
>
{{ $t('weblate') }}
</a>
</i18n-t>
</template>
</InputField>
<InputField v-slot="{ id }" :label="$t('user.settings.general.theme.theme')">
<SelectField
:id="id"