index.vue 3.76 KB
<script setup lang="ts">
  import { Collapse } from 'ant-design-vue';
  import { BasicForm, useForm } from '/@/components/Form';
  import { credentialsTypeOptions, FileItemType, formSchemas } from './config';
  import { ref, watch } from 'vue';
  import { buildUUID } from '/@/utils/uuid';
  import { CredentialsTypeEnum, CredentialsTypeNameEnum } from './config';
  import { MqttFieldsEnum } from '../../../../enum/formField/external';

  const props = withDefaults(
    defineProps<{
      value?: Recordable;
    }>(),
    {
      value: () => ({}),
    }
  );

  const activeKey = ref('credentials');

  const type = ref(CredentialsTypeNameEnum.ANONYMOUS);

  const [register, { getFieldsValue, setFieldsValue, validate }] = useForm({
    schemas: formSchemas(setCredentialsType),
    showActionButtonGroup: false,
    layout: 'vertical',
  });

  function setCredentialsType(
    _value: CredentialsTypeEnum,
    option: { label: CredentialsTypeNameEnum; value: CredentialsTypeEnum }
  ) {
    type.value = option.label;
  }

  const getFileValue = (file: FileItemType[]) => {
    return file?.[0]?.data || null;
  };

  const setFileValueByKey = (
    value: Recordable,
    key: MqttFieldsEnum,
    fileNameKey: MqttFieldsEnum
  ) => {
    return value[key]
      ? [{ uid: buildUUID(), name: value[fileNameKey], data: value[key] } as FileItemType]
      : [];
  };

  const getValues = () => {
    const value = getFieldsValue();
    return {
      ...value,
      ...(value?.[MqttFieldsEnum.TYPE] === CredentialsTypeEnum.PEM
        ? {
            [MqttFieldsEnum.CA_CERT]: getFileValue(value?.[MqttFieldsEnum.CA_CERT]),
            [MqttFieldsEnum.CA_CERT]: getFileValue(value?.[MqttFieldsEnum.CERT]),
            [MqttFieldsEnum.PRIVATE_KEY]: getFileValue(value?.[MqttFieldsEnum.PRIVATE_KEY]),
          }
        : {}),
    };
  };

  const setValues = (value: Recordable) => {
    const typeLabel = credentialsTypeOptions.find(
      (item) => item.value === value?.[MqttFieldsEnum.TYPE]
    )?.label;
    type.value = typeLabel!;
    setFieldsValue({
      ...value,
      [MqttFieldsEnum.CA_CERT]: setFileValueByKey(
        value,
        MqttFieldsEnum.CA_CERT,
        MqttFieldsEnum.CA_CERT_FILE_NAME
      ),
      [MqttFieldsEnum.CERT]: setFileValueByKey(
        value,
        MqttFieldsEnum.CERT,
        MqttFieldsEnum.CERT_FILE_NAME
      ),
      [MqttFieldsEnum.PRIVATE_KEY]: setFileValueByKey(
        value,
        MqttFieldsEnum.PRIVATE_KEY,
        MqttFieldsEnum.PRIVATE_KEY_FILE_NAME
      ),
    });
  };

  watch(
    () => props.value,
    (target) => {
      setValues(target);
    }
  );

  defineExpose({
    validate,
    getFieldsValue: getValues,
    setFieldsValue: setValues,
  });
</script>

<template>
  <Collapse v-model:active-key="activeKey" class="credentials-card" expand-icon-position="right">
    <Collapse.Panel :key="activeKey" class="box-shadow bg-light-50 shadow-2xl">
      <template #header>
        <section class="flex w-full h-full h-8 justify-between items-center">
          <div class="w-1/2 text-left">Credentials</div>
          <div class="w-1/2 text-left font-medium text-gray-400">
            {{ type }}
          </div>
        </section>
      </template>
      <BasicForm @register="register" />
    </Collapse.Panel>
  </Collapse>
</template>

<style lang="less" scoped>
  .credentials-card {
    :deep(.ant-collapse) {
      &-header {
        @apply !px-6;
      }

      &-content {
        &-box {
          @apply px-6;
        }
      }
    }

    :deep(.ant-form) {
      > .ant-row {
        > .ant-col {
          > .ant-row {
            > .ant-col {
              min-height: fit-content;
            }
          }
        }
      }
    }
  }

  .box-shadow {
    box-shadow: 0 3px 1px -2px #0003, 0 2px 2px 0 #00000024, 0 1px 5px 0 #0000001f;
  }
</style>