antd#FormItemProps TypeScript Examples

The following examples show how to use antd#FormItemProps. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: JmixFormFieldWrapper.tsx    From jmix-frontend with Apache License 2.0 6 votes vote down vote up
function mergeWithDefaultFormItemProps<FormItemProps = Record<string, any>>(
  entityMetaInfo: MetaClassInfo[],
  entityName: string,
  propertyName: string,
  messages: EntityMessages | null,
  formItemProps?: FormItemProps,
) {
  const defaults = getDefaultFormItemProps(entityMetaInfo, entityName, propertyName, messages);
  const merged = {...defaults, ...formItemProps};

  // TypeScript doesn't know whether `rules` is defined
  if (merged.rules == null) {
    merged.rules = [];
  }

  // Add a passthrough rule. This will clear server-side errors on `validateTrigger` without having to manually set errors on fields.
  merged.rules.push(passthroughRule);

  return merged;
}
Example #2
Source File: index.tsx    From datart with Apache License 2.0 6 votes vote down vote up
SqlOperator: React.FC<SqlOperatorProps> = memo(
  ({ controllerType }) => {
    const tc = useI18NPrefix(`viz.control`);
    const hideForm = FixedSqlOperatorTypes.includes(controllerType);
    const itemProps: FormItemProps<any> = {
      preserve: true,
      name: SqlOperatorName,
      label: tc('sqlOperator'),
      hidden: hideForm,
    };
    const optionKeys: FilterSqlOperator[] =
      SQL_OPERATOR_OPTIONS_TYPES[controllerType] || [];
    const options = ALL_SQL_OPERATOR_OPTIONS.filter(it =>
      optionKeys.includes(it.value),
    );

    return <SqlOperatorForm options={options} {...itemProps} />;
  },
)
Example #3
Source File: index.tsx    From datart with Apache License 2.0 6 votes vote down vote up
MaxValueSetter: React.FC<NumberSetterProps> = memo(({ label }) => {
  const itemProps: FormItemProps<any> = {
    preserve: true,
    name: MaxValueName,
    label: label,
    required: true,
  };
  return <NumberSetForm {...itemProps} />;
})
Example #4
Source File: index.tsx    From datart with Apache License 2.0 6 votes vote down vote up
MinValueSetter: React.FC<NumberSetterProps> = memo(({ label }) => {
  const itemProps: FormItemProps<any> = {
    preserve: true,
    name: MinValueName,
    label: label,
    required: true,
  };
  return <NumberSetForm {...itemProps} />;
})
Example #5
Source File: index.tsx    From datart with Apache License 2.0 6 votes vote down vote up
NumberSetter: React.FC<NumberSetterProps> = ({ label }) => {
  const itemProps: FormItemProps<any> = {
    preserve: true,
    name: ControllerValuesName,
    label: label,
    required: false,
  };
  return <NumberSetForm {...itemProps} />;
}
Example #6
Source File: RangeNumberSet.tsx    From datart with Apache License 2.0 6 votes vote down vote up
RangeNumberSetter: React.FC<{}> = memo(() => {
  const tc = useI18NPrefix(`viz.control`);
  const itemProps: FormItemProps<any> = {
    preserve: true,
    name: ControllerValuesName,
    label: tc('defaultValue'),
    required: false,
  };
  return <RangeNumberSetForm {...itemProps} />;
})
Example #7
Source File: SliderSet.tsx    From datart with Apache License 2.0 6 votes vote down vote up
SliderSetter: React.FC<SliderSetFormProps> = memo(props => {
  const itemProps: FormItemProps<any> = {
    preserve: true,
    name: ControllerValuesName,
    label: props.label,
    required: true,
  };
  return <SliderSetForm {...itemProps} {...props} />;
})
Example #8
Source File: SliderSet.tsx    From datart with Apache License 2.0 6 votes vote down vote up
RangeSliderSetter: React.FC<SliderSetFormProps> = memo(props => {
  const itemProps: FormItemProps<any> = {
    preserve: true,
    name: ControllerValuesName,
    label: props.label,
    required: false,
  };
  return <RangeSliderSetForm {...itemProps} {...props} />;
})
Example #9
Source File: index.tsx    From datart with Apache License 2.0 6 votes vote down vote up
TextSetter: React.FC<TextSetterProps> = memo(() => {
  const tc = useI18NPrefix(`viz.control`);
  const itemProps: FormItemProps<any> = {
    preserve: true,
    name: ControllerValuesName,
    label: tc('defaultValue'),
    required: false,
  };
  return <TextSetForm {...itemProps} />;
})
Example #10
Source File: index.tsx    From condo with MIT License 5 votes vote down vote up
TicketFormItem: React.FC<FormItemProps> = (props) => (
    <Form.Item labelCol={FORM_FILED_COL_PROPS} wrapperCol={FORM_FILED_COL_PROPS} {...props} />
)
Example #11
Source File: FormItemEx.tsx    From datart with Apache License 2.0 5 votes vote down vote up
FormItemEx: FC<FormItemProps> = memo(({ children, ...rest }) => {
  return <StyledFromItemEx {...rest}>{children}</StyledFromItemEx>;
})
Example #12
Source File: BasicWrapper.tsx    From datart with Apache License 2.0 5 votes vote down vote up
export function BW(props: FormItemProps) {
  return <Wrapper {...props} colon={false} />;
}
Example #13
Source File: EditableTable.tsx    From amiya with MIT License 5 votes vote down vote up
export function EditableRowCell(props: AnyKeyProps) {
  const { field, record, children, tableData, setTableData, tableProps, ...restProps } = props
  const form = useContext(EditableContext)
  const editing = record?.editing || false
  let tag: ReactNode

  useEffect(() => {
    if (editing) {
      // 设置表单数据
      form.setFieldsValue({ ...record })
    }
  }, [editing])

  const handleSave = async () => {
    // 获取表单数据
    const values = await form.validateFields()
    // 将表单数据与行数据合并
    const newRow = { ...record, ...values }
    // 重新构建数组
    const newTableData = [...tableData]
    // 寻找到对应行
    const index = newTableData.findIndex(row => getKey(row, tableProps.rowKey) === getKey(newRow, tableProps.rowKey))
    // 替换行
    newTableData.splice(index, 1, newRow)
    // 替换表格数据
    setTableData(newTableData)
  }

  let cell = children[1]

  if (cell && typeof cell === 'function') {
    // 获取表格
    const cellTag = cell({ editing, form, mode: 'row' })
    if (editing) {
      tag = (
        <Form.Item
          hasFeedback
          _internalItemRender={{
            mark: 'pro_table_render',
            render: (
              inputProps: FormItemProps & {
                errors: any[]
              },
              doms: {
                input: JSX.Element
                errorList: JSX.Element
                extra: JSX.Element
              }
            ) => <RuleFormItem inputProps={inputProps} {...doms} popoverProps={field.popoverProps} />
          }}
          name={field.key}
          style={{ margin: '-5px 0' }}
          {...field.formItemProps}
        >
          {cellTag}
        </Form.Item>
      )
    } else {
      tag = <div className="editable-row-cell">{cellTag}</div>
    }
  } else {
    if (!field) {
      // 普通的表格元素
      tag = children
    }
  }

  // 前置元素
  const before = field?.before ? field.before({ record, field, refreshRow: handleSave }) : null
  // 后置元素
  const after = field?.after ? field.after({ record, field, refreshRow: handleSave }) : null

  return (
    <td {...restProps}>
      {before}
      {tag}
      {after}
    </td>
  )
}
Example #14
Source File: ContextItemForm.tsx    From next-basics with GNU General Public License v3.0 4 votes vote down vote up
export function ContextItemForm({
  data,
  onContextItemUpdate,
  settingItemForm,
}: ContextItemFormProps): React.ReactElement {
  const { providerList, highlightTokens, onClickHighlightToken } =
    useBuilderUIContext();
  const originalProviderList = useMemo(
    () =>
      (providerList ?? []).map((provider) => ({
        label: provider,
        value: provider,
      })),
    [providerList]
  );
  const [providerOptions, setProviderOptions] = useState(originalProviderList);
  const [contextType, setContextType] = useState(ContextType.VALUE);
  const [errorFields, setErrorFields] = useState<
    Record<string, { help: string }>
  >({});

  const getFormItemProps = (
    name: string,
    text: string | boolean = true
  ): FormItemProps => {
    let label = name;
    if (typeof text === "string") {
      label = text;
    } else if (text) {
      label = name[0].toUpperCase() + name.substr(1);
    }
    return {
      name,
      label,
      validateStatus: errorFields[name] ? "error" : "success",
      help: errorFields[name]?.help,
    };
  };

  const typeOptions = useMemo(() => {
    return [
      { label: "Value", value: ContextType.VALUE },
      { label: "Provider", value: ContextType.RESOLVE },
      { label: "FlowApi", value: ContextType.FLOW_API },
      ...((data?.resolve as SelectorProviderResolveConf)?.provider
        ? [
            {
              label: "Provider Selector",
              value: ContextType.SELECTOR_RESOLVE,
            },
          ]
        : []),
    ];
  }, [data]);

  useEffect(() => {
    const isValue = !data?.resolve;
    const type = isValue
      ? ContextType.VALUE
      : (data.resolve as SelectorProviderResolveConf).provider
      ? ContextType.SELECTOR_RESOLVE
      : (data.resolve as UseProviderResolveConf).useProvider?.includes("@")
      ? ContextType.FLOW_API
      : ContextType.RESOLVE;
    setContextType(type);
  }, [data]);

  const onTypeChange = (event: RadioChangeEvent): void => {
    setContextType(event.target.value);
  };

  const onSearch = (v: string): void => {
    const q = v.trim().toLowerCase();
    setProviderOptions(
      originalProviderList.filter((opt) => opt.label.includes(q))
    );
  };

  useEffect(() => {
    setProviderOptions(originalProviderList);
  }, [originalProviderList]);

  const onSettingFormFinish = (values: ContextItemFormValue): void => {
    const computedValue = computeItemToSubmit(values);
    if ("error" in computedValue) {
      setErrorFields(computedValue.errorFields);
      return;
    }
    setErrorFields({});
    onContextItemUpdate?.(computedValue);
  };

  const handleCodeChange = (field: string): void => {
    if (errorFields[field]) {
      delete errorFields[field];
      setErrorFields({ ...errorFields });
    }
  };

  const getCodeEditorItem = (
    field: string,
    realField?: string
  ): React.ReactNode => {
    return (
      <CodeEditorItem
        tabSize={2}
        minLines={5}
        maxLines={12}
        printMargin={false}
        showLineNumbers={true}
        theme="tomorrow"
        enableLiveAutocompletion={true}
        mode="brick_next_yaml"
        schemaRef={fieldCodeEditorConfigMap[field].schemaRef}
        highlightTokens={highlightTokens}
        onClickHighlightToken={onClickHighlightToken}
        onChange={() => handleCodeChange(realField ?? field)}
      ></CodeEditorItem>
    );
  };

  return (
    <Form
      layout="vertical"
      name="settingItemForm"
      form={settingItemForm}
      onFinish={onSettingFormFinish}
    >
      <Form.Item
        name="name"
        label="Name"
        rules={[{ required: true, message: "Name is required!" }]}
      >
        <Input />
      </Form.Item>
      <Form.Item {...getFormItemProps("type")}>
        <Radio.Group
          options={typeOptions}
          optionType="button"
          onChange={onTypeChange}
        >
          {typeOptions.map((v) => (
            <Radio.Button value={v.value} key={v.value}>
              {v.label}
            </Radio.Button>
          ))}
        </Radio.Group>
      </Form.Item>
      {contextType === ContextType.VALUE ? (
        <Form.Item {...getFormItemProps("value")}>
          {getCodeEditorItem("value")}
        </Form.Item>
      ) : (
        <>
          {contextType === ContextType.SELECTOR_RESOLVE ? (
            <Form.Item
              {...getFormItemProps("provider")}
              rules={[{ required: true, message: "Provider is required!" }]}
            >
              <Input />
            </Form.Item>
          ) : contextType === ContextType.FLOW_API ? (
            <Form.Item
              label="flowApi"
              name="flowApi"
              rules={[
                { required: true, message: "Please select a flowAPi!" },
                { validator: checkContractRule },
              ]}
            >
              <ContractAutoComplete />
            </Form.Item>
          ) : (
            <Form.Item
              label="useProvider"
              name="useProvider"
              rules={[{ required: true, message: "Please select a provider!" }]}
            >
              <AutoComplete options={providerOptions} onSearch={onSearch} />
            </Form.Item>
          )}
          <Form.Item {...getFormItemProps("args")}>
            {getCodeEditorItem("args")}
          </Form.Item>
          <Form.Item {...getFormItemProps("transform")}>
            {getCodeEditorItem("transform")}
          </Form.Item>
          <Form.Item {...getFormItemProps("onReject", false)}>
            {getCodeEditorItem("onReject")}
          </Form.Item>
          <Form.Item {...getFormItemProps("resolveIf", "If of resolve")}>
            {getCodeEditorItem("if", "resolveIf")}
          </Form.Item>
          <Form.Item
            {...getFormItemProps("value", "Fallback value")}
            tooltip="The value of context will fallback to this value when the if of resolve is false."
          >
            {getCodeEditorItem("value")}
          </Form.Item>
        </>
      )}
      <Form.Item {...getFormItemProps("if")}>
        {getCodeEditorItem("if")}
      </Form.Item>
      <Form.Item {...getFormItemProps("onChange", false)}>
        {getCodeEditorItem("onChange")}
      </Form.Item>
    </Form>
  );
}
Example #15
Source File: ConfigurableFieldsForm.tsx    From jitsu with MIT License 4 votes vote down vote up
ConfigurableFieldsFormComponent = ({
  fieldsParamsList,
  form,
  extraForms,
  initialValues,
  availableOauthBackendSecrets,
  hideFields,
  handleTouchAnyField,
  setFormValues,
  setInitialFormValues,
}: Props) => {
  const [debugModalsStates, setDebugModalsStates] = useState<{ [id: string]: boolean }>({})
  const [debugModalsValues, setDebugModalsValues] = useState<{ [id: string]: string }>({})

  const forceUpdateAll = useForceUpdate()
  const { forceUpdatedTargets, forceUpdateTheTarget } = useForceUpdateTarget()

  const handleTouchField = debounce(handleTouchAnyField ?? (() => {}), 1000)

  const handleChangeIntInput = useCallback(
    (id: string) => (value: number) => {
      form.setFieldsValue({ [id]: value })
    },
    [form]
  )

  const handleChangeTextInput = useCallback(
    (id: string) => (value: string) => {
      form.setFieldsValue({ [id]: value })
    },
    [form]
  )

  const handleChangeSwitch = useCallback(
    (id: string) => (value: boolean) => {
      form.setFieldsValue({ [id]: value })
      handleTouchAnyField?.()
      forceUpdateAll()
      handleTouchField()
    },
    [form, forceUpdateAll]
  )
  const handleOpenDebugger = useCallback(
    (id: string) => {
      setDebugModalsValues({ ...debugModalsValues, [id]: form.getFieldValue(id) })
      setDebugModalsStates({ ...debugModalsStates, [id]: true })
    },
    [form]
  )

  const handleJsonChange = (id: string) => (value: string) => {
    const values = {
      [id]: value ? value : "",
    }
    form.setFieldsValue(values)
    setFormValues?.(form.getFieldsValue())
    handleTouchField()
  }

  const getInitialValue = (id: string, defaultValue: any, constantValue: any, type: string) => {
    const initial = get(initialValues, id)
    if (typeof initial !== "undefined") {
      return initial
    }

    let calcValue: any
    if (typeof defaultValue !== "undefined") {
      calcValue = defaultValue
    } else if (typeof constantValue !== "undefined") {
      calcValue = constantValue
    } else if (type === "boolean") {
      calcValue = false
    } else if (type === "json") {
      calcValue = {}
    } else if (type === "javascript") {
      calcValue = "return {}"
    } else if (type === "html") {
      calcValue = "<script>\n</script>"
    } else if (type.indexOf("array/") === 0) {
      calcValue = []
    } else {
      calcValue = ""
    }

    return type === "json" ? JSON.stringify(calcValue) : calcValue
  }

  const getFieldComponent = (
    type: ParameterType<any>,
    id: string,
    defaultValue?: any,
    constantValue?: any,
    jsDebugger?: "object" | "string" | null,
    bigField?: boolean,
    displayName?: string,
    codeSuggestions?: string,
    documentation?: React.ReactNode,
    validationRules?: FormItemProps["rules"]
  ) => {
    const defaultValueToDisplay =
      form.getFieldValue(id) ?? getInitialValue(id, defaultValue, constantValue, type?.typeName)
    form.setFieldsValue({ ...form.getFieldsValue(), [id]: defaultValueToDisplay })

    const className = hideFields?.some(field => field === getFieldNameById(id)) ? "hidden" : ""

    const formItemWrapperProps: FormItemWrapperProps = {
      type,
      id,
      bigField,
      displayName,
      documentation,
      validationRules,
      className,
    }

    switch (type?.typeName) {
      case "password":
        return (
          <FormItemWrapper key={id} {...formItemWrapperProps}>
            <Input.Password
              autoComplete="off"
              iconRender={visible => (visible ? <EyeOutlined /> : <EyeInvisibleOutlined />)}
            />
          </FormItemWrapper>
        )

      case "int": {
        return (
          <FormItemWrapper key={id} {...formItemWrapperProps}>
            <InputNumber autoComplete="off" inputMode="numeric" onChange={handleChangeIntInput(id)} />
          </FormItemWrapper>
        )
      }

      case "selection": {
        return (
          <FormItemWrapper key={id} {...formItemWrapperProps}>
            <Select
              allowClear
              mode={type.data.maxOptions > 1 ? "multiple" : undefined}
              onChange={() => forceUpdateTheTarget("select")}
            >
              {type.data.options.map(({ id, displayName }: Option) => {
                return (
                  <Select.Option value={id} key={id}>
                    {displayName}
                  </Select.Option>
                )
              })}
            </Select>
          </FormItemWrapper>
        )
      }
      case "array/string":
        return (
          <FormItemWrapper key={id} {...formItemWrapperProps}>
            <EditableList initialValue={defaultValueToDisplay} />
          </FormItemWrapper>
        )
      case "javascript":
      case "html":
      case "json": {
        return (
          <FormItemWrapper key={id} {...formItemWrapperProps}>
            <CodeEditor
              initialValue={defaultValueToDisplay}
              className={styles.codeEditor}
              extraSuggestions={codeSuggestions}
              language={type?.typeName}
              handleChange={handleJsonChange(id)}
            />
            <span className="z-50">
              {jsDebugger && (
                <>
                  {bigField ? (
                    <Button
                      size="large"
                      className="absolute mr-0 mt-0 top-0 right-0"
                      type="text"
                      onClick={() => handleOpenDebugger(id)}
                      icon={<CodeOutlined />}
                    >
                      Open Debugger
                    </Button>
                  ) : (
                    <Tooltip title="Debug expression">
                      <span className="absolute top-1.5 right-3">
                        <BugIcon onClick={() => handleOpenDebugger(id)} className={styles.bugIcon} />
                      </span>
                    </Tooltip>
                  )}
                </>
              )}
            </span>
          </FormItemWrapper>
        )
      }

      case "boolean":
        return (
          <FormItemWrapper key={id} {...formItemWrapperProps}>
            {bigField ? (
              <SwitchWithLabel
                label={displayName}
                id={id}
                onChange={handleChangeSwitch(id)}
                defaultChecked={!!defaultValueToDisplay}
              />
            ) : (
              <Switch className={"mb-0.5"} onChange={handleChangeSwitch(id)} defaultChecked={!!defaultValueToDisplay} />
            )}
          </FormItemWrapper>
        )

      case "file":
        return (
          <FormItemWrapper key={id} {...formItemWrapperProps}>
            <InputWithUpload onChange={handleChangeTextInput(id)} value={defaultValueToDisplay} />
          </FormItemWrapper>
        )

      case "description":
        return (
          <div key={id} className="ant-row ant-form-item form-field_fixed-label">
            <div className="ant-col ant-col-4 ant-form-item-label">
              <label>{displayName}:</label>
            </div>
            <div className="ant-col ant-col-20 ant-form-item-control pt-1.5">{defaultValue}</div>
          </div>
        )

      case "oauthSecret":
      case "string":
      default: {
        const backendSecretAvailable =
          type?.typeName === "oauthSecret" &&
          (availableOauthBackendSecrets === "all_from_config" ||
            availableOauthBackendSecrets?.some(name => getFieldNameById(id) === name))
        if (backendSecretAvailable) {
          formItemWrapperProps.validationRules = validationRules.filter(value => !value["required"])
        }
        const placeholder = backendSecretAvailable
          ? "Leave this field empty to use a value provided by Jitsu"
          : undefined
        return (
          <FormItemWrapper key={id} {...formItemWrapperProps}>
            <InputWithDebug
              id={id}
              placeholder={placeholder}
              jsDebugger={jsDebugger}
              onButtonClick={() => handleOpenDebugger(id)}
            />
          </FormItemWrapper>
        )
      }
    }
  }

  const handleDebuggerRun = async (field: string, debuggerType: "object" | "string", values: DebuggerFormValues) => {
    let transform = {}
    if (field === "_transform") {
      transform = {
        _transform_enabled: true,
        _transform: values.code,
      }
    }
    const configForm = extraForms && extraForms[0]
    const mappingForm = extraForms && extraForms[1]

    const data = {
      reformat: debuggerType == "string",
      uid: initialValues._uid,
      type: initialValues._type,
      field: field,
      expression: values.code,
      object: JSON.parse(values.object),
      config: makeObjectFromFieldsValues({
        ...initialValues,
        ...configForm?.getFieldsValue(),
        ...mappingForm?.getFieldsValue(),
        ...transform,
      }),
      template_variables: Object.entries((configForm || form).getFieldsValue())
        .filter(v => v[0].startsWith("_formData._"))
        .reduce((accumulator: any, currentValue: [string, unknown]) => {
          set(accumulator, currentValue[0].replace("_formData._", ""), currentValue[1])
          return accumulator
        }, {}),
    }

    return services.backendApiClient.post(`/destinations/evaluate?project_id=${services.activeProject.id}`, data)
  }

  const handleCloseDebugger = id => setDebugModalsStates({ ...debugModalsStates, [id]: false })

  const handleSaveDebugger = (id, value: string) => {
    form.setFieldsValue({ [id]: value })
    handleCloseDebugger(id)
  }

  /**
   * Runs after every re-render caused by `Select` field change
   * to pick up the values of conditionally rendered fields.
   */
  useEffect(() => {
    const isInitialRender = !forceUpdatedTargets["select"]
    if (!isInitialRender) setFormValues?.(form.getFieldsValue())
  }, [forceUpdatedTargets["select"]])

  useEffect(() => {
    /**
     *
     * 1st render:
     * component creates fields, fills them with values,
     * lets the `form` instance to pick them
     *
     */
    let formValues = {}
    const formFields: Parameters<typeof form.setFields>[0] = []
    fieldsParamsList.forEach((param: Parameter) => {
      const initConfig = makeObjectFromFieldsValues(formValues)
      const fieldNeeded = !param.omitFieldRule?.(initConfig)
      const id = param.id

      const constantValue = typeof param.constant === "function" ? param.constant?.(initConfig) : param.constant
      const initialValue = getInitialValue(id, param.defaultValue, constantValue, param.type?.typeName)

      if (fieldNeeded) {
        formValues[id] = initialValue
        formFields.push({
          name: id,
          value: initialValue,
          touched: false,
        })
      }
    })

    form.setFields(formFields)

    /**
     * @reason
     * `formValues` holds correct values for dynamically rendered fields
     * @warning
     * Using `form.getFieldsValue()` instead of `formValues` is not recommended because
     * it needs form to re-render once to pick up values of dynamically rendered fields
     */
    setInitialFormValues?.(formValues)

    /**
     *
     * 2nd render: component removes/adds fields conditionally
     *  depending on the form values
     *
     */
    forceUpdateAll()
  }, [])

  return (
    <>
      {fieldsParamsList.map(
        ({
          id,
          documentation,
          displayName,
          type,
          defaultValue,
          required,
          constant,
          omitFieldRule,
          jsDebugger,
          bigField,
          codeSuggestions,
          validator,
        }: Parameter) => {
          const currentFormValues = form.getFieldsValue() ?? {}
          const defaultFormValues = fieldsParamsList.reduce(
            (result, { id, defaultValue }) => ({
              ...result,
              [id]: defaultValue,
            }),
            {}
          )
          const formItemName = id
          const formValues = {
            ...defaultFormValues,
            ...currentFormValues,
          }
          const parsedFormValues = makeObjectFromFieldsValues(formValues)
          const constantValue = typeof constant === "function" ? constant?.(parsedFormValues) : constant
          const isHidden = constantValue !== undefined
          const isOmitted = omitFieldRule ? omitFieldRule(parsedFormValues) : false

          const validationRules: FormItemProps["rules"] = []
          if (!isHidden) {
            const isRequired = typeof required === "boolean" ? required : required?.(parsedFormValues)
            if (isRequired)
              validationRules.push({
                required: true,
                message: `${displayName} field is required.`,
              })
            if (type?.typeName === "isoUtcDate")
              validationRules.push(isoDateValidator(`${displayName} field is required.`))
          }
          if (validator) {
            validationRules.push({ validator: validator })
          }

          return isOmitted ? null : !isHidden ? (
            <Row key={id} className={cn(isHidden && "hidden")}>
              <Col span={24}>
                {jsDebugger ? (
                  <CodeDebuggerModal
                    visible={debugModalsStates[id]}
                    codeFieldLabelDebugger="Expression"
                    extraSuggestionsDebugger={codeSuggestions}
                    defaultCodeValueDebugger={debugModalsValues[id]}
                    handleCloseDebugger={() => handleCloseDebugger(id)}
                    runDebugger={values => handleDebuggerRun(id, jsDebugger, values)}
                    handleSaveCodeDebugger={value => handleSaveDebugger(id, value)}
                  />
                ) : null}
                {getFieldComponent(
                  type,
                  id,
                  defaultValue,
                  constantValue,
                  jsDebugger,
                  bigField,
                  displayName,
                  codeSuggestions,
                  documentation,
                  validationRules
                )}
              </Col>
            </Row>
          ) : (
            <Form.Item key={formItemName} name={formItemName} hidden={true} initialValue={constantValue} />
          )
        }
      )}
    </>
  )
}
Example #16
Source File: index.tsx    From datart with Apache License 2.0 4 votes vote down vote up
export function ConfigComponent({
  attr,
  form,
  sourceId,
  testLoading,
  disabled,
  allowManage,
  schemaDataSource,
  subFormRowKey,
  subFormRowKeyValidator,
  onTest,
  onSubFormTest,
  onDbTypeChange,
}: ConfigComponentProps) {
  const {
    name,
    displayName,
    description,
    required,
    defaultValue,
    type,
    options,
  } = attr;
  let component: ReactElement | null = null;
  let extraFormItemProps: Partial<FormItemProps> = {};
  const t = useI18NPrefix('source');
  const tg = useI18NPrefix('global');

  switch (name) {
    case 'url':
      component = (
        <Input
          suffix={
            <Button
              type="link"
              size="small"
              loading={testLoading}
              onClick={onTest}
            >
              {t('form.test')}
            </Button>
          }
          disabled={disabled}
        />
      );
      break;
    case 'dbType':
      component = (
        <Select
          disabled={disabled}
          onChange={onDbTypeChange}
          showSearch
          allowClear
        >
          {options?.map(({ dbType }) => (
            <Select.Option key={dbType} value={dbType}>
              {dbType}
            </Select.Option>
          ))}
        </Select>
      );
      break;
    case 'path':
      component = (
        <FileUpload
          form={form}
          sourceId={sourceId}
          loading={testLoading}
          onTest={onTest}
        />
      );
      break;
    case 'format':
      break;
    default:
      switch (type) {
        case 'string':
          if (options && options.length > 0) {
            if (options.length > 3) {
              component = (
                <Select disabled={disabled} showSearch allowClear>
                  {options.map(o => (
                    <Select.Option key={o} value={o}>
                      {o}
                    </Select.Option>
                  ))}
                </Select>
              );
            } else {
              component = (
                <Radio.Group disabled={disabled}>
                  {options.map(o => (
                    <Radio key={o} value={o}>
                      {o}
                    </Radio>
                  ))}
                </Radio.Group>
              );
            }
          } else {
            component = <Input disabled={disabled} />;
          }
          break;
        case 'password':
          component = (
            <Input.Password disabled={disabled} autoComplete="new-password" />
          );
          break;
        case 'bool':
          component = <Switch disabled={disabled} />;
          extraFormItemProps.valuePropName = 'checked';
          break;
        case 'object':
          component = (
            <Properties disabled={disabled} allowManage={allowManage} />
          );
          extraFormItemProps.initialValue = {};
          extraFormItemProps.wrapperCol = { span: 16 };
          break;
        case 'array':
        case 'files':
          component = (
            <ArrayConfig
              attr={attr}
              sourceId={sourceId}
              testLoading={testLoading}
              disabled={disabled}
              allowManage={allowManage}
              onSubFormTest={onSubFormTest}
            />
          );
          extraFormItemProps.initialValue = [];
          extraFormItemProps.wrapperCol = { span: 12 };
          break;
        case 'schema':
          component = <SchemaComponent dataSource={schemaDataSource} />;
          extraFormItemProps.wrapperCol = { span: 16 };
          break;
        default:
          return null;
      }
      break;
  }

  let rules: Rule[] = [];

  if (required) {
    rules.push({
      required: true,
      message: `${name}${tg('validation.required')}`,
    });
  }

  if (subFormRowKey === name) {
    rules.push({
      validator: (_, value) => {
        const valid = subFormRowKeyValidator && subFormRowKeyValidator(value);
        return valid
          ? Promise.resolve()
          : Promise.reject(new Error(t('form.duplicateName')));
      },
    });
  }

  return !['path', 'format'].includes(name) ? (
    <Form.Item
      name={['config', name]}
      label={displayName}
      initialValue={defaultValue}
      extra={description}
      rules={rules}
      {...extraFormItemProps}
    >
      {component}
    </Form.Item>
  ) : (
    component
  );
}