Files
n8n/packages/frontend/editor-ui/src/app/components/Banner.vue
T
alighasami 3d5eaf9445
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
first commit
2026-03-17 16:22:57 +03:30

135 lines
2.5 KiB
Vue

<script setup lang="ts">
/**
* @TODO Move to design system
*/
import { ref } from 'vue';
import { ElTag } from 'element-plus';
import { N8nButton, N8nIcon, N8nLink } from '@n8n/design-system';
interface Props {
theme: 'success' | 'danger';
message: string;
buttonLabel?: string;
buttonLoadingLabel?: string;
buttonTitle?: string;
details?: string;
buttonLoading?: boolean;
}
withDefaults(defineProps<Props>(), {
buttonLoading: false,
buttonLabel: '',
buttonLoadingLabel: '',
buttonTitle: '',
details: '',
});
const emit = defineEmits<{
click: [];
}>();
const expanded = ref(false);
const expand = () => {
expanded.value = true;
};
const onClick = () => {
expanded.value = false;
emit('click');
};
</script>
<template>
<ElTag :type="theme" :disable-transitions="true" :class="$style.container">
<N8nIcon
:icon="theme === 'success' ? 'circle-check' : 'triangle-alert'"
:class="theme === 'success' ? $style.icon : $style.dangerIcon"
/>
<div :class="$style.banner">
<div :class="$style.content">
<div>
<span :class="theme === 'success' ? $style.message : $style.dangerMessage">
{{ message }}&nbsp;
</span>
<N8nLink v-if="details && !expanded" :bold="true" size="small" @click="expand">
<span :class="$style.moreDetails">More details</span>
</N8nLink>
</div>
</div>
<slot v-if="$slots.button" name="button" />
<N8nButton
variant="outline"
v-else-if="buttonLabel"
:label="buttonLoading && buttonLoadingLabel ? buttonLoadingLabel : buttonLabel"
:title="buttonTitle"
:loading="buttonLoading"
size="small"
@click.stop="onClick"
/>
</div>
<div v-if="expanded" :class="$style.details">
{{ details }}
</div>
</ElTag>
</template>
<style module lang="scss">
.icon {
position: absolute;
left: 14px;
top: 0;
bottom: 0;
margin: auto 0;
}
.dangerIcon {
composes: icon;
color: var(--color--danger);
}
.container {
width: 100%;
position: relative;
padding-left: 40px;
border: none;
}
.message {
white-space: normal;
line-height: var(--line-height--md);
overflow: hidden;
word-break: break-word;
}
.dangerMessage {
composes: message;
color: var(--callout--color--text--danger);
}
.banner {
display: flex;
align-items: center;
}
.content {
flex-grow: 1;
min-height: 26px;
display: flex;
align-items: center;
}
.details {
composes: message;
margin-top: var(--spacing--3xs);
color: var(--color--text);
font-size: var(--font-size--2xs);
}
.moreDetails {
font-size: var(--font-size--xs);
}
</style>