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

Issue #3264898 by Ryo Yamashita, yas: Add the function to edit K8s Namespace in the SPA

parent e41f3c73
Loading
Loading
Loading
Loading
+2 −1
Changes for modules/cloud_dashboard/cloud_dashboard/src/constant/entity_info_template/k8s/namespace.ts: 2 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -6,9 +6,10 @@ const K8S_NAMESPACE_TEMPLATE: EntityInfoTemplate = {
  entityRecords: [
    {
      panelName: 'Namespace',
      tableRecordList: ['annotations'],
      tableRecordList: ['annotations', 'labels'],
      keyValueRecords: [
        { labelName: 'Name', name: 'name', type: 'default' },
        { labelName: 'Labels', name: 'labels', type: 'default' },
        { labelName: 'Annotations', name: 'annotations', type: 'default' },
        { labelName: 'Status', name: 'status', type: 'default' },
      ]
+6 −0
Changes for modules/cloud_dashboard/cloud_dashboard/src/model/KeyValueItem.ts: 6 added lines, 0 removed lines.
Original line number Diff line number Diff line
interface KeyValueItem {
  item_key: string;
  item_value: string;
}

export default KeyValueItem;
+21 −0
Changes for modules/cloud_dashboard/cloud_dashboard/src/molecules/K8sDetailPropertyTextArea.tsx: 21 added lines, 0 removed lines.
Original line number Diff line number Diff line
import Form from 'bootstrap3-components/Form';
import React from 'react';

const K8sDetailPropertyTextArea = ({detail, setDetail}: {
  detail: string,
  setDetail: (s: string) => void,
}) => {
  return <Form.Group>
    <Form.Group>
      <Form.Label className="form-required">Detail</Form.Label>
      <div className="form-textarea-wrapper">
        <textarea className="required resize-vertical form-textarea form-control"
          rows={20} cols={60} value={detail} onChange={(e) => {
            setDetail(e.currentTarget.value);
          }} />
      </div>
    </Form.Group>
  </Form.Group>;
}

export default K8sDetailPropertyTextArea;
+131 −0
Changes for modules/cloud_dashboard/cloud_dashboard/src/molecules/KeyValueTableBlock.tsx: 131 added lines, 0 removed lines.
Original line number Diff line number Diff line
import Button from 'bootstrap3-components/Button';
import Form from 'bootstrap3-components/Form';
import GlyphIcon from 'bootstrap3-components/GlyphIcon';
import Table from 'bootstrap3-components/Table';
import KeyValueItem from 'model/KeyValueItem';

const KeyValueTableBlock = ({ title, keyValueList, setKeyValueList }: {
  title: string,
  keyValueList: KeyValueItem[],
  setKeyValueList: (l: KeyValueItem[]) => void,
}) => {

  const changeItemKey = (s: string, index: number) => {
    const newKeyValueList: KeyValueItem[] = JSON.parse(JSON.stringify(keyValueList));
    newKeyValueList[index].item_key = s;
    setKeyValueList(newKeyValueList);
  }

  const changeItemValue = (s: string, index: number) => {
    const newKeyValueList: KeyValueItem[] = JSON.parse(JSON.stringify(keyValueList));
    newKeyValueList[index].item_value = s;
    setKeyValueList(newKeyValueList);
  }

  const orderForward = (index: number) => {
    const newKeyValueList: KeyValueItem[] = JSON.parse(JSON.stringify(keyValueList));
    const tempKey = newKeyValueList[index].item_key;
    const tempValue = newKeyValueList[index].item_value;
    newKeyValueList[index].item_key = newKeyValueList[index + 1].item_key;
    newKeyValueList[index].item_value = newKeyValueList[index + 1].item_value;
    newKeyValueList[index + 1].item_key = tempKey;
    newKeyValueList[index + 1].item_value = tempValue;
    setKeyValueList(newKeyValueList);
  }

  const orderBackward = (index: number) => {
    const newKeyValueList: KeyValueItem[] = JSON.parse(JSON.stringify(keyValueList));
    const tempKey = newKeyValueList[index].item_key;
    const tempValue = newKeyValueList[index].item_value;
    newKeyValueList[index].item_key = newKeyValueList[index - 1].item_key;
    newKeyValueList[index].item_value = newKeyValueList[index - 1].item_value;
    newKeyValueList[index - 1].item_key = tempKey;
    newKeyValueList[index - 1].item_value = tempValue;
    setKeyValueList(newKeyValueList);
  }

  const addRecord = (index: number) => {
    const newKeyValueList: KeyValueItem[] = [];
    for (let i = 0; i < keyValueList.length; i += 1) {
      newKeyValueList.push(JSON.parse(JSON.stringify(keyValueList[i])));
      if (i === index) {
        newKeyValueList.push({
          item_key: '',
          item_value: '',
        });
      }
    }
    setKeyValueList(newKeyValueList);
  }

  const deleteRecord = (index: number) => {
    const newKeyValueList: KeyValueItem[] = [];
    for (let i = 0; i < keyValueList.length; i += 1) {
      if (i !== index) {
        newKeyValueList.push(JSON.parse(JSON.stringify(keyValueList[i])));
      }
    }
    if (newKeyValueList.length === 0) {
      newKeyValueList.push({
        item_key: '',
        item_value: '',
      });
    }
    setKeyValueList(newKeyValueList);
  }

  return <Form.Group>
    <div>
      <div className="form-item">
        <Table hover={true} striped={true} responsive={true}>
          <thead>
            <tr>
              <th colSpan={2} className="field-label">{title}</th>
              <th>Action</th>
            </tr>
          </thead>
          <tbody>
            {
              keyValueList.map((pair, index) => {
                return <tr key={index}>
                  <td>
                    <Form.Input value={pair.item_key} onChange={(e) => {
                      changeItemKey(e.currentTarget.value, index);
                    }} />
                  </td>
                  <td>
                    <Form.Input value={pair.item_value} onChange={(e) => {
                      changeItemValue(e.currentTarget.value, index);
                    }} />
                  </td>
                  <td>
                    <Button.Group>
                      <Button onClick={() => {
                        orderBackward(index);
                      }} disabled={index === 0}>
                        <GlyphIcon iconName='chevron-up' />
                      </Button>
                      <Button onClick={() => {
                        orderForward(index);
                      }} disabled={index === keyValueList.length - 1}>
                        <GlyphIcon iconName='chevron-down' />
                      </Button>
                      <Button onClick={() => {
                        addRecord(index);
                      }}><GlyphIcon iconName='plus' /></Button>
                      <Button onClick={() => {
                        deleteRecord(index);
                      }}><GlyphIcon iconName='trash' /></Button>
                    </Button.Group>
                  </td>
                </tr>;
              })
            }
          </tbody>
        </Table>
      </div>
    </div>
  </Form.Group>;
}

export default KeyValueTableBlock;
+7 −2
Changes for modules/cloud_dashboard/cloud_dashboard/src/pages/EntityInfoPage.tsx: 7 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ import EntityInfoPanelData from 'model/EntityInfoPanelData';
import EntityInfoTemplate from 'model/EntityInfoTemplate';
import EntityInfoPanel from 'organisms/EntityInfoPanel';
import MenuBar from 'organisms/MenuBar';
import K8sNamespaceEditPage from 'pages/k8s/K8sNamespaceEditPage';
import K8sPodEditPage from 'pages/k8s/K8sPodEditPage';
import React, { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
@@ -144,9 +145,13 @@ const EntityInfoPage = ({ entityInfoTemplate }: {
  const params = (new URL(window.location.href)).searchParams;
  if (params.has('mode')
    && params.get('mode') === 'edit'
    && entityInfoTemplate.cloudServiceProvider === 'k8s'
    && entityInfoTemplate.entityName === 'pod') {
    && entityInfoTemplate.cloudServiceProvider === 'k8s') {
    switch (entityInfoTemplate.entityName) {
      case 'pod':
        return <K8sPodEditPage entityInfoTemplate={entityInfoTemplate} />;
      case 'namespace':
        return <K8sNamespaceEditPage entityInfoTemplate={entityInfoTemplate} />;
    }
  }

  return <FluidContainer className="px-0">
Loading