mirror of
				https://github.com/strapi/strapi.git
				synced 2025-11-04 03:43:34 +00:00 
			
		
		
		
	
						commit
						1cb6275a16
					
				@ -115,30 +115,6 @@
 | 
			
		||||
      "component": "blog.test-como",
 | 
			
		||||
      "required": false,
 | 
			
		||||
      "min": 2
 | 
			
		||||
    },
 | 
			
		||||
    "temp_one_to_one": {
 | 
			
		||||
      "type": "relation",
 | 
			
		||||
      "relation": "oneToOne",
 | 
			
		||||
      "target": "api::temp.temp",
 | 
			
		||||
      "inversedBy": "one_to_one"
 | 
			
		||||
    },
 | 
			
		||||
    "temp": {
 | 
			
		||||
      "type": "relation",
 | 
			
		||||
      "relation": "manyToOne",
 | 
			
		||||
      "target": "api::temp.temp",
 | 
			
		||||
      "inversedBy": "one_to_many"
 | 
			
		||||
    },
 | 
			
		||||
    "temps": {
 | 
			
		||||
      "type": "relation",
 | 
			
		||||
      "relation": "oneToMany",
 | 
			
		||||
      "target": "api::temp.temp",
 | 
			
		||||
      "mappedBy": "many_to_one"
 | 
			
		||||
    },
 | 
			
		||||
    "many_to_many_temp": {
 | 
			
		||||
      "type": "relation",
 | 
			
		||||
      "relation": "manyToMany",
 | 
			
		||||
      "target": "api::temp.temp",
 | 
			
		||||
      "inversedBy": "many_to_many"
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -9,7 +9,7 @@
 | 
			
		||||
    "description": ""
 | 
			
		||||
  },
 | 
			
		||||
  "options": {
 | 
			
		||||
    "draftAndPublish": true
 | 
			
		||||
    "draftAndPublish": false
 | 
			
		||||
  },
 | 
			
		||||
  "pluginOptions": {},
 | 
			
		||||
  "attributes": {
 | 
			
		||||
@ -17,7 +17,7 @@
 | 
			
		||||
      "type": "string"
 | 
			
		||||
    },
 | 
			
		||||
    "long": {
 | 
			
		||||
      "type": "string"
 | 
			
		||||
      "type": "text"
 | 
			
		||||
    },
 | 
			
		||||
    "email": {
 | 
			
		||||
      "type": "email"
 | 
			
		||||
@ -28,7 +28,7 @@
 | 
			
		||||
    "password": {
 | 
			
		||||
      "type": "password"
 | 
			
		||||
    },
 | 
			
		||||
    "number": {
 | 
			
		||||
    "number_int": {
 | 
			
		||||
      "type": "integer"
 | 
			
		||||
    },
 | 
			
		||||
    "enum": {
 | 
			
		||||
@ -77,39 +77,33 @@
 | 
			
		||||
    "uid": {
 | 
			
		||||
      "type": "uid"
 | 
			
		||||
    },
 | 
			
		||||
    "one_way": {
 | 
			
		||||
      "type": "relation",
 | 
			
		||||
      "relation": "oneToOne",
 | 
			
		||||
      "target": "api::address.address"
 | 
			
		||||
    "number_big": {
 | 
			
		||||
      "type": "biginteger"
 | 
			
		||||
    },
 | 
			
		||||
    "one_to_one": {
 | 
			
		||||
      "type": "relation",
 | 
			
		||||
      "relation": "oneToOne",
 | 
			
		||||
      "target": "api::address.address",
 | 
			
		||||
      "inversedBy": "temp_one_to_one"
 | 
			
		||||
    "number_dec": {
 | 
			
		||||
      "type": "decimal"
 | 
			
		||||
    },
 | 
			
		||||
    "one_to_many": {
 | 
			
		||||
      "type": "relation",
 | 
			
		||||
      "relation": "oneToMany",
 | 
			
		||||
      "target": "api::address.address",
 | 
			
		||||
      "mappedBy": "temp"
 | 
			
		||||
    "number_float": {
 | 
			
		||||
      "type": "float"
 | 
			
		||||
    },
 | 
			
		||||
    "many_to_one": {
 | 
			
		||||
      "type": "relation",
 | 
			
		||||
      "relation": "manyToOne",
 | 
			
		||||
      "target": "api::address.address",
 | 
			
		||||
      "inversedBy": "temps"
 | 
			
		||||
    "enum_req_def": {
 | 
			
		||||
      "type": "enumeration",
 | 
			
		||||
      "enum": [
 | 
			
		||||
        "un",
 | 
			
		||||
        "deux",
 | 
			
		||||
        "trois"
 | 
			
		||||
      ],
 | 
			
		||||
      "required": true,
 | 
			
		||||
      "default": "un"
 | 
			
		||||
    },
 | 
			
		||||
    "many_to_many": {
 | 
			
		||||
      "type": "relation",
 | 
			
		||||
      "relation": "manyToMany",
 | 
			
		||||
      "target": "api::address.address",
 | 
			
		||||
      "inversedBy": "many_to_many_temp"
 | 
			
		||||
    },
 | 
			
		||||
    "many_way": {
 | 
			
		||||
      "type": "relation",
 | 
			
		||||
      "relation": "oneToMany",
 | 
			
		||||
      "target": "api::address.address"
 | 
			
		||||
    "enum_req": {
 | 
			
		||||
      "type": "enumeration",
 | 
			
		||||
      "enum": [
 | 
			
		||||
        "un",
 | 
			
		||||
        "deux",
 | 
			
		||||
        "trois"
 | 
			
		||||
      ],
 | 
			
		||||
      "required": true
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -93,6 +93,7 @@ const EditViewDataManagerProvider = ({
 | 
			
		||||
    const errorsInForm = Object.keys(formErrors);
 | 
			
		||||
 | 
			
		||||
    // TODO check if working with DZ, components...
 | 
			
		||||
    // TODO use querySelector querySelectorAll('[data-strapi-field-error]')
 | 
			
		||||
    if (errorsInForm.length > 0) {
 | 
			
		||||
      const firstError = errorsInForm[0];
 | 
			
		||||
      const el = document.getElementById(firstError);
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,6 @@
 | 
			
		||||
import { get, isArray, isObject } from 'lodash';
 | 
			
		||||
import get from 'lodash/get';
 | 
			
		||||
import isArray from 'lodash/isArray';
 | 
			
		||||
import isObject from 'lodash/isObject';
 | 
			
		||||
 | 
			
		||||
/* eslint-disable indent */
 | 
			
		||||
 | 
			
		||||
@ -23,13 +25,23 @@ const cleanData = (retrievedData, currentSchema, componentsSchema) => {
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          break;
 | 
			
		||||
        case 'date':
 | 
			
		||||
          cleanedData =
 | 
			
		||||
            value && value._isAMomentObject === true ? value.format('YYYY-MM-DD') : value;
 | 
			
		||||
          break;
 | 
			
		||||
        case 'datetime':
 | 
			
		||||
          cleanedData = value && value._isAMomentObject === true ? value.toISOString() : value;
 | 
			
		||||
        // TODO
 | 
			
		||||
        // case 'date':
 | 
			
		||||
        //   cleanedData =
 | 
			
		||||
        //     value && value._isAMomentObject === true ? value.format('YYYY-MM-DD') : value;
 | 
			
		||||
        //   break;
 | 
			
		||||
        // case 'datetime':
 | 
			
		||||
        //   cleanedData = value && value._isAMomentObject === true ? value.toISOString() : value;
 | 
			
		||||
        //   break;
 | 
			
		||||
        case 'time': {
 | 
			
		||||
          cleanedData = value;
 | 
			
		||||
 | 
			
		||||
          if (value && value.split(':').length < 3) {
 | 
			
		||||
            cleanedData = `${value}:00`;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
        case 'media':
 | 
			
		||||
          if (getOtherInfos(schema, [current, 'multiple']) === true) {
 | 
			
		||||
            cleanedData = value ? value.filter(file => !(file instanceof File)) : null;
 | 
			
		||||
 | 
			
		||||
@ -1,16 +1,26 @@
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * Input
 | 
			
		||||
 * GenericInput
 | 
			
		||||
 * This is a temp file move it to the helper plugin when ready
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { useIntl } from 'react-intl';
 | 
			
		||||
import { ToggleInput } from '@strapi/parts/ToggleInput';
 | 
			
		||||
import { TextInput } from '@strapi/parts/TextInput';
 | 
			
		||||
import React, { useState } from 'react';
 | 
			
		||||
import PropTypes from 'prop-types';
 | 
			
		||||
import { useIntl } from 'react-intl';
 | 
			
		||||
import cloneDeep from 'lodash/cloneDeep';
 | 
			
		||||
import { formatISO } from 'date-fns';
 | 
			
		||||
import { DatePicker } from '@strapi/parts/DatePicker';
 | 
			
		||||
import { NumberInput } from '@strapi/parts/NumberInput';
 | 
			
		||||
import { Select, Option } from '@strapi/parts/Select';
 | 
			
		||||
import { Textarea } from '@strapi/parts/Textarea';
 | 
			
		||||
import { TextInput } from '@strapi/parts/TextInput';
 | 
			
		||||
import { TimePicker } from '@strapi/parts/TimePicker';
 | 
			
		||||
import { ToggleInput } from '@strapi/parts/ToggleInput';
 | 
			
		||||
import Hide from '@strapi/icons/Hide';
 | 
			
		||||
import Show from '@strapi/icons/Show';
 | 
			
		||||
 | 
			
		||||
const Input = ({
 | 
			
		||||
const GenericInput = ({
 | 
			
		||||
  autoComplete,
 | 
			
		||||
  customInputs,
 | 
			
		||||
  description,
 | 
			
		||||
  disabled,
 | 
			
		||||
@ -19,12 +29,15 @@ const Input = ({
 | 
			
		||||
  error,
 | 
			
		||||
  name,
 | 
			
		||||
  onChange,
 | 
			
		||||
  options,
 | 
			
		||||
  placeholder,
 | 
			
		||||
  step,
 | 
			
		||||
  type,
 | 
			
		||||
  value,
 | 
			
		||||
  ...rest
 | 
			
		||||
}) => {
 | 
			
		||||
  const { formatMessage } = useIntl();
 | 
			
		||||
  const [showPassword, setShowPassword] = useState(false);
 | 
			
		||||
 | 
			
		||||
  const CustomInput = customInputs ? customInputs[type] : null;
 | 
			
		||||
 | 
			
		||||
@ -46,10 +59,12 @@ const Input = ({
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const label = formatMessage(
 | 
			
		||||
    { id: intlLabel.id, defaultMessage: intlLabel.defaultMessage },
 | 
			
		||||
    { ...intlLabel.values }
 | 
			
		||||
  );
 | 
			
		||||
  const label = intlLabel.id
 | 
			
		||||
    ? formatMessage(
 | 
			
		||||
        { id: intlLabel.id, defaultMessage: intlLabel.defaultMessage },
 | 
			
		||||
        { ...intlLabel.values }
 | 
			
		||||
      )
 | 
			
		||||
    : name;
 | 
			
		||||
 | 
			
		||||
  const hint = description
 | 
			
		||||
    ? formatMessage(
 | 
			
		||||
@ -58,30 +73,6 @@ const Input = ({
 | 
			
		||||
      )
 | 
			
		||||
    : '';
 | 
			
		||||
 | 
			
		||||
  if (type === 'bool') {
 | 
			
		||||
    return (
 | 
			
		||||
      <ToggleInput
 | 
			
		||||
        checked={value || false}
 | 
			
		||||
        disabled={disabled}
 | 
			
		||||
        hint={hint}
 | 
			
		||||
        label={label}
 | 
			
		||||
        labelAction={labelAction}
 | 
			
		||||
        name={name}
 | 
			
		||||
        offLabel={formatMessage({
 | 
			
		||||
          id: 'app.components.ToggleCheckbox.off-label',
 | 
			
		||||
          defaultMessage: 'Off',
 | 
			
		||||
        })}
 | 
			
		||||
        onLabel={formatMessage({
 | 
			
		||||
          id: 'app.components.ToggleCheckbox.on-label',
 | 
			
		||||
          defaultMessage: 'On',
 | 
			
		||||
        })}
 | 
			
		||||
        onChange={e => {
 | 
			
		||||
          onChange({ target: { name, value: e.target.checked } });
 | 
			
		||||
        }}
 | 
			
		||||
      />
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const formattedPlaceholder = placeholder
 | 
			
		||||
    ? formatMessage(
 | 
			
		||||
        { id: placeholder.id, defaultMessage: placeholder.defaultMessage },
 | 
			
		||||
@ -91,34 +82,228 @@ const Input = ({
 | 
			
		||||
 | 
			
		||||
  const errorMessage = error ? formatMessage({ id: error, defaultMessage: error }) : '';
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <TextInput
 | 
			
		||||
      disabled={disabled}
 | 
			
		||||
      error={errorMessage}
 | 
			
		||||
      label={label}
 | 
			
		||||
      labelAction={labelAction}
 | 
			
		||||
      id={name}
 | 
			
		||||
      hint={hint}
 | 
			
		||||
      name={name}
 | 
			
		||||
      onChange={onChange}
 | 
			
		||||
      placeholder={formattedPlaceholder}
 | 
			
		||||
      type={type}
 | 
			
		||||
      value={value || ''}
 | 
			
		||||
    />
 | 
			
		||||
  );
 | 
			
		||||
  switch (type) {
 | 
			
		||||
    case 'bool': {
 | 
			
		||||
      return (
 | 
			
		||||
        <ToggleInput
 | 
			
		||||
          checked={value || false}
 | 
			
		||||
          disabled={disabled}
 | 
			
		||||
          hint={hint}
 | 
			
		||||
          label={label}
 | 
			
		||||
          labelAction={labelAction}
 | 
			
		||||
          name={name}
 | 
			
		||||
          offLabel={formatMessage({
 | 
			
		||||
            id: 'app.components.ToggleCheckbox.off-label',
 | 
			
		||||
            defaultMessage: 'Off',
 | 
			
		||||
          })}
 | 
			
		||||
          onLabel={formatMessage({
 | 
			
		||||
            id: 'app.components.ToggleCheckbox.on-label',
 | 
			
		||||
            defaultMessage: 'On',
 | 
			
		||||
          })}
 | 
			
		||||
          onChange={e => {
 | 
			
		||||
            onChange({ target: { name, value: e.target.checked } });
 | 
			
		||||
          }}
 | 
			
		||||
        />
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
    case 'date': {
 | 
			
		||||
      return (
 | 
			
		||||
        <DatePicker
 | 
			
		||||
          clearLabel={formatMessage({ id: 'clearLabel', defaultMessage: 'Clear' })}
 | 
			
		||||
          disabled={disabled}
 | 
			
		||||
          error={errorMessage}
 | 
			
		||||
          label={label}
 | 
			
		||||
          labelAction={labelAction}
 | 
			
		||||
          id={name}
 | 
			
		||||
          hint={hint}
 | 
			
		||||
          name={name}
 | 
			
		||||
          onChange={date => {
 | 
			
		||||
            const formattedDate = formatISO(cloneDeep(date), { representation: 'date' });
 | 
			
		||||
 | 
			
		||||
            onChange({ target: { name, value: formattedDate, type } });
 | 
			
		||||
          }}
 | 
			
		||||
          onClear={() => onChange({ target: { name, value: '', type } })}
 | 
			
		||||
          placeholder={formattedPlaceholder}
 | 
			
		||||
          selectedDate={value ? new Date(value) : null}
 | 
			
		||||
          selectedDateLabel={formattedDate => `Date picker, current is ${formattedDate}`}
 | 
			
		||||
        />
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
    case 'number': {
 | 
			
		||||
      return (
 | 
			
		||||
        <NumberInput
 | 
			
		||||
          disabled={disabled}
 | 
			
		||||
          error={errorMessage}
 | 
			
		||||
          label={label}
 | 
			
		||||
          labelAction={labelAction}
 | 
			
		||||
          id={name}
 | 
			
		||||
          hint={hint}
 | 
			
		||||
          name={name}
 | 
			
		||||
          onValueChange={value => {
 | 
			
		||||
            onChange({ target: { name, value, type } });
 | 
			
		||||
          }}
 | 
			
		||||
          placeholder={formattedPlaceholder}
 | 
			
		||||
          step={step}
 | 
			
		||||
          value={value || undefined}
 | 
			
		||||
        />
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
    case 'email':
 | 
			
		||||
    case 'text':
 | 
			
		||||
    case 'string': {
 | 
			
		||||
      return (
 | 
			
		||||
        <TextInput
 | 
			
		||||
          autoComplete={autoComplete}
 | 
			
		||||
          disabled={disabled}
 | 
			
		||||
          error={errorMessage}
 | 
			
		||||
          label={label}
 | 
			
		||||
          labelAction={labelAction}
 | 
			
		||||
          id={name}
 | 
			
		||||
          hint={hint}
 | 
			
		||||
          name={name}
 | 
			
		||||
          onChange={onChange}
 | 
			
		||||
          placeholder={formattedPlaceholder}
 | 
			
		||||
          type={type}
 | 
			
		||||
          value={value || ''}
 | 
			
		||||
        />
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
    case 'password': {
 | 
			
		||||
      return (
 | 
			
		||||
        <TextInput
 | 
			
		||||
          autoComplete={autoComplete}
 | 
			
		||||
          disabled={disabled}
 | 
			
		||||
          error={errorMessage}
 | 
			
		||||
          endAction={
 | 
			
		||||
            <button
 | 
			
		||||
              aria-label={formatMessage({
 | 
			
		||||
                id: 'Auth.form.password.show-password',
 | 
			
		||||
                defaultMessage: 'Show password',
 | 
			
		||||
              })}
 | 
			
		||||
              onClick={() => {
 | 
			
		||||
                setShowPassword(prev => !prev);
 | 
			
		||||
              }}
 | 
			
		||||
              style={{
 | 
			
		||||
                border: 'none',
 | 
			
		||||
                padding: 0,
 | 
			
		||||
                background: 'transparent',
 | 
			
		||||
              }}
 | 
			
		||||
              type="button"
 | 
			
		||||
            >
 | 
			
		||||
              {showPassword ? <Show /> : <Hide />}
 | 
			
		||||
            </button>
 | 
			
		||||
          }
 | 
			
		||||
          label={label}
 | 
			
		||||
          labelAction={labelAction}
 | 
			
		||||
          id={name}
 | 
			
		||||
          hint={hint}
 | 
			
		||||
          name={name}
 | 
			
		||||
          onChange={onChange}
 | 
			
		||||
          placeholder={formattedPlaceholder}
 | 
			
		||||
          type={showPassword ? 'text' : 'password'}
 | 
			
		||||
          value={value || ''}
 | 
			
		||||
        />
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
    case 'select': {
 | 
			
		||||
      return (
 | 
			
		||||
        <Select
 | 
			
		||||
          disabled={disabled}
 | 
			
		||||
          error={errorMessage}
 | 
			
		||||
          label={label}
 | 
			
		||||
          labelAction={labelAction}
 | 
			
		||||
          id={name}
 | 
			
		||||
          hint={hint}
 | 
			
		||||
          name={name}
 | 
			
		||||
          onChange={value => {
 | 
			
		||||
            onChange({ target: { name, value: value === '' ? null : value, type: 'select' } });
 | 
			
		||||
          }}
 | 
			
		||||
          placeholder={formattedPlaceholder}
 | 
			
		||||
          value={value || ''}
 | 
			
		||||
        >
 | 
			
		||||
          {options.map(({ metadatas: { intlLabel, disabled, hidden }, key, value }) => {
 | 
			
		||||
            return (
 | 
			
		||||
              <Option key={key} value={value} disabled={disabled} hidden={hidden}>
 | 
			
		||||
                {formatMessage(intlLabel)}
 | 
			
		||||
              </Option>
 | 
			
		||||
            );
 | 
			
		||||
          })}
 | 
			
		||||
        </Select>
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
    case 'textarea': {
 | 
			
		||||
      return (
 | 
			
		||||
        <Textarea
 | 
			
		||||
          disabled={disabled}
 | 
			
		||||
          error={errorMessage}
 | 
			
		||||
          label={label}
 | 
			
		||||
          labelAction={labelAction}
 | 
			
		||||
          id={name}
 | 
			
		||||
          hint={hint}
 | 
			
		||||
          name={name}
 | 
			
		||||
          onChange={onChange}
 | 
			
		||||
          placeholder={formattedPlaceholder}
 | 
			
		||||
          type={type}
 | 
			
		||||
          value={value || ''}
 | 
			
		||||
        >
 | 
			
		||||
          {value}
 | 
			
		||||
        </Textarea>
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
    case 'time': {
 | 
			
		||||
      let time = value;
 | 
			
		||||
 | 
			
		||||
      // The backend send a value which has the following format: '00:45:00.000'
 | 
			
		||||
      // or the time picker only supports hours & minutes so we need to mutate the value
 | 
			
		||||
      if (value && value.split(':').length > 2) {
 | 
			
		||||
        time = time.split(':');
 | 
			
		||||
        time.pop();
 | 
			
		||||
        time = time.join(':');
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return (
 | 
			
		||||
        <TimePicker
 | 
			
		||||
          clearLabel={formatMessage({ id: 'clearLabel', defaultMessage: 'Clear' })}
 | 
			
		||||
          disabled={disabled}
 | 
			
		||||
          error={errorMessage}
 | 
			
		||||
          label={label}
 | 
			
		||||
          labelAction={labelAction}
 | 
			
		||||
          id={name}
 | 
			
		||||
          hint={hint}
 | 
			
		||||
          name={name}
 | 
			
		||||
          onChange={time => {
 | 
			
		||||
            onChange({ target: { name, value: `${time}`, type } });
 | 
			
		||||
          }}
 | 
			
		||||
          onClear={() => {
 | 
			
		||||
            onChange({ target: { name, value: null, type } });
 | 
			
		||||
          }}
 | 
			
		||||
          placeholder={formattedPlaceholder}
 | 
			
		||||
          step={step}
 | 
			
		||||
          value={time}
 | 
			
		||||
        />
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
    default: {
 | 
			
		||||
      return <div>{type} is not supported</div>;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Input.defaultProps = {
 | 
			
		||||
GenericInput.defaultProps = {
 | 
			
		||||
  autoComplete: undefined,
 | 
			
		||||
  customInputs: null,
 | 
			
		||||
  description: null,
 | 
			
		||||
  disabled: false,
 | 
			
		||||
  error: '',
 | 
			
		||||
  labelAction: undefined,
 | 
			
		||||
  placeholder: null,
 | 
			
		||||
  options: [],
 | 
			
		||||
  step: 1,
 | 
			
		||||
  value: '',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Input.propTypes = {
 | 
			
		||||
GenericInput.propTypes = {
 | 
			
		||||
  autoComplete: PropTypes.string,
 | 
			
		||||
  customInputs: PropTypes.object,
 | 
			
		||||
  description: PropTypes.shape({
 | 
			
		||||
    id: PropTypes.string.isRequired,
 | 
			
		||||
@ -135,13 +320,28 @@ Input.propTypes = {
 | 
			
		||||
  labelAction: PropTypes.element,
 | 
			
		||||
  name: PropTypes.string.isRequired,
 | 
			
		||||
  onChange: PropTypes.func.isRequired,
 | 
			
		||||
  options: PropTypes.arrayOf(
 | 
			
		||||
    PropTypes.shape({
 | 
			
		||||
      metadatas: PropTypes.shape({
 | 
			
		||||
        intlLabel: PropTypes.shape({
 | 
			
		||||
          id: PropTypes.string.isRequired,
 | 
			
		||||
          defaultMessage: PropTypes.string.isRequired,
 | 
			
		||||
        }).isRequired,
 | 
			
		||||
        disabled: PropTypes.bool,
 | 
			
		||||
        hidden: PropTypes.bool,
 | 
			
		||||
      }).isRequired,
 | 
			
		||||
      key: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
 | 
			
		||||
      value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
 | 
			
		||||
    }).isRequired
 | 
			
		||||
  ),
 | 
			
		||||
  placeholder: PropTypes.shape({
 | 
			
		||||
    id: PropTypes.string.isRequired,
 | 
			
		||||
    defaultMessage: PropTypes.string.isRequired,
 | 
			
		||||
    values: PropTypes.object,
 | 
			
		||||
  }),
 | 
			
		||||
  step: PropTypes.number,
 | 
			
		||||
  type: PropTypes.string.isRequired,
 | 
			
		||||
  value: PropTypes.any,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default Input;
 | 
			
		||||
export default GenericInput;
 | 
			
		||||
 | 
			
		||||
@ -166,7 +166,7 @@ function Inputs({
 | 
			
		||||
    isRequired,
 | 
			
		||||
  ]);
 | 
			
		||||
 | 
			
		||||
  const { label, description, visible } = metadatas;
 | 
			
		||||
  const { label, description, placeholder, visible } = metadatas;
 | 
			
		||||
 | 
			
		||||
  if (visible === false) {
 | 
			
		||||
    return null;
 | 
			
		||||
@ -218,8 +218,10 @@ function Inputs({
 | 
			
		||||
        // wysiwyg: WysiwygWithErrors,
 | 
			
		||||
        // uid: InputUID,
 | 
			
		||||
        // ...fields,
 | 
			
		||||
        json: () => <div>TODO json</div>,
 | 
			
		||||
        media: () => <div>TODO media</div>,
 | 
			
		||||
        uid: () => <div>TODO uid</div>,
 | 
			
		||||
        wysiwyg: () => <div>TODO wysiwyg</div>,
 | 
			
		||||
      }}
 | 
			
		||||
      multiple={fieldSchema.multiple || false}
 | 
			
		||||
      attribute={fieldSchema}
 | 
			
		||||
@ -227,9 +229,10 @@ function Inputs({
 | 
			
		||||
      onBlur={onBlur}
 | 
			
		||||
      onChange={onChange}
 | 
			
		||||
      options={options}
 | 
			
		||||
      placeholder={placeholder ? { id: placeholder, defaultMessage: placeholder } : null}
 | 
			
		||||
      step={step}
 | 
			
		||||
      type={inputType}
 | 
			
		||||
      validations={validations}
 | 
			
		||||
      // validations={validations}
 | 
			
		||||
      value={inputValue}
 | 
			
		||||
      withDefaultValue={false}
 | 
			
		||||
    />
 | 
			
		||||
 | 
			
		||||
@ -1,19 +1,32 @@
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { FormattedMessage } from 'react-intl';
 | 
			
		||||
 | 
			
		||||
const generateOptions = (options, isRequired = false) => [
 | 
			
		||||
  <FormattedMessage id="components.InputSelect.option.placeholder" key="__enum_option_null">
 | 
			
		||||
    {msg => (
 | 
			
		||||
      <option disabled={isRequired} hidden={isRequired} value="">
 | 
			
		||||
        {msg}
 | 
			
		||||
      </option>
 | 
			
		||||
    )}
 | 
			
		||||
  </FormattedMessage>,
 | 
			
		||||
  ...options.map(v => (
 | 
			
		||||
    <option key={v} value={v}>
 | 
			
		||||
      {v}
 | 
			
		||||
    </option>
 | 
			
		||||
  )),
 | 
			
		||||
];
 | 
			
		||||
const generateOptions = (options, isRequired = false) => {
 | 
			
		||||
  return [
 | 
			
		||||
    {
 | 
			
		||||
      metadatas: {
 | 
			
		||||
        intlLabel: {
 | 
			
		||||
          id: 'components.InputSelect.option.placeholder',
 | 
			
		||||
          defaultMessage: 'Choose here',
 | 
			
		||||
        },
 | 
			
		||||
        disabled: isRequired,
 | 
			
		||||
        hidden: isRequired,
 | 
			
		||||
      },
 | 
			
		||||
      key: '__enum_option_null',
 | 
			
		||||
      value: '',
 | 
			
		||||
    },
 | 
			
		||||
    ...options.map(option => {
 | 
			
		||||
      return {
 | 
			
		||||
        metadatas: {
 | 
			
		||||
          intlLabel: {
 | 
			
		||||
            id: option,
 | 
			
		||||
            defaultMessage: option,
 | 
			
		||||
          },
 | 
			
		||||
          hidden: false,
 | 
			
		||||
          disabled: false,
 | 
			
		||||
        },
 | 
			
		||||
        key: option,
 | 
			
		||||
        value: option,
 | 
			
		||||
      };
 | 
			
		||||
    }),
 | 
			
		||||
  ];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default generateOptions;
 | 
			
		||||
 | 
			
		||||
@ -156,7 +156,7 @@ const EditView = ({
 | 
			
		||||
                                  {grid.map(
 | 
			
		||||
                                    ({ fieldSchema, labelAction, metadatas, name, size }) => {
 | 
			
		||||
                                      return (
 | 
			
		||||
                                        <GridItem col={size} key={name}>
 | 
			
		||||
                                        <GridItem col={size} key={name} s={12} xs={12}>
 | 
			
		||||
                                          <Inputs
 | 
			
		||||
                                            fieldSchema={fieldSchema}
 | 
			
		||||
                                            keys={name}
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,7 @@ import { TimePicker } from '@strapi/parts/TimePicker';
 | 
			
		||||
import { Select, Option } from '@strapi/parts/Select';
 | 
			
		||||
import { useIntl } from 'react-intl';
 | 
			
		||||
import { formatISO } from 'date-fns';
 | 
			
		||||
import { cloneDeep } from 'lodash';
 | 
			
		||||
import cloneDeep from 'lodash/cloneDeep';
 | 
			
		||||
 | 
			
		||||
const Inputs = ({ label, onChange, options, type, value }) => {
 | 
			
		||||
  const { formatMessage } = useIntl();
 | 
			
		||||
 | 
			
		||||
@ -110,6 +110,7 @@ const CMEditViewLocalePicker = ({
 | 
			
		||||
            <Option
 | 
			
		||||
              value={value.value}
 | 
			
		||||
              disabled
 | 
			
		||||
              hidden
 | 
			
		||||
              startIcon={hasDraftAndPublishEnabled ? <Bullet status={currentLocaleStatus} /> : null}
 | 
			
		||||
            >
 | 
			
		||||
              {value.label}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user