index.vue 6.57 KB
<script setup lang="ts">
  import { ComponentPublicInstance, ref, unref, watch } from 'vue';
  import { Tooltip, Button } from 'ant-design-vue';
  import { CollapseContainer } from '/@/components/Container';
  import { Icon } from '/@/components/Icon';
  import { FlipFlopItemType, FlipFlopComponentTypeEnum, ScheduleOptionItemType } from './types';
  import { BasicForm, FormActionType } from '/@/components/Form';
  import { getFormSchemas, FormFieldEnum } from './config';
  import { useSceneLinkageDrawerContext } from '../SceneLinkageDrawer/sceneLinkageDrawerContext';
  import { ScheduleTypeEnum, ScheduleTypeNameEnum } from '/@/enums/linkedgeEnum';
  import { ConditionFilter } from '../ConditionFilter';
  import { EnablingRule } from '../EnablingRule';
  import { useModal } from '/@/components/Modal';
  import { DataActionModeEnum } from '/@/enums/toolEnum';
  import { EnableRuleFormModalParamsType, ScheduleType } from '../EnablingRule/type';
  import { useFlipFlopData } from './useFlipFlopData';
  import { createNewFlipFlopItem } from '.';

  const { disabledDrawer } = useSceneLinkageDrawerContext();

  const emit = defineEmits(['delete']);

  const props = withDefaults(
    defineProps<{
      addButtonName?: string;
      defaultNull?: boolean;
      panelTitle?: (index: number) => string;
      showAddButton?: boolean;
      disabled?: boolean;
      type?: FlipFlopComponentTypeEnum;
    }>(),
    {
      addButtonName: '触发器 (OR)',
      defaultNull: false,
      panelTitle: (index: number) => `触发器${index}`,
      showAddButton: true,
      disabled: false,
      type: FlipFlopComponentTypeEnum.FLIP_FLOP,
    }
  );

  const formSchemas = getFormSchemas(props.type);

  const [registerModal, { openModal }] = useModal();

  const handleOpenModal = (type: ScheduleTypeEnum, flipFlopItem: FlipFlopItemType) => {
    if (unref(disabledDrawer) && type !== flipFlopItem.schedule.type) return;

    if (type === ScheduleTypeEnum.ANY_TIME) {
      flipFlopItem.schedule = { type };
      return;
    }

    openModal(true, {
      mode: DataActionModeEnum.CREATE,
      record: {
        type,
        schedule: flipFlopItem.schedule,
        key: flipFlopItem.key,
      },
    } as EnableRuleFormModalParamsType);
  };

  const handleRuleSetting = (params: ScheduleType, key: string) => {
    const index = unref(flipFlopListElRef).findIndex((flipFlopItem) => flipFlopItem.key === key);

    ~index && (unref(flipFlopListElRef)[index].schedule = params);
  };

  const scheduleOptions: ScheduleOptionItemType[] = Object.keys(ScheduleTypeEnum).map((value) => ({
    label: ScheduleTypeNameEnum[value],
    value: value as ScheduleTypeEnum,
  }));

  const { organizationId } = useSceneLinkageDrawerContext();

  const flipFlopListElRef = ref<FlipFlopItemType[]>(
    props.defaultNull ? [] : [createNewFlipFlopItem()]
  );

  /**
   * @description on organization change
   */
  watch(organizationId, () => {
    unref(flipFlopListElRef).forEach((flipFlopItem) =>
      flipFlopItem.ref?.setFieldsValue({ [FormFieldEnum.ENTITY_ID]: [] })
    );
  });

  const setFlopFlipFormRef = (
    flipFlopItem: FlipFlopItemType,
    el: Nullable<Element | ComponentPublicInstance>
  ) => {
    flipFlopItem.ref = el as unknown as FormActionType;
  };

  const setFlopFlipConditionRef = (
    flipFlopItem: FlipFlopItemType,
    el: Nullable<Element | ComponentPublicInstance>
  ) => {
    flipFlopItem.conditionRef = el as unknown as InstanceType<typeof ConditionFilter>;
  };

  const handleDelete = (flipFlopItem: FlipFlopItemType) => {
    const index = unref(flipFlopListElRef).findIndex((item) => item.key === flipFlopItem.key);
    ~index && unref(flipFlopListElRef).splice(index, 1);
    emit('delete');
  };

  const handleAdd = () => {
    flipFlopListElRef.value.push(createNewFlipFlopItem());
  };

  const { getFieldsValue, setFieldsValue, validate, resetFieldsValue } =
    useFlipFlopData(flipFlopListElRef);

  defineExpose({ getFieldsValue, setFieldsValue, validate, resetFieldsValue });
</script>

<template>
  <section>
    <CollapseContainer
      v-for="(flipFlopItem, index) in flipFlopListElRef"
      :key="flipFlopItem.key"
      :title="panelTitle(index + 1)"
      class="mb-4"
    >
      <template #action>
        <header class="flex items-center justify-between">
          <div class="flex items-center">
            <div class="flex">
              <span class="mr-2">启用规则:</span>
              <div
                class="px-1 cursor-pointer"
                v-for="schedule in scheduleOptions"
                :key="schedule.value"
                type="text"
                :class="flipFlopItem.schedule.type === schedule.value ? 'text-blue-400' : ''"
                @click="handleOpenModal(schedule.value, flipFlopItem)"
              >
                {{ schedule.label }}
              </div>
            </div>
            <Tooltip title="删除">
              <Icon
                v-if="!disabledDrawer"
                class="ml-2 cursor-pointer"
                icon="fluent:delete-off-20-regular"
                size="20"
                @click="handleDelete(flipFlopItem)"
              />
            </Tooltip>
          </div>
        </header>
      </template>
      <BasicForm
        :ref="(el) => setFlopFlipFormRef(flipFlopItem, el)"
        :key="flipFlopItem.key"
        class="trigger-form"
        layout="horizontal"
        :disabled="disabledDrawer"
        :schemas="formSchemas"
        :showActionButtonGroup="false"
        :baseColProps="{ span: 6, xxl: 6, xl: 8, lg: 12, sm: 24 }"
      >
        <template #conditionFilter="{ model }">
          <ConditionFilter
            :ref="(el) => setFlopFlipConditionRef(flipFlopItem, el)"
            :triggerType="model[FormFieldEnum.CONDITION_VALUE_TYPE]"
            :object-model="model[FormFieldEnum.CONDITION_KEY_DETAIL]"
            :condition-type="model[FormFieldEnum.CONDITION_TYPE]"
          />
        </template>
      </BasicForm>
    </CollapseContainer>
    <Button
      v-if="showAddButton && !disabledDrawer"
      type="primary"
      class="w-full"
      @click="handleAdd"
    >
      <Icon icon="ant-design:plus-outlined" />
      {{ addButtonName }}
    </Button>

    <EnablingRule @register="registerModal" @setting-complete="handleRuleSetting" />
  </section>
</template>

<style lang="less" scoped>
  .trigger-form {
    :deep(.ant-form-item-control-input-content) {
      width: 100%;

      > div > div {
        width: 100%;
      }

      .ant-input-number {
        width: 100% !important;
      }
      // .ant-col {
      //   .ant-row{
      //     .ant-col {
      //       .
      //     }
      //   }
      // }
    }
  }
</style>