All files / web/src/components/nodes/shared NodeActions.vue

0% Statements 0/32
100% Branches 1/1
100% Functions 1/1
0% Lines 0/32

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121                                                                                                                                                                                                                                                 
<script setup lang="ts">
import { ref } from 'vue'
import { Settings, Play, FileText } from 'lucide-vue-next'
import { ElTooltip } from 'element-plus'
 
interface Props {
  showTestButton?: boolean
  testButtonTooltip?: string
  testButtonDisabled?: boolean
}
 
withDefaults(defineProps<Props>(), {
  showTestButton: true,
  testButtonTooltip: 'Test Node',
  testButtonDisabled: false
})
 
const emit = defineEmits<{
  'open-config': []
  'view-io': []
  'test': []
}>()
 
const showActions = ref(false)
 
defineExpose({
  show: () => { showActions.value = true },
  hide: () => { showActions.value = false }
})
</script>
 
<template>
  <Transition name="actions">
    <div v-if="showActions" class="node-actions">
      <ElTooltip content="Configure Node" placement="top">
        <button class="action-btn" @click.stop="emit('open-config')">
          <Settings :size="14" />
        </button>
      </ElTooltip>
      <ElTooltip v-if="showTestButton" :content="testButtonTooltip" placement="top">
        <button
          class="action-btn test-btn"
          @click.stop="emit('test')"
          :disabled="testButtonDisabled"
        >
          <Play :size="14" />
        </button>
      </ElTooltip>
      <ElTooltip content="View Input/Output" placement="top">
        <button class="action-btn io-btn" @click.stop="emit('view-io')">
          <FileText :size="14" />
        </button>
      </ElTooltip>
      <slot name="extra" />
    </div>
  </Transition>
</template>
 
<style lang="scss" scoped>
.node-actions {
  position: absolute;
  top: calc(-1 * var(--rf-spacing-5xl));
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: var(--rf-spacing-xs);
  padding: var(--rf-spacing-3xs);
  background: var(--rf-color-bg-container);
  border-radius: var(--rf-radius-base);
  box-shadow: var(--rf-shadow-md);
  z-index: var(--rf-z-index-dropdown);
 
  .action-btn {
    width: var(--rf-size-icon-md);
    height: var(--rf-size-icon-md);
    padding: 0;
    border: none;
    background: var(--rf-color-bg-secondary);
    color: var(--rf-color-text-secondary);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--rf-radius-small);
    transition: all var(--rf-transition-fast);
 
    &:hover {
      background: var(--rf-color-primary-bg-lighter);
      color: var(--rf-color-primary);
      transform: scale(1.1);
    }
 
    &.io-btn:hover {
      background: var(--rf-color-info-bg-lighter);
      color: var(--rf-color-info);
    }
 
    &.test-btn:hover:not(:disabled) {
      background: var(--rf-color-success-bg-lighter);
      color: var(--rf-color-success);
    }
 
    &:disabled {
      opacity: 0.5;
      cursor: not-allowed;
    }
  }
}
 
.actions-enter-active,
.actions-leave-active {
  transition: all var(--rf-transition-fast);
}
 
.actions-enter-from,
.actions-leave-to {
  opacity: 0;
  transform: translateX(-50%) translateY(5px);
}
</style>