Commit d45998a4 authored by Ryo Yamashita's avatar Ryo Yamashita Committed by Yas Naoi
Browse files

Issue #3325264 by Ryo Yamashita, yas: Add 'item-array' form type into Cloud Dashboard

parent efc76a28
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
@@ -57,8 +57,18 @@ const AWS_CLOUD_VPC_TEMPLATE: EntityFormTemplate[] = [
        type: 'panel',
        panelName: 'CIDR Blocks',
        keyValueRecords: [
          { type: 'cidr', labelName: 'IPv4 CIDR', name: 'cidr_blocks', defaultValue: [] },
          { type: 'cidr', labelName: 'IPv6 CIDR', name: 'ipv6_cidr_blocks', defaultValue: [] },
          { type: 'item-array', labelName: 'IPv4 CIDR', name: 'cidr_blocks', defaultValue: [], info: [
            { labelName: 'CIDR', name: 'cidr', },
            { labelName: 'State', name: 'state', readOnly: true },
            { labelName: 'Status reason', name: 'status_message', readOnly: true },
            { labelName: 'Association ID', name: 'association_id', readOnly: true },
          ] },
          { type: 'item-array', labelName: 'IPv6 CIDR', name: 'ipv6_cidr_blocks', defaultValue: [], info: [
            { labelName: 'CIDR', name: 'cidr', },
            { labelName: 'State', name: 'state', readOnly: true },
            { labelName: 'Status reason', name: 'status_message', readOnly: true },
            { labelName: 'Association ID', name: 'association_id', readOnly: true },
          ] },
        ]
      }
    ]
+0 −8
Original line number Diff line number Diff line
type CidrBlock = {
  cidr: string,
  state: string,
  status_message: string,
  association_id: string,
}

export default CidrBlock;
+6 −6
Original line number Diff line number Diff line
@@ -4,7 +4,8 @@

import KeyValueItem from 'model/KeyValueItem';
import SecurityGroupPermission from 'model/SecurityGroupPermission';
import CidrBlock from "./CidrBlock";



type EntityFormColumnBase = {
  labelName: string,
@@ -59,6 +60,10 @@ type EntityFormColumnInfo = {
  type: 'boolean',
  defaultValue: boolean,
  labels?: [string, string],
} | {
  type: 'item-array',
  info: { labelName: string, name: string, readOnly?: boolean }[],
  defaultValue: { labelName: string, name: string, }[],
};


@@ -83,11 +88,6 @@ type EntityFormColumn = (EntityFormColumnBase & EntityFormColumnInfo) | {
  type: 'file',
  labelName: string,
  name: string,
} | {
  type: 'cidr',
  labelName: string,
  name: string,
  defaultValue: CidrBlock[],
};

export default EntityFormColumn;
+6 −4
Original line number Diff line number Diff line
import EntityFormColumn from 'model/EntityFormColumn';
import BooleanInputBlock from 'molecules/BooleanInputBlock';
import CidrInputBlock from 'molecules/CidrInputBlock';
import DateTimeInputBlock from 'molecules/DateTimeInputBlock';
import FileInputBlock from 'molecules/FileInputBlock';
import HiddenBlock from 'molecules/HiddenBlock';
import JoinSelectBlock from 'molecules/JoinSelectBlock';
import KeyValueTableBlock from 'molecules/KeyValueTableBlock';
import LabelBlock from 'molecules/LabelBlock';
import MultiItemInputBlock from 'molecules/MultiItemInputBlock';
import MultiNumberInputBlock from 'molecules/MultiNumberInputBlock';
import MultiStringInputBlock from 'molecules/MultiStringInputBlock';
import NumberInputBlock from 'molecules/NumberInputBlock';
@@ -212,11 +212,13 @@ const EntityFormBlock = ({ keyValueRecord, cloudContext, formData, setFormData }
        value={value}
        defaultValue={keyValueRecord.defaultValue ?? ''}
        setValue={setValue} />;
    case 'cidr':
      return <CidrInputBlock
    case 'item-array':
      return <MultiItemInputBlock
        label={keyValueRecord.labelName}
        setValue={setValue}
        value={Array.isArray(value) ? value : []} />;
        value={Array.isArray(value) ? value : []}
        info={keyValueRecord.info}
      />;
    default:
      return <></>;
  }
+62 −39
Original line number Diff line number Diff line
import CidrBlock from 'model/CidrBlock';
import { Button, Col, Row, Table } from 'react-bootstrap';
import { BsTrashFill } from 'react-icons/bs';

type ItemBlock = Record<string, string>;

const StringInput = ({ label, placeholder, value, setValue, readOnly }: {
  label: string,
  placeholder?: string,
@@ -20,51 +21,72 @@ const StringInput = ({ label, placeholder, value, setValue, readOnly }: {
  </Col>;
}

const CidrForm = ({ value, setValue }: {
  value: CidrBlock,
  setValue: (s: CidrBlock) => void,
const ItemForm = ({ value, setValue, info }: {
  value: ItemBlock,
  setValue: (s: ItemBlock) => void,
  info: { labelName: string, name: string, readOnly?: boolean, }[],
}) => {
  const setSingleValue = (key: string, s: string) => {
    const newValue: { [key: string]: any } = JSON.parse(JSON.stringify(value));
    newValue[key] = s;
    setValue(newValue as CidrBlock);
    setValue(newValue as ItemBlock);
  }
  return <>
    <StringInput label="CIDR" value={value.cidr} setValue={(s) => setSingleValue('cidr', s)} />
    <StringInput label="State" value={value.state} setValue={(s) => setSingleValue('state', s)} readOnly={true} />
    <StringInput label="Status reason" value={value.status_message} setValue={(s) => setSingleValue('status_message', s)} readOnly={true} />
    <StringInput label="Association ID" value={value.association_id} setValue={(s) => setSingleValue('association_id', s)} readOnly={true} />
    {
      info.map((itemInfo) => {
        return <StringInput key={itemInfo.name}
          label={itemInfo.labelName}
          value={value[itemInfo.name]}
          setValue={(s) => setSingleValue(itemInfo.name, s)}
          readOnly={itemInfo.readOnly}
        />;
      })
    }
  </>;
}

/**
 * Block of key-value input view.
 */
const CidrInputBlock = ({ label, value, setValue }: {
const MultiItemInputBlock = ({ label, value, setValue, info }: {
  label: string,
  value: CidrBlock[],
  setValue: (s: CidrBlock[]) => void,
  value: ItemBlock[],
  setValue: (s: ItemBlock[]) => void,
  info: { labelName: string, name: string, readOnly?: boolean }[],
}) => {

  const setSingleValue = (cidr: CidrBlock, index: number) => {
    const newValue: CidrBlock[] = JSON.parse(JSON.stringify(value));
    newValue[index] = cidr;
  const setSingleValue = (item: ItemBlock, index: number) => {
    const newValue: ItemBlock[] = JSON.parse(JSON.stringify(value));
    newValue[index] = item;
    setValue(newValue);
  }

  const addCidr = (index: number) => {
    const newValue: CidrBlock[] = JSON.parse(JSON.stringify(value));
    newValue.push({
      cidr: '',
      state: '',
      status_message: '',
      association_id: '',
    });
  const createNewItem = () => {
    const temp: Record<string, string> = {};
    for (const itemInfo of info) {
      temp[itemInfo.name] = '';
    }
    return temp;
  }

  const addItem = (index: number) => {
    const oldValue: ItemBlock[] = JSON.parse(JSON.stringify(value));
    if (oldValue.length === 0) {
      setValue([createNewItem()]);
      return;
    }
    const newValue: ItemBlock[] = [];
    for (let i = 0; i < oldValue.length; i += 1) {
      newValue.push(oldValue[i]);
      if (i === index) {
        newValue.push(createNewItem());
      }
    }
    setValue(newValue);
  }

  const moveUpCidr = (index: number) => {
    const newValue: CidrBlock[] = JSON.parse(JSON.stringify(value));
  const moveUpItem = (index: number) => {
    const newValue: ItemBlock[] = JSON.parse(JSON.stringify(value));
    const value1 = JSON.parse(JSON.stringify(newValue[index - 1]));
    const value2 = JSON.parse(JSON.stringify(newValue[index]));
    newValue[index] = value1;
@@ -72,8 +94,8 @@ const CidrInputBlock = ({ label, value, setValue }: {
    setValue(newValue);
  }

  const moveDownCidr = (index: number) => {
    const newValue: CidrBlock[] = JSON.parse(JSON.stringify(value));
  const moveDownItem = (index: number) => {
    const newValue: ItemBlock[] = JSON.parse(JSON.stringify(value));
    const value1 = JSON.parse(JSON.stringify(newValue[index + 1]));
    const value2 = JSON.parse(JSON.stringify(newValue[index]));
    newValue[index] = value1;
@@ -81,9 +103,9 @@ const CidrInputBlock = ({ label, value, setValue }: {
    setValue(newValue);
  }

  const deleteCidr = (index: number) => {
    const newValue: CidrBlock[] = JSON.parse(JSON.stringify(value));
    const newValue2: CidrBlock[] = [];
  const deleteItem = (index: number) => {
    const newValue: ItemBlock[] = JSON.parse(JSON.stringify(value));
    const newValue2: ItemBlock[] = [];
    for (let i = 0; i < newValue.length; i++) {
      if (i !== index) {
        newValue2.push(newValue[i]);
@@ -92,10 +114,11 @@ const CidrInputBlock = ({ label, value, setValue }: {
    setValue(newValue2);
  }

  // If there are no cidr objects, initialize a blank one.
  // If there are no item objects, initialize a blank one.
  // Otherwise, the "+" and up/down arrows do not show up.
  console.log(value);
  if (value.length === 0) {
    addCidr(0);
    addItem(0);
  }

  return <div className="field--type-cidr-block mb-3">
@@ -112,25 +135,25 @@ const CidrInputBlock = ({ label, value, setValue }: {
          </thead>
          <tbody>
            {
              value.map((cidr, index) => {
              value.map((item, index) => {
                return <tr key={index}>
                  <div className="field-multiple-drag"></div>
                  <td className="d-block">
                    <Row key={index} className="mb-3">
                      <CidrForm value={cidr}
                      <ItemForm value={item} info={info}
                        setValue={(data) => setSingleValue(data, index)} />
                    </Row>
                  </td>
                  <td className="text-nowrap">
                    <Button className="mx-1"
                      onClick={() => addCidr(index)}></Button>
                      onClick={() => addItem(index)}></Button>
                    <Button className="mx-1" disabled={index <= 0}
                      onClick={() => moveUpCidr(index)}></Button>
                      onClick={() => moveUpItem(index)}></Button>
                    <Button className="mx-1"
                      disabled={index >= value.length - 1}
                      onClick={() => moveDownCidr(index)}></Button>
                      onClick={() => moveDownItem(index)}></Button>
                    <Button className="mx-1"
                      onClick={() => deleteCidr(index)}><BsTrashFill /></Button>
                      onClick={() => deleteItem(index)}><BsTrashFill /></Button>
                  </td>
                </tr>;
              })
@@ -142,4 +165,4 @@ const CidrInputBlock = ({ label, value, setValue }: {
  </div>
}

export default CidrInputBlock;
export default MultiItemInputBlock;