useAwaitPopupWindowBindData.ts 3.87 KB
import { Component, computed, ref, shallowRef, toRaw, unref } from 'vue';
import { fetchConnectionComponent, fetchCreateComponent } from '../packages';
import { CreateModalDefineExposeType, AwaitPopupWindowReturnDataType } from '../types';
import { EdgeData, NodeData } from '../types/node';
import { DataActionModeEnum } from '/@/enums/toolEnum';
import { ElementsTypeEnum } from '../enum';

interface OptionsType {
  mode: DataActionModeEnum;
  type: ElementsTypeEnum;
}

export interface ElementInfo {
  id: string;
  type: ElementsTypeEnum;
}

export function useAwaitPopupWindowBindData(
  options: OptionsType = { mode: DataActionModeEnum.CREATE, type: ElementsTypeEnum.NODE }
) {
  const { type, mode } = options;

  const visible = ref(false);

  const nodeData = ref<NodeData>();

  const edgeData = ref<EdgeData>();

  const spinning = ref(false);

  const resolveFn = ref<(options: AwaitPopupWindowReturnDataType) => void>();

  const createComponentEl = ref<Nullable<CreateModalDefineExposeType>>();

  const shadowComponent = shallowRef<Nullable<Component>>();

  const elementInfo = ref<ElementInfo>();

  const getNodeSetValue = computed(() => {
    return unref(mode) === DataActionModeEnum.CREATE
      ? unref(nodeData)?.config?.configurationDescriptor.nodeDefinition.defaultConfiguration
      : unref(nodeData)?.data?.configuration;
  });

  const getEdgeSetValue = computed(() => {
    return {
      type:
        unref(mode) === DataActionModeEnum.CREATE
          ? unref(nodeData)?.config?.configurationDescriptor?.nodeDefinition.relationTypes
          : unref(edgeData)?.data,
    };
  });

  const getSetValue = computed(() =>
    unref(type) === ElementsTypeEnum.EDGE ? unref(getEdgeSetValue) : unref(getNodeSetValue)
  );

  const getComponentKey = computed(() => unref(nodeData)?.config?.key);

  const handleFetchComponent = async (nodeOptions: NodeData, edgeOptions?: EdgeData) => {
    nodeData.value = nodeOptions;
    edgeData.value = edgeOptions;

    spinning.value = true;
    shadowComponent.value = null;
    const modules =
      ElementsTypeEnum.NODE === type
        ? await fetchCreateComponent(nodeOptions.config!)
        : await fetchConnectionComponent(nodeOptions.config!);

    const component = (await modules?.()) as Record<'default', Component>;
    shadowComponent.value = component?.default;
    spinning.value = false;
  };

  const open = async (
    nodeData: NodeData,
    edgeData?: EdgeData,
    _elementInfo?: ElementInfo
  ): Promise<AwaitPopupWindowReturnDataType> => {
    elementInfo.value = _elementInfo;
    await handleFetchComponent(nodeData, edgeData);
    return new Promise((_resolve) => {
      visible.value = true;
      resolveFn.value = _resolve;
    });
  };

  const handleOnMounted = () => {
    unref(createComponentEl)?.setFieldsValue?.(toRaw(unref(getSetValue)), toRaw(unref(nodeData)));
  };

  const validate = async () => {
    return (await unref(createComponentEl)?.validate?.()) || { flag: true };
  };

  const handleSubmitData = (extraData: Recordable = {}, value: Recordable = {}) => {
    return Object.assign(
      {},
      extraData,
      unref(type) === ElementsTypeEnum.NODE ? { configuration: toRaw(unref(value)) } : value
    );
  };

  const handleSubmit = async (extraData: Recordable = {}) => {
    const { flag } = await validate();
    if (!flag) return;
    const value = await unref(createComponentEl)?.getFieldsValue?.();
    unref(resolveFn)?.({
      flag: true,
      data: handleSubmitData(extraData, value),
    } as AwaitPopupWindowReturnDataType);
    visible.value = false;
  };

  const handleCancel = () => {
    unref(resolveFn)?.({ flag: false, data: null } as AwaitPopupWindowReturnDataType);
    visible.value = false;
  };

  return {
    visible,
    nodeData,
    spinning,
    elementInfo,
    shadowComponent,
    createComponentEl,
    getComponentKey,
    open,
    handleOnMounted,
    handleSubmit,
    handleCancel,
  };
}