Skip to content

Commit

Permalink
add a new visual variant of the trigger button
Browse files Browse the repository at this point in the history
  • Loading branch information
autologie committed Jan 24, 2025
1 parent d16de8c commit 2b48850
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import CanvasNodeRenderer from '@/components/canvas/elements/nodes/CanvasNodeRen
import CanvasNodeTriggerButton from '@/components/canvas/elements/nodes/CanvasNodeTriggerButton.vue';
import CanvasHandleRenderer from '@/components/canvas/elements/handles/CanvasHandleRenderer.vue';
import { useNodeConnections } from '@/composables/useNodeConnections';
import { CanvasNodeKey } from '@/constants';
import { CanvasNodeKey, LOCAL_STORAGE_CANVAS_TRIGGER_BUTTON_VARIANT } from '@/constants';
import { useContextMenu } from '@/composables/useContextMenu';
import type { NodeProps, XYPosition } from '@vue-flow/core';
import { Position } from '@vue-flow/core';
Expand All @@ -36,6 +36,7 @@ import {
import type { EventBus } from 'n8n-design-system';
import { createEventBus } from 'n8n-design-system';
import { isEqual } from 'lodash-es';
import { useLocalStorage } from '@vueuse/core';
type Props = NodeProps<CanvasNodeData> & {
readOnly?: boolean;
Expand Down Expand Up @@ -116,6 +117,13 @@ const dataTestId = computed(() =>
: 'canvas-node',
);
const triggerButtonVariant = useLocalStorage<1 | 2>(LOCAL_STORAGE_CANVAS_TRIGGER_BUTTON_VARIANT, 2);
const buttonContainerClass = computed(() => ({
[style['button-container']]: true,
[style['button-container-variant-2']]: triggerButtonVariant.value === 2,
}));
/**
* Event bus
*/
Expand Down Expand Up @@ -406,25 +414,26 @@ onBeforeUnmount(() => {
:disabled="isDisabled"
/>
<!-- @TODO :color-default="iconColorDefault"-->
<template #button>
<CanvasNodeTriggerButton
v-if="
!isDisabled &&
props.data.render.type === CanvasNodeRenderType.Default &&
props.data.render.options.trigger
"
:data="props.data"
/>
</template>
</CanvasNodeRenderer>

<div
v-if="
!isDisabled &&
props.data.render.type === CanvasNodeRenderType.Default &&
props.data.render.options.trigger
"
:class="buttonContainerClass"
>
<CanvasNodeTriggerButton :data="props.data" :variant="triggerButtonVariant" />
</div>
</div>
</template>

<style lang="scss" module>
.canvasNode {
&:hover,
&:focus-within,
&.showToolbar {
&.showToolbar,
&:has(> :hover:not(.button-container)) {
.canvasNodeToolbar {
opacity: 1;
}
Expand All @@ -445,4 +454,60 @@ onBeforeUnmount(() => {
opacity: 1;
}
}
.button-container {
z-index: -1;
position: absolute;
display: flex;
align-items: center;
/**
background: rgba(255, 0, 0, 0.1);
*/
height: 300%;
right: -100%;
top: -100%;
padding-right: calc(200% + var(--spacing-xl));
&:not(.button-container-variant-2) {
button {
opacity: 1;
}
}
}
.button-container-variant-2 {
padding-right: calc(200% + var(--spacing-s));
& button {
animation: slide-out 0.2s ease forwards;
}
.canvasNode:hover & > button {
animation: slide-in 0.2s ease forwards;
}
}
@keyframes slide-in {
from {
translate: -12px 0;
opacity: 0;
}
to {
translate: 0 0;
opacity: 1;
}
}
@keyframes slide-out {
from {
translate: 0 0;
opacity: 1;
}
to {
translate: -12px 0;
opacity: 0;
}
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ const node = inject(CanvasNodeKey);
const slots = defineSlots<{
default?: () => unknown;
button?: () => unknown;
}>();
const Render = () => {
Expand All @@ -33,7 +32,7 @@ const Render = () => {
{
'data-canvas-node-render-type': renderType,
},
slots,
slots.default,
);
};
</script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { type CanvasNodeData } from '@/types';
import { computed } from 'vue';
import { useRouter } from 'vue-router';
const { data } = defineProps<{ data: CanvasNodeData }>();
const { data, variant } = defineProps<{ data: CanvasNodeData; variant: 1 | 2 }>();
const router = useRouter();
const i18n = useI18n();
Expand All @@ -24,19 +24,37 @@ const isExecuting = computed(() => uiStore.isActionActive['workflowRunning']);

<template>
<N8nButton
v-if="data.type === CHAT_TRIGGER_NODE_TYPE"
v-if="variant === 1 && data.type === CHAT_TRIGGER_NODE_TYPE"
type="secondary"
size="large"
:disabled="isExecuting"
@click="toggleChatOpen('node')"
>{{ isChatOpen ? i18n.baseText('chat.hide') : i18n.baseText('chat.window.title') }}</N8nButton
>
<N8nButton
v-else
v-else-if="variant === 1"
type="secondary"
size="large"
:disabled="isExecuting"
@click="runEntireWorkflow('node', data.name)"
>{{ i18n.baseText('nodeView.runButtonText.executeWorkflow') }}</N8nButton
>
<N8nButton
v-else-if="variant === 2 && data.type === CHAT_TRIGGER_NODE_TYPE"
type="primary"
size="large"
:disabled="isExecuting"
:label="isChatOpen ? i18n.baseText('chat.hide') : i18n.baseText('chat.window.title')"
icon="comment"
@click="toggleChatOpen('node')"
/>
<N8nButton
v-else
type="primary"
size="large"
:disabled="isExecuting"
:label="i18n.baseText('nodeView.runButtonText.executeWorkflow')"
icon="bolt"
@click="runEntireWorkflow('node', data.name)"
/>
</template>
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@ import { computed, ref, useCssModule, watch } from 'vue';
import { useNodeConnections } from '@/composables/useNodeConnections';
import { useI18n } from '@/composables/useI18n';
import { useCanvasNode } from '@/composables/useCanvasNode';
import { NODE_INSERT_SPACER_BETWEEN_INPUT_GROUPS } from '@/constants';
import {
LOCAL_STORAGE_CANVAS_TRIGGER_BUTTON_VARIANT,
NODE_INSERT_SPACER_BETWEEN_INPUT_GROUPS,
} from '@/constants';
import type { CanvasNodeDefaultRender } from '@/types';
import { useCanvas } from '@/composables/useCanvas';
import { useLocalStorage } from '@vueuse/core';
const $style = useCssModule();
const i18n = useI18n();
Expand Down Expand Up @@ -106,6 +110,8 @@ const isStrikethroughVisible = computed(() => {
const showTooltip = ref(false);
const triggerButtonVariant = useLocalStorage<1 | 2>(LOCAL_STORAGE_CANVAS_TRIGGER_BUTTON_VARIANT, 2);
watch(initialized, () => {
if (initialized.value) {
showTooltip.value = true;
Expand All @@ -128,21 +134,25 @@ function openContextMenu(event: MouseEvent) {
<div :class="classes" :style="styles" :data-test-id="dataTestId" @contextmenu="openContextMenu">
<CanvasNodeTooltip v-if="renderOptions.tooltip" :visible="showTooltip" />
<slot />
<CanvasNodeTriggerIcon
v-if="renderOptions.trigger && triggerButtonVariant === 2"
:variant="2"
/>
<CanvasNodeStatusIcons v-if="!isDisabled" :class="$style.statusIcons" />
<CanvasNodeDisabledStrikeThrough v-if="isStrikethroughVisible" />
<div :class="$style.description">
<div v-if="label" :class="$style.label">
{{ label }}
<CanvasNodeTriggerIcon v-if="renderOptions.trigger" />
<CanvasNodeTriggerIcon
v-if="renderOptions.trigger && triggerButtonVariant === 1"
:variant="1"
/>
</div>
<div v-if="isDisabled" :class="$style.disabledLabel">
({{ i18n.baseText('node.disabled') }})
</div>
<div v-if="subtitle" :class="$style.subtitle">{{ subtitle }}</div>
</div>
<div v-if="$slots.button" :class="$style['button-container']">
<slot name="button" />
</div>
</div>
</template>

Expand Down Expand Up @@ -316,11 +326,4 @@ function openContextMenu(event: MouseEvent) {
bottom: var(--canvas-node--status-icons-offset);
right: var(--canvas-node--status-icons-offset);
}
.button-container {
position: absolute;
right: 100%;
top: auto;
margin: var(--spacing-m);
}
</style>
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script lang="ts" setup>
import { useI18n } from '@/composables/useI18n';
const { variant } = defineProps<{ variant: 1 | 2 }>();
const i18n = useI18n();
</script>

Expand All @@ -9,17 +10,54 @@ const i18n = useI18n();
<template #content>
<span v-n8n-html="i18n.baseText('node.thisIsATriggerNode')" />
</template>
<div :class="$style.triggerIcon">
<FontAwesomeIcon icon="bolt" size="md" />
<div :class="variant === 1 ? $style['triggerIcon-variant-1'] : $style['triggerIcon-variant-2']">
<FontAwesomeIcon icon="bolt" size="lg" />
</div>
</N8nTooltip>
</template>

<style lang="scss" module>
.triggerIcon {
.triggerIcon-variant-1 {
display: inline;
position: static;
color: var(--color-primary);
padding: var(--spacing-4xs);
}
.triggerIcon-variant-2 {
position: absolute;
right: 100%;
margin: auto;
color: var(--color-primary);
padding: var(--spacing-s);
animation: slide-in 0.2s ease forwards;
:global(.hovered) & {
animation: slide-out 0.2s ease forwards;
}
}
@keyframes slide-in {
from {
translate: -12px 0;
opacity: 0;
}
to {
translate: 0 0;
opacity: 1;
}
}
@keyframes slide-out {
from {
translate: 0 0;
opacity: 1;
}
to {
translate: -12px 0;
opacity: 0;
}
}
</style>
1 change: 1 addition & 0 deletions packages/editor-ui/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,7 @@ export const LOCAL_STORAGE_EXPERIMENT_OVERRIDES = 'N8N_EXPERIMENT_OVERRIDES';
export const LOCAL_STORAGE_HIDE_GITHUB_STAR_BUTTON = 'N8N_HIDE_HIDE_GITHUB_STAR_BUTTON';
export const LOCAL_STORAGE_NDV_INPUT_PANEL_DISPLAY_MODE = 'N8N_NDV_INPUT_PANEL_DISPLAY_MODE';
export const LOCAL_STORAGE_NDV_OUTPUT_PANEL_DISPLAY_MODE = 'N8N_NDV_OUTPUT_PANEL_DISPLAY_MODE';
export const LOCAL_STORAGE_CANVAS_TRIGGER_BUTTON_VARIANT = 'Canvas.TriggerButtonVariant';
export const BASE_NODE_SURVEY_URL = 'https://n8n-community.typeform.com/to/BvmzxqYv#nodename=';

export const HIRING_BANNER = `
Expand Down

0 comments on commit 2b48850

Please sign in to comment.