Ben Lin
2024-07-01 f60c5156615626515bd6d84f151a1292b8b936c1
src/components/FlowChart/src/FlowChartToolbar.vue
@@ -6,7 +6,7 @@
        <span :class="`${prefixCls}-toolbar__icon`" v-if="item.icon" @click="onControl(item)">
          <Icon
            :icon="item.icon"
            :class="item.disabled ? 'cursor-not-allowed disabeld' : 'cursor-pointer'"
            :class="item.disabled ? 'cursor-not-allowed disabled' : 'cursor-pointer'"
          />
        </span>
      </Tooltip>
@@ -14,122 +14,137 @@
    </template>
  </div>
</template>
<script lang="ts">
<script lang="ts" setup>
  import type { ToolbarConfig } from './types';
  import { defineComponent, ref, onUnmounted, unref, nextTick, watchEffect } from 'vue';
  import { ref, onUnmounted, unref, nextTick, watchEffect } from 'vue';
  import { Divider, Tooltip } from 'ant-design-vue';
  import Icon from '@/components/Icon/Icon.vue';
  import { useFlowChartContext } from './useFlowContext';
  import { ToolbarTypeEnum } from './enum';
  export default defineComponent({
    name: 'FlowChartToolbar',
    components: { Icon, Divider, Tooltip },
    props: {
      prefixCls: String,
  defineOptions({ name: 'FlowChartToolbar' });
  defineProps({
    prefixCls: String,
  });
  const emit = defineEmits(['view-data', 'save-data', 'addlf', 'undo', 'redo']);
  const toolbarItemList = ref<ToolbarConfig[]>([
    {
      type: ToolbarTypeEnum.ADD,
      icon: 'ion:add-outline',
      tooltip: '新增流程',
    },
    emits: ['view-data'],
    setup(_, { emit }) {
      const toolbarItemList = ref<ToolbarConfig[]>([
        {
          type: ToolbarTypeEnum.ZOOM_IN,
          icon: 'codicon:zoom-out',
          tooltip: '缩小',
        },
        {
          type: ToolbarTypeEnum.ZOOM_OUT,
          icon: 'codicon:zoom-in',
          tooltip: '放大',
        },
        {
          type: ToolbarTypeEnum.RESET_ZOOM,
          icon: 'codicon:screen-normal',
          tooltip: '重置比例',
        },
        { separate: true },
        {
          type: ToolbarTypeEnum.UNDO,
          icon: 'ion:arrow-undo-outline',
          tooltip: '后退',
          disabled: true,
        },
        {
          type: ToolbarTypeEnum.REDO,
          icon: 'ion:arrow-redo-outline',
          tooltip: '前进',
          disabled: true,
        },
        { separate: true },
        {
          type: ToolbarTypeEnum.SNAPSHOT,
          icon: 'ion:download-outline',
          tooltip: '下载',
        },
        {
          type: ToolbarTypeEnum.VIEW_DATA,
          icon: 'carbon:document-view',
          tooltip: '查看数据',
        },
      ]);
      const { logicFlow } = useFlowChartContext();
      function onHistoryChange({ data: { undoAble, redoAble } }) {
        const itemsList = unref(toolbarItemList);
        const undoIndex = itemsList.findIndex((item) => item.type === ToolbarTypeEnum.UNDO);
        const redoIndex = itemsList.findIndex((item) => item.type === ToolbarTypeEnum.REDO);
        if (undoIndex !== -1) {
          unref(toolbarItemList)[undoIndex].disabled = !undoAble;
        }
        if (redoIndex !== -1) {
          unref(toolbarItemList)[redoIndex].disabled = !redoAble;
        }
      }
      const onControl = (item) => {
        const lf = unref(logicFlow);
        if (!lf) {
          return;
        }
        switch (item.type) {
          case ToolbarTypeEnum.ZOOM_IN:
            lf.zoom();
            break;
          case ToolbarTypeEnum.ZOOM_OUT:
            lf.zoom(true);
            break;
          case ToolbarTypeEnum.RESET_ZOOM:
            lf.resetZoom();
            break;
          case ToolbarTypeEnum.UNDO:
            lf.undo();
            break;
          case ToolbarTypeEnum.REDO:
            lf.redo();
            break;
          case ToolbarTypeEnum.SNAPSHOT:
            lf.getSnapshot();
            break;
          case ToolbarTypeEnum.VIEW_DATA:
            emit('view-data');
            break;
        }
      };
      watchEffect(async () => {
        if (unref(logicFlow)) {
          await nextTick();
          unref(logicFlow)?.on('history:change', onHistoryChange);
        }
      });
      onUnmounted(() => {
        unref(logicFlow)?.off('history:change', onHistoryChange);
      });
      return { toolbarItemList, onControl };
    {
      type: ToolbarTypeEnum.ZOOM_IN,
      icon: 'codicon:zoom-out',
      tooltip: '缩小',
    },
    {
      type: ToolbarTypeEnum.ZOOM_OUT,
      icon: 'codicon:zoom-in',
      tooltip: '放大',
    },
    {
      type: ToolbarTypeEnum.RESET_ZOOM,
      icon: 'codicon:screen-normal',
      tooltip: '重置比例',
    },
    { separate: true },
    {
      type: ToolbarTypeEnum.UNDO,
      icon: 'ion:arrow-undo-outline',
      tooltip: '后退',
      disabled: true,
    },
    {
      type: ToolbarTypeEnum.REDO,
      icon: 'ion:arrow-redo-outline',
      tooltip: '前进',
      disabled: true,
    },
    { separate: true },
    {
      type: ToolbarTypeEnum.SNAPSHOT,
      icon: 'ion:download-outline',
      tooltip: '下载',
    },
    {
      type: ToolbarTypeEnum.SAVE_DATA,
      icon: 'ion:save-outline',
      tooltip: '保存',
    },
    {
      type: ToolbarTypeEnum.VIEW_DATA,
      icon: 'carbon:document-view',
      tooltip: '查看数据',
    },
  ]);
  const { logicFlow } = useFlowChartContext();
  function onHistoryChange({ data: { undoAble, redoAble } }) {
    const itemsList = unref(toolbarItemList);
    const undoIndex = itemsList.findIndex((item) => item.type === ToolbarTypeEnum.UNDO);
    const redoIndex = itemsList.findIndex((item) => item.type === ToolbarTypeEnum.REDO);
    if (undoIndex !== -1) {
      unref(toolbarItemList)[undoIndex].disabled = !undoAble;
    }
    if (redoIndex !== -1) {
      unref(toolbarItemList)[redoIndex].disabled = !redoAble;
    }
  }
  const onControl = (item) => {
    const lf = unref(logicFlow);
    if (!lf) {
      return;
    }
    switch (item.type) {
      case ToolbarTypeEnum.ADD:
        emit('addlf');
        break;
      case ToolbarTypeEnum.ZOOM_IN:
        lf.zoom();
        break;
      case ToolbarTypeEnum.ZOOM_OUT:
        lf.zoom(true);
        break;
      case ToolbarTypeEnum.RESET_ZOOM:
        lf.resetZoom();
        break;
      case ToolbarTypeEnum.UNDO:
        lf.undo();
        emit('undo');
        break;
      case ToolbarTypeEnum.REDO:
        lf.redo();
        emit('redo');
        break;
      case ToolbarTypeEnum.SNAPSHOT:
        lf.getSnapshot();
        break;
      case ToolbarTypeEnum.VIEW_DATA:
        emit('view-data');
        break;
      case ToolbarTypeEnum.SAVE_DATA:
        emit('save-data');
        break;
    }
  };
  watchEffect(async () => {
    if (unref(logicFlow)) {
      await nextTick();
      unref(logicFlow)?.on('history:change', onHistoryChange);
    }
  });
  onUnmounted(() => {
    unref(logicFlow)?.off('history:change', onHistoryChange);
  });
</script>
<style lang="less">