BasicNode.vue 3.63 KB
<script lang="ts" setup>
  import type { NodeProps } from '@vue-flow/core';
  import { Handle, Position } from '@vue-flow/core';
  import { computed, unref } from 'vue';
  import { Tooltip } from 'ant-design-vue';
  import { Icon } from '/@/components/Icon';
  import type { NodeData, NodeDefinition } from '../../../types/node';
  import BasicToolbar from './BasicToolbar.vue';
  import NodeExtraContent from './NodeExtraContent.vue';

  const props = defineProps<NodeProps>();

  const getData = computed(() => props.data as NodeData);

  const getNodeDefinition = computed<NodeDefinition>(() => {
    const { config } = unref(getData);
    const { configurationDescriptor } = config || {};
    const { nodeDefinition } = configurationDescriptor || {};
    return nodeDefinition || {};
  });

  const getHasInEnabled = computed(() => unref(getNodeDefinition).inEnabled);

  const getHasOutEnabled = computed(() => unref(getNodeDefinition).outEnabled);

  const getLabel = computed(() => {
    const { config } = unref(getData);

    return config?.name;
  });

  const getIconUrl = computed(() => {
    const { iconUrl } = unref(getNodeDefinition);
    return iconUrl;
  });

  const getIcon = computed(() => {
    const { icon } = unref(getNodeDefinition);
    const { categoryConfig } = unref(getData);
    const { icon: categoryIcon } = categoryConfig || {};
    return icon || categoryIcon || 'tabler:circuit-ground';
  });

  const getName = computed(() => {
    const { data } = unref(getData);
    return data?.name;
  });

  const getBackgroundColor = computed(() => {
    const { config, categoryConfig } = unref(getData);
    const { backgroundColor: categoryBackgroundColor } = categoryConfig || {};
    const { backgroundColor } = config || {};
    return backgroundColor || categoryBackgroundColor;
  });
</script>

<template>
  <Tooltip color="#fff" :mouse-enter-delay="0.5" placement="right">
    <template #title>
      <section class="text-dark-900 text-xs">
        <p class="mb-0 font-bold"> {{ getData?.data?.name }} </p>
        <p class="mb-0 mt-2 text-gray-500 italic">
          {{ getData.categoryConfig?.title }}
          {{ getData?.categoryConfig?.title && getData.config?.name ? '-' : '' }}
          {{ getData.config?.name }}
        </p>
        <p class="mt-1 mb-0 text-gray-500">{{ getData.data?.description }}</p>
      </section>
    </template>
    <main
      class="basic-node-hover flex items-center w-44 h-12 rounded border px-4 py-2 border-gray-700 dark:text-light-50"
      :style="{ backgroundColor: getBackgroundColor, outline: selected ? '3px solid red' : 'none' }"
    >
      <div>
        <Icon v-if="!getIconUrl" class="text-2xl dark:text-light-50" :icon="getIcon" />
        <img v-if="getIconUrl" :src="getIconUrl" class="w-4 h-4" />
      </div>
      <BasicToolbar v-if="!getData.config?.disableAction" v-bind="$props" />
      <div class="flex text-xs flex-col ml-2 text-left truncate">
        <span class="text-gray-700 w-full truncate dark:text-light-50">{{ getLabel }}</span>
        <span class="w-full truncate dark:text-neutral-50">{{ getName }}</span>
      </div>
      <div class="flex-auto">
        <NodeExtraContent :config="getData.config" :nodeProps="$props" />
      </div>
      <Handle v-if="getHasInEnabled" type="source" :position="Position.Left" />
      <Handle v-if="getHasOutEnabled" type="source" :position="Position.Right" />
    </main>
  </Tooltip>
</template>

<style lang="css" scoped>
  .basic-node-hover::before {
    content: '';
    position: absolute;
    width: 100%;
    height: 100%;
    left: 0;
    display: none;
    background-color: #00000027;
  }

  .basic-node-hover:hover::before {
    display: block;
  }
</style>