NodeItem.vue 3.56 KB
<script lang="ts" setup>
  import { Tooltip } from 'ant-design-vue';
  import { computed, ref, toRaw, unref } from 'vue';
  import { EFFECT_SYMBOL, TRANSFER_DATA_KEY } from '../../../hook/useDragCreate';
  import { CategoryConfigType, NodeItemConfigType } from '../../../types/node';

  const props = defineProps<{
    categoryConfig?: CategoryConfigType;
    config?: NodeItemConfigType;
  }>();

  const visible = ref(false);

  const getNodeDefinition = computed(() => {
    const { config } = props;
    const { configurationDescriptor } = config || {};
    const { nodeDefinition } = configurationDescriptor || {};
    return nodeDefinition || {};
  });

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

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

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

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

  const getBackgroundColor = computed(() => {
    const { config, categoryConfig } = props;
    const { backgroundColor } = config || {};
    const { backgroundColor: categoryBackgroundColor } = categoryConfig || {};
    return backgroundColor || categoryBackgroundColor;
  });

  const handleOnDragStart = (event: DragEvent, options: object) => {
    if (event.dataTransfer) {
      event.dataTransfer.setData(
        TRANSFER_DATA_KEY,
        JSON.stringify({ offsetX: event.offsetX, offsetY: event.offsetY, options })
      );
      event.dataTransfer.effectAllowed = EFFECT_SYMBOL;
    }
  };

  const handleDragStart = (event: DragEvent) => {
    visible.value = false;
    handleOnDragStart(event, toRaw(unref(props)));
  };
</script>

<template>
  <Tooltip
    v-model:visible="visible"
    placement="right"
    color="#fff"
    trigger="hover"
    :mouse-enter-delay="0.5"
    overlay-class-name="!max-w-90"
  >
    <template #title>
      <section class="text-dark-900">
        <h1 class="font-bold dark:text-dark-50">
          {{ config?.name }}
        </h1>
        <p class="italic text-gray-600">
          {{ getNodeDefinition.description }}
        </p>
        <p v-html="getNodeDefinition.details"></p>
      </section>
    </template>
    <main
      class="node flex items-center cursor-pointer w-44 h-12 min-h-12 rounded border relative px-4 py-2 border-gray-700 z-10"
      :style="{ backgroundColor: getBackgroundColor }"
      :draggable="true"
      @dragstart="handleDragStart"
    >
      <div>
        <img v-if="getIconUrl" class="w-4 h-4" :src="getIconUrl" alt="" />
        <Icon v-if="!getIconUrl" class="text-2xl dark:text-light-50" :icon="getIcon" />
      </div>
      <div class="flex flex-1 text-xs flex-col ml-2 text-left truncate">
        <span class="text-gray-700 w-full truncate text-xs dark:text-light-50">
          {{ config?.name }}
        </span>
      </div>
      <div
        v-if="getHasInEnabledFlag"
        class="w-4 h-4 bg-gray-300 rounded-md border absolute -left-3 border-gray-500"
      ></div>
      <div
        v-if="getHasOutEnabledFlag"
        class="w-4 h-4 bg-gray-300 rounded-md border absolute -right-3 border-gray-500"
      ></div>
    </main>
  </Tooltip>
</template>

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

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