Add option to render button as link (#2378)

Fixes: https://github.com/woodpecker-ci/woodpecker/issues/1259

Work from https://github.com/woodpecker-ci/woodpecker/pull/1602/files

With this approach, existing buttons are still working and buttons with
`to="https://..."` are rendered as `a` tag. Not sure about the
"recursive render" issue from the original PR, have not seen any
rendering issue, any idea about this?


![image](https://github.com/woodpecker-ci/woodpecker/assets/3391958/2e87be21-3d3d-47b3-a2c4-1ffe5cfee592)
This commit is contained in:
Robert Kaussow 2023-09-08 08:44:22 +02:00 committed by GitHub
parent 718ec6141c
commit e21a41de8c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,6 +1,7 @@
<template>
<button
type="button"
<component
:is="to === null ? 'button' : httpLink ? 'a' : 'router-link'"
v-bind="btnAttrs"
class="relative flex items-center py-1 px-2 rounded-md border shadow-sm cursor-pointer transition-all duration-150 overflow-hidden disabled:opacity-50 disabled:cursor-not-allowed"
:class="{
'bg-wp-control-neutral-100 hover:bg-wp-control-neutral-200 border-wp-control-neutral-300 text-wp-text-100':
@ -12,7 +13,6 @@
}"
:title="title"
:disabled="disabled"
@click="doClick"
>
<slot>
<Icon v-if="startIcon" :name="startIcon" class="!w-6 !h-6" :class="{ invisible: isLoading, 'mr-1': text }" />
@ -32,12 +32,12 @@
<Icon name="loading" class="animate-spin" />
</div>
</slot>
</button>
</component>
</template>
<script lang="ts" setup>
import { computed, useAttrs } from 'vue';
import { RouteLocationRaw, useRouter } from 'vue-router';
import { RouteLocationRaw } from 'vue-router';
import Icon, { IconNames } from '~/components/atomic/Icon.vue';
@ -62,24 +62,19 @@ const props = withDefaults(
},
);
const router = useRouter();
const httpLink = computed(() => typeof props.to === 'string' && props.to.startsWith('http'));
async function doClick() {
if (props.isLoading) {
return;
const btnAttrs = computed(() => {
if (props.to === null) {
return { type: 'button' };
}
if (!props.to) {
return;
if (httpLink.value) {
return { href: props.to };
}
if (typeof props.to === 'string' && props.to.startsWith('http')) {
window.location.href = props.to;
return;
}
await router.push(props.to);
}
return { to: props.to };
});
const attrs = useAttrs();
const passedClasses = computed(() => {