@ant-design/icons#EyeOutlined JavaScript Examples

The following examples show how to use @ant-design/icons#EyeOutlined. 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: FocusButton.jsx    From ui with MIT License 6 votes vote down vote up
FocusButton = (props) => {
  const { store, lookupKey, experimentId } = props;

  const dispatch = useDispatch();

  const focusData = useSelector((state) => state.cellInfo.focus);
  const buttonRef = useRef(null);

  const onClick = (e) => {
    // Prevent clicking button from clicking the component it is embedded in (i.e. table row).
    e.stopPropagation();

    // Lose focus so the button changes color from blue to black when you click on it.
    buttonRef.current.blur();

    dispatch(setCellInfoFocus(experimentId, store, lookupKey));
  };

  const focused = focusData.store === store && focusData.key === lookupKey;

  return (
    <Tooltip placement='right' title={`${(focused) ? 'Hide color on' : 'Show color on'} embedding`} destroyTooltipOnHide>
      <Button
        type='dashed'
        aria-label='Show on embedding'
        style={{ background: 'none' }}
        size='small'
        onClick={onClick}
        ref={buttonRef}
      >
        {focused
          ? (<EyeTwoTone style={{ cursor: 'pointer' }} />)
          : (<EyeOutlined style={{ cursor: 'pointer' }} />)}
      </Button>
    </Tooltip>
  );
}
Example #2
Source File: CrudDataTable.jsx    From starter-antd-admin-crud-auth-mern with MIT License 6 votes vote down vote up
function DropDownRowMenu({ row }) {
  const dispatch = useDispatch();
  const { crudContextAction } = useCrudContext();
  const { panel, collapsedBox, modal, readBox, editBox } = crudContextAction;
  const item = useSelector(selectItemById(row._id));
  const Show = () => {
    dispatch(crud.currentItem(item));
    panel.open();
    collapsedBox.open();
    readBox.open();
  };
  function Edit() {
    dispatch(crud.currentAction("update", item));
    editBox.open();
    panel.open();
    collapsedBox.open();
  }
  function Delete() {
    dispatch(crud.currentAction("delete", item));
    modal.open();
  }
  return (
    <Menu style={{ width: 130 }}>
      <Menu.Item key={`${uniqueId()}`} icon={<EyeOutlined />} onClick={Show}>
        Show
      </Menu.Item>
      <Menu.Item key={`${uniqueId()}`} icon={<EditOutlined />} onClick={Edit}>
        Edit
      </Menu.Item>
      <Menu.Item
        key={`${uniqueId()}`}
        icon={<DeleteOutlined />}
        onClick={Delete}
      >
        Delete
      </Menu.Item>
    </Menu>
  );
}
Example #3
Source File: CrudDataTable.jsx    From starter-antd-admin-crud-auth-mern with MIT License 6 votes vote down vote up
function DropDownRowMenu({ row }) {
  const dispatch = useDispatch();
  const { crudContextAction } = useCrudContext();
  const { panel, collapsedBox, modal, readBox, editBox } = crudContextAction;
  const item = useSelector(selectItemById(row._id));
  const Show = () => {
    dispatch(crud.currentItem(item));
    panel.open();
    collapsedBox.open();
    readBox.open();
  };
  function Edit() {
    dispatch(crud.currentAction("update", item));
    editBox.open();
    panel.open();
    collapsedBox.open();
  }
  function Delete() {
    dispatch(crud.currentAction("delete", item));
    modal.open();
  }
  return (
    <Menu style={{ width: 130 }}>
      <Menu.Item key={`${uniqueId()}`} icon={<EyeOutlined />} onClick={Show}>
        Show
      </Menu.Item>
      <Menu.Item key={`${uniqueId()}`} icon={<EditOutlined />} onClick={Edit}>
        Edit
      </Menu.Item>
      <Menu.Item
        key={`${uniqueId()}`}
        icon={<DeleteOutlined />}
        onClick={Delete}
      >
        Delete
      </Menu.Item>
    </Menu>
  );
}
Example #4
Source File: index.jsx    From starter-antd-admin-crud-auth-mern with MIT License 6 votes vote down vote up
function DropDownRowMenu({ row }) {
  const Show = () => {};
  function Edit() {}
  function Delete() {}
  return (
    <Menu style={{ width: 130 }}>
      <Menu.Item icon={<EyeOutlined />} onClick={Show}>
        Show
      </Menu.Item>
      <Menu.Item icon={<EditOutlined />} onClick={Edit}>
        Edit
      </Menu.Item>
      <Menu.Item icon={<DeleteOutlined />} onClick={Delete}>
        Delete
      </Menu.Item>
    </Menu>
  );
}
Example #5
Source File: DataTableDropMenu.jsx    From erp-crm with MIT License 6 votes vote down vote up
export default function DataTableDropMenu({ row, entity }) {
  const dispatch = useDispatch();
  const { erpContextAction } = useErpContext();
  const { readPanel, updatePanel, modal } = erpContextAction;
  const item = useSelector(selectItemById(row._id));
  function Read() {
    dispatch(erp.currentItem({ data: item }));
    readPanel.open();
  }
  function Edit() {
    dispatch(erp.currentAction({ actionType: 'update', data: item }));
    updatePanel.open();
  }
  function Delete() {
    dispatch(erp.currentAction({ actionType: 'delete', data: item }));
    modal.open();
  }
  function Download() {
    window.open(`${DOWNLOAD_BASE_URL}${entity}/${entity}-${row._id}.pdf`, '_blank');
  }
  return (
    <Menu style={{ minWidth: 130 }}>
      <Menu.Item key={`${uniqueId()}`} icon={<EyeOutlined />} onClick={Read}>
        Show
      </Menu.Item>
      <Menu.Item key={`${uniqueId()}`} icon={<EditOutlined />} onClick={Edit}>
        Edit
      </Menu.Item>
      <Menu.Item key={`${uniqueId()}`} icon={<FilePdfOutlined />} onClick={Download}>
        Download
      </Menu.Item>
      <Menu.Item key={`${uniqueId()}`} icon={<DeleteOutlined />} onClick={Delete}>
        Delete
      </Menu.Item>
    </Menu>
  );
}
Example #6
Source File: CrudDataTable.jsx    From erp-crm with MIT License 6 votes vote down vote up
function DropDownRowMenu({ row }) {
  const dispatch = useDispatch();
  const { crudContextAction } = useCrudContext();
  const { panel, collapsedBox, modal, readBox, editBox } = crudContextAction;
  const item = useSelector(selectItemById(row._id));
  const Show = () => {
    dispatch(crud.currentItem({ data: item }));
    panel.open();
    collapsedBox.open();
    readBox.open();
  };
  function Edit() {
    dispatch(crud.currentItem({ data: item }));
    dispatch(crud.currentAction({ actionType: 'update', data: item }));
    editBox.open();
    panel.open();
    collapsedBox.open();
  }
  function Delete() {
    dispatch(crud.currentAction({ actionType: 'delete', data: item }));
    modal.open();
  }
  return (
    <Menu style={{ width: 130 }}>
      <Menu.Item key={`${uniqueId()}`} icon={<EyeOutlined />} onClick={Show}>
        Show
      </Menu.Item>
      <Menu.Item key={`${uniqueId()}`} icon={<EditOutlined />} onClick={Edit}>
        Edit
      </Menu.Item>
      <Menu.Item key={`${uniqueId()}`} icon={<DeleteOutlined />} onClick={Delete}>
        Delete
      </Menu.Item>
    </Menu>
  );
}
Example #7
Source File: index.jsx    From erp-crm with MIT License 6 votes vote down vote up
function DropDownRowMenu({ row }) {
  const Show = () => {};
  function Edit() {}
  function Delete() {}
  return (
    <Menu style={{ width: 130 }}>
      <Menu.Item icon={<EyeOutlined />} onClick={Show}>
        Show
      </Menu.Item>
      <Menu.Item icon={<EditOutlined />} onClick={Edit}>
        Edit
      </Menu.Item>
      <Menu.Item icon={<DeleteOutlined />} onClick={Delete}>
        Delete
      </Menu.Item>
    </Menu>
  );
}
Example #8
Source File: Relations.js    From label-studio-frontend with Apache License 2.0 6 votes vote down vote up
RelationsComponent = ({ store }) => {
  const annotation = store.annotationStore.selected;
  const { relations } = annotation.relationStore;
  const hasRelations = relations.length > 0;
  const relationsUIVisible = annotation.relationStore.showConnections;

  return (
    <Block name="relations">
      {/* override LS styles' height */}
      <Elem name="header">
        <Elem name="title">Relations ({relations.length})</Elem>
        {hasRelations && (
          <Button
            size="small"
            type="link"
            icon={relationsUIVisible ? <EyeInvisibleOutlined /> : <EyeOutlined />}
            onClick={() => annotation.relationStore.toggleConnections()}
            className={[relationsUIVisible ? styles.uihidden : styles.uivisible, globalStyles.link]}
          />
        )}
      </Elem>

      <Elem name="content">
        {hasRelations ? (
          <List
            size="small"
            bordered
            itemLayout="vertical"
            className={styles.list}
            dataSource={annotation.relationStore.relations}
            renderItem={item => <ListItem item={item} />}
          />
        ) : (
          <p>No Relations added yet</p>
        )}
      </Elem>
    </Block>
  );
}
Example #9
Source File: _config.jsx    From documentation with MIT License 6 votes vote down vote up
features = [
    {
        title: translate({ id: "pages.home.features.logic.title" }),
        Icon: EyeOutlined,
        description: translate({ id: "pages.home.features.logic.description" }),
    },
    {
        title: translate({ id: "pages.home.features.adaptability.title" }),
        Icon: LoginOutlined,
        description: translate({ id: "pages.home.features.adaptability.description" }),
    },
    {
        title: translate({ id: "pages.home.features.debt.title" }),
        Icon: FileProtectOutlined,
        description: translate({ id: "pages.home.features.debt.description" }),
    },
    {
        title: translate({ id: "pages.home.features.shared.title" }),
        Icon: BuildOutlined,
        description: translate({ id: "pages.home.features.shared.description" }),
    },
]
Example #10
Source File: Predictions.js    From label-studio-frontend with Apache License 2.0 5 votes vote down vote up
Prediction = observer(({ item, store }) => {
  const toggleVisibility = e => {
    e.preventDefault();
    e.stopPropagation();
    item.toggleVisibility();
    const c = document.getElementById(`c-${item.id}`);

    if (c) c.style.display = item.hidden ? "none" : "unset";
  };

  const highlight = () => {
    const c = document.getElementById(`c-${item.id}`);

    if (c) c.classList.add("hover");
  };

  const unhighlight = () => {
    const c = document.getElementById(`c-${item.id}`);

    if (c) c.classList.remove("hover");
  };

  return (
    <List.Item
      key={item.id}
      className={item.selected ? `${styles.annotation} ${styles.annotation_selected}` : styles.annotation}
      onClick={() => {
        !item.selected && store.annotationStore.selectPrediction(item.id);
      }}
      onMouseEnter={highlight}
      onMouseLeave={unhighlight}
    >
      <div className={styles.itembtns}>
        <div>
          <div className={styles.title}>{item.createdBy ? `Model (${item.createdBy})` : null}</div>
          Created
          <i>{item.createdAgo ? ` ${item.createdAgo} ago` : ` ${Utils.UDate.prettyDate(item.createdDate)}`}</i>
        </div>
        <div className={styles.buttons}>
          {item.selected && (
            <Tooltip placement="topLeft" title="Add a new annotation based on this prediction">
              <Button
                size="small"
                onClick={ev => {
                  ev.preventDefault();

                  const cs = store.annotationStore;
                  const p = cs.selected;
                  const c = cs.addAnnotationFromPrediction(p);

                  // this is here because otherwise React doesn't re-render the change in the tree
                  window.setTimeout(function() {
                    store.annotationStore.selectAnnotation(c.id);
                  }, 50);
                }}
              >
                <CopyOutlined />
              </Button>
            </Tooltip>
          )}
          {store.annotationStore.viewingAllAnnotations && (
            <Button size="small" type="primary" ghost onClick={toggleVisibility}>
              {item.hidden ? <EyeInvisibleOutlined /> : <EyeOutlined />}
            </Button>
          )}
        </div>
      </div>
    </List.Item>
  );
})
Example #11
Source File: AdminDataTable.jsx    From erp-crm with MIT License 5 votes vote down vote up
function DropDownRowMenu({ row }) {
  const dispatch = useDispatch();
  const { crudContextAction } = useCrudContext();
  const { panel, collapsedBox, modal, advancedBox, readBox, editBox } = crudContextAction;
  const item = useSelector(selectItemById(row._id));
  const Show = () => {
    dispatch(crud.currentItem({ data: item }));
    panel.open();
    collapsedBox.open();
    readBox.open();
  };
  function Edit() {
    dispatch(crud.currentItem({ data: item }));
    dispatch(crud.currentAction({ actionType: 'update', data: item }));
    editBox.open();
    panel.open();
    collapsedBox.open();
  }
  function UpdatePassword() {
    dispatch(crud.currentItem({ data: item }));
    dispatch(crud.currentAction({ actionType: 'update', data: item }));
    advancedBox.open();
    panel.open();
    collapsedBox.open();
  }
  function Delete() {
    dispatch(crud.currentAction({ actionType: 'delete', data: item }));
    modal.open();
  }
  return (
    <Menu style={{ minWidth: 130 }}>
      <Menu.Item key={`${uniqueId()}`} icon={<EyeOutlined />} onClick={Show}>
        Show
      </Menu.Item>
      <Menu.Item key={`${uniqueId()}`} icon={<EditOutlined />} onClick={Edit}>
        Edit
      </Menu.Item>
      <Menu.Item key={`${uniqueId()}`} icon={<LockOutlined />} onClick={UpdatePassword}>
        Update Password
      </Menu.Item>
      <Menu.Item key={`${uniqueId()}`} icon={<DeleteOutlined />} onClick={Delete}>
        Delete
      </Menu.Item>
    </Menu>
  );
}
Example #12
Source File: DataTableDropMenu.jsx    From erp-crm with MIT License 5 votes vote down vote up
export default function DataTableDropMenu({ row, entity }) {
  const dispatch = useDispatch();
  const { erpContextAction } = useErpContext();
  const { readPanel, updatePanel, recordPanel, modal } = erpContextAction;
  const item = useSelector(selectItemById(row._id));
  function Read() {
    dispatch(erp.currentItem({ data: item }));
    readPanel.open();
  }
  function RecordPayment() {
    dispatch(erp.currentAction({ actionType: 'recordPayment', data: item }));
    recordPanel.open();
    dispatch(erp.currentItem({ data: item }));
  }
  function Edit() {
    dispatch(erp.currentAction({ actionType: 'update', data: item }));
    updatePanel.open();
  }
  function Delete() {
    dispatch(erp.currentAction({ actionType: 'delete', data: item }));
    modal.open();
  }
  function Download() {
    window.open(`${DOWNLOAD_BASE_URL}${entity}/${entity}-${row._id}.pdf`, '_blank');
  }
  return (
    <Menu style={{ minWidth: 130 }}>
      <Menu.Item key={`${uniqueId()}`} icon={<EyeOutlined />} onClick={Read}>
        Show
      </Menu.Item>
      <Menu.Item key={`${uniqueId()}`} icon={<CreditCardOutlined />} onClick={RecordPayment}>
        Record Payment
      </Menu.Item>
      <Menu.Item key={`${uniqueId()}`} icon={<EditOutlined />} onClick={Edit}>
        Edit
      </Menu.Item>
      <Menu.Item key={`${uniqueId()}`} icon={<FilePdfOutlined />} onClick={Download}>
        Download
      </Menu.Item>
      <Menu.Item key={`${uniqueId()}`} icon={<DeleteOutlined />} onClick={Delete}>
        Delete
      </Menu.Item>
    </Menu>
  );
}
Example #13
Source File: AdminDataTable.jsx    From starter-antd-admin-crud-auth-mern with MIT License 5 votes vote down vote up
function DropDownRowMenu({ row }) {
  const dispatch = useDispatch();
  const { crudContextAction } = useCrudContext();
  const {
    panel,
    collapsedBox,
    modal,
    advancedBox,
    readBox,
    editBox,
  } = crudContextAction;
  const item = useSelector(selectItemById(row._id));
  const Show = () => {
    dispatch(crud.currentItem(item));
    panel.open();
    collapsedBox.open();
    readBox.open();
  };
  function Edit() {
    dispatch(crud.currentAction("update", item));
    editBox.open();
    panel.open();
    collapsedBox.open();
  }
  function UpdatePassword() {
    dispatch(crud.currentAction("update", item));
    advancedBox.open();
    panel.open();
    collapsedBox.open();
  }
  function Delete() {
    dispatch(crud.currentAction("delete", item));
    modal.open();
  }
  return (
    <Menu style={{ minWidth: 130 }}>
      <Menu.Item key={`${uniqueId()}`} icon={<EyeOutlined />} onClick={Show}>
        Show
      </Menu.Item>
      <Menu.Item key={`${uniqueId()}`} icon={<EditOutlined />} onClick={Edit}>
        Edit
      </Menu.Item>
      <Menu.Item
        key={`${uniqueId()}`}
        icon={<LockOutlined />}
        onClick={UpdatePassword}
      >
        Update Password
      </Menu.Item>
      <Menu.Item
        key={`${uniqueId()}`}
        icon={<DeleteOutlined />}
        onClick={Delete}
      >
        Delete
      </Menu.Item>
    </Menu>
  );
}
Example #14
Source File: Annotations.js    From label-studio-frontend with Apache License 2.0 4 votes vote down vote up
Annotation = observer(({ item, store }) => {
  const removeHoney = () => (
    <Tooltip placement="topLeft" title="Unset this result as a ground truth">
      <Button
        size="small"
        type="primary"
        onClick={ev => {
          ev.preventDefault();
          item.setGroundTruth(false);
        }}
      >
        <StarOutlined />
      </Button>
    </Tooltip>
  );

  const setHoney = () => {
    const title = item.ground_truth
      ? "Unset this result as a ground truth"
      : "Set this result as a ground truth";

    return (
      <Tooltip placement="topLeft" title={title}>
        <Button
          size="small"
          look="link"
          onClick={ev => {
            ev.preventDefault();
            item.setGroundTruth(!item.ground_truth);
          }}
        >
          {item.ground_truth ? (
            <StarFilled />
          ) : (
            <StarOutlined />
          )}
        </Button>
      </Tooltip>
    );
  };

  const toggleVisibility = e => {
    e.preventDefault();
    e.stopPropagation();
    item.toggleVisibility();
    const c = document.getElementById(`c-${item.id}`);

    if (c) c.style.display = item.hidden ? "none" : "unset";
  };

  const highlight = () => {
    const c = document.getElementById(`c-${item.id}`);

    if (c) c.classList.add("hover");
  };

  const unhighlight = () => {
    const c = document.getElementById(`c-${item.id}`);

    if (c) c.classList.remove("hover");
  };

  /**
   * Default badge for saved annotations
   */
  let badge = <Badge status="default" />;

  /**
   *
   */
  let annotationID;

  /**
   * Title of card
   */
  if (item.userGenerate && !item.sentUserGenerate) {
    annotationID = <span className={styles.title}>Unsaved Annotation</span>;
  } else {
    if (item.pk) {
      annotationID = <span className={styles.title}>ID {item.pk}</span>;
    } else if (item.id) {
      annotationID = <span className={styles.title}>ID {item.id}</span>;
    }
  }

  /**
   * Badge for processing of user generate annotation
   */
  if (item.userGenerate) {
    badge = <Badge status="processing" />;
  }

  /**
   * Badge for complete of user generate annotation
   */
  if (item.userGenerate && item.sentUserGenerate) {
    badge = <Badge status="success" />;
  }

  const btnsView = () => {
    const confirm = () => {
      // ev.preventDefault();
      // debugger;
      item.list.deleteAnnotation(item);
    };

    return (
      <div className={styles.buttons}>
        {store.hasInterface("ground-truth") && (item.ground_truth ? removeHoney() : setHoney())}
        &nbsp;
        {store.hasInterface("annotations:delete") && (
          <Tooltip placement="topLeft" title="Delete selected annotation">
            <Popconfirm
              placement="bottomLeft"
              title={"Please confirm you want to delete this annotation"}
              onConfirm={confirm}
              okText="Delete"
              okType="danger"
              cancelText="Cancel"
            >
              <Button size="small" danger style={{ background: "transparent" }}>
                <DeleteOutlined />
              </Button>
            </Popconfirm>
          </Tooltip>
        )}
      </div>
    );
  };

  return (
    <List.Item
      key={item.id}
      className={item.selected ? `${styles.annotation} ${styles.annotation_selected}` : styles.annotation}
      onClick={() => {
        !item.selected && store.annotationStore.selectAnnotation(item.id);
      }}
      onMouseEnter={highlight}
      onMouseLeave={unhighlight}
    >
      <div className={styles.annotationcard}>
        <div>
          <div className={styles.title}>
            {badge}
            {annotationID}
          </div>
          {item.pk ? "Created" : "Started"}
          <i>{item.createdAgo ? ` ${item.createdAgo} ago` : ` ${Utils.UDate.prettyDate(item.createdDate)}`}</i>
          {item.createdBy && item.pk ? ` by ${item.createdBy}` : null}
          <DraftPanel item={item} />
        </div>
        {/* platform uses was_cancelled so check both */}
        {store.hasInterface("skip") && (item.skipped || item.was_cancelled) && (
          <Tooltip placement="topLeft" title="Skipped annotation">
            <StopOutlined className={styles.skipped} />
          </Tooltip>
        )}
        {store.annotationStore.viewingAllAnnotations && (
          <Button size="small" type="primary" ghost onClick={toggleVisibility}>
            {item.hidden ? <EyeInvisibleOutlined /> : <EyeOutlined />}
          </Button>
        )}
        {item.selected && btnsView()}
      </div>
    </List.Item>
  );
})
Example #15
Source File: adminChallengeCreate.js    From ctf_platform with MIT License 4 votes vote down vote up
CreateChallengeForm = (props) => {
    const [form] = Form.useForm();
    const [editorValue, setEditorValue] = React.useState("")
    const [existingCats, setExistingCats] = React.useState([])
    const [finalSortedChalls, setfinalSortedChalls] = React.useState([])

    useEffect(() => {
        var currentValues = form.getFieldsValue()
        currentValues.flags = [""]

        form.setFieldsValue(currentValues)
        //Render existing categories select options
        let existCats = []
        for (let i = 0; i < props.allCat.length; i++) {
            existCats.push(<Option key={props.allCat[i].key} value={props.allCat[i].key}>{props.allCat[i].key}</Option>)
        }
        setExistingCats(existCats)
        //Render existing challenges select options
        let existChalls = {}
        for (let i = 0; i < props.challenges.length; i++) {
            if (!(props.challenges[i].category in existChalls)) existChalls[props.challenges[i].category] = []
            existChalls[props.challenges[i].category].push({
                value: props.challenges[i]._id,
                label: props.challenges[i].name
            })
        }

        let finalChalls = []
        for (const category in existChalls) {
            finalChalls.push({
                value: category,
                label: category,
                children: existChalls[category]
            })
        }
        setfinalSortedChalls(finalChalls)
    }, [])

    return (
        <Form
            form={form}
            name="create_challenge_form"
            className="create_challenge_form"
            onValuesChange={() => { if (props.state.edited === false) props.setState({ edited: true }) }}
            onFinish={async (values) => {
                props.setState({ edited: false })
                if (typeof values.flags === "undefined") {
                    message.warn("Please enter at least 1 flag")
                }
                else {
                    //console.log(values)
                    props.setState({ loading: true })
                    if (values.visibility === "false") {
                        values.visibility = false
                    }
                    else {
                        values.visibility = true
                    }
                    if (values.dynamic === "false") {
                        values.dynamic = false
                    }
                    else {
                        values.dynamic = true
                    }
                    if (typeof values.writeup !== "undefined") {
                        if (typeof values.writeupComplete === "undefined") {
                            values.writeupComplete = true
                        }
                    }
                    const category = (typeof values.category1 !== "undefined") ? values.category1 : values.category2
                    let requires = undefined
                    if (values.requires && values.requires.length > 0) requires = values.requires[1]
                    await fetch(window.ipAddress + "/v1/challenge/new", {
                        method: 'post',
                        headers: { 'Content-Type': 'application/json', "Authorization": window.IRSCTFToken },
                        body: JSON.stringify({
                            "name": values.name,
                            "category": category,
                            "description": values.description,
                            "points": values.points,
                            "flags": values.flags,
                            "tags": values.tags,
                            "hints": values.hints,
                            "max_attempts": values.max_attempts,
                            "visibility": values.visibility,
                            "writeup": values.writeup,
                            "writeupComplete": values.writeupComplete,
                            "requires": requires,
                            "dynamic": values.dynamic,
                            "initial": values.initial,
                            "minSolves": values.minSolves,
                            "minimum": values.minimum
                        })
                    }).then((results) => {
                        return results.json(); //return data in JSON (since its JSON data)
                    }).then((data) => {
                        //console.log(data)
                        if (data.success === true) {
                            message.success({ content: "Created challenge " + values.name + " successfully!" })
                            form.resetFields()
                            props.handleCreateBack()
                        }
                        else if (data.error === "exists") {
                            message.warn("A challenge with an existing name exists")
                        }
                        else {
                            message.error({ content: "Oops. Unknown error, please contact an admin." })
                        }



                    }).catch((error) => {
                        console.log(error)
                        message.error({ content: "Oops. Issue connecting with the server or client error, please check console and report the error. " });
                    })
                    props.setState({ loading: false })


                }

            }}

        >
            <Prompt
                when={props.state.edited}
                message='The challenge details you entered have not been saved. Are you sure you want to leave?'
            />

            <h1>Challenge Name:</h1>
            <Form.Item
                name="name"
                rules={[{ required: true, message: 'Please enter a challenge name' }]}
            >

                <Input allowClear placeholder="Challenge name" />
            </Form.Item>

            <Divider />
            <h1>Challenge Category:</h1>
            <h4>Select an Existing Category: </h4>
            <Form.Item
                name="category1"
                rules={[{ required: !props.state.selectCatDisabled, message: 'Please enter a challenge category' }]}
            >

                <Select
                    disabled={props.state.selectCatDisabled}
                    allowClear
                    showSearch
                    placeholder="Select an existing Category"
                    onChange={(value) => {
                        if (value) {
                            props.setState({ inputCatDisabled: true })
                        }
                        else {
                            props.setState({ inputCatDisabled: false })
                        }
                    }}
                >
                    {existingCats}
                </Select>

            </Form.Item>
            <h4>Enter a New Category</h4>
            <Form.Item
                name="category2"
                rules={[{ required: !props.state.inputCatDisabled, message: 'Please enter a challenge category' }]}
            >

                <Input onChange={(e) => {
                    e.target.value.length > 0 ? props.setState({ selectCatDisabled: true }) : props.setState({ selectCatDisabled: false })
                }} disabled={props.state.inputCatDisabled} allowClear placeholder="Enter a new challenge category" />
            </Form.Item>

            <Divider />

            <Suspense fallback={<div style={{ height: "100%", width: "100%", display: "flex", justifyContent: "center", alignItems: "center", zIndex: 15 }}>
                <Ellipsis color="#177ddc" size={120} ></Ellipsis>
            </div>}>
                <h1>Challenge Description (Supports <a href="https://guides.github.com/features/mastering-markdown/" target="_blank" rel="noreferrer">Markdown</a> and <a href="https://github.com/rehypejs/rehype-raw" target="_blank" rel="noreferrer">HTML</a>):</h1>
                <Form.Item
                    name="description"
                    rules={[{ required: true, message: 'Please enter a description' }]}
                    valuePropName={editorValue}
                >
                    <MDEditor value={editorValue} onChange={(value) => { setEditorValue(value) }} preview="edit" />
                </Form.Item>
                <h3>Challenge Description Preview</h3>
                <Card
                    type="inner"
                    bordered={true}
                    bodyStyle={{ backgroundColor: "#262626", textAlign: "center" }}
                    className="challengeModal"
                >
                    <MarkdownRender>{editorValue}</MarkdownRender>
                </Card>
            </Suspense>


            <Divider />

            <div className="settings-responsive2" style={{ display: "flex", justifyContent: "space-around" }}>

                <div style={{ display: "flex", flexDirection: "column", justifyContent: "center" }}>

                    <Card>
                        <h1>Challenge Points:</h1>
                        <Form.Item
                            name="points"
                            rules={[{ required: true, message: 'Please enter challenge points' }, {
                                type: 'integer',
                                message: "Please enter a valid integer between 0-100000",
                            },]}
                            initialValue={0}
                        >

                            <InputNumber disabled={props.state.dynamic} min={0} max={100000} style={{ width: "30ch" }} ></InputNumber>
                        </Form.Item>
                    </Card>

                    <Card>
                        <h1>Maximum Number of Attempts (Set to 0 for unlimited)</h1>
                        <Form.Item
                            name="max_attempts"
                            rules={[{ required: true, message: 'Please enter the maximum number of attempts' }, {
                                type: 'integer',
                                message: "Please enter a valid integer between 0-10000",
                            },]}
                            style={{ alignText: 'center' }}
                            initialValue={0}
                        >

                            <InputNumber min={0} max={10000} style={{ width: "30ch" }}></InputNumber>
                        </Form.Item>
                    </Card>
                </div>

                <Divider type="vertical" style={{ height: "inherit" }} />

                <div style={{ display: "flex", flexDirection: "column" }}>
                    <Form.List name="flags" >
                        {(fields, { add, remove }) => {
                            return (
                                <Card>
                                    <h1>Flags</h1>
                                    {fields.map(field => (
                                        <Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="start">
                                            <Form.Item
                                                {...field}
                                                name={[field.name]}
                                                fieldKey={[field.fieldKey]}
                                                rules={[{ required: true, message: 'Missing flag' }, { message: "Please enter a flag that is < 1000 characters", pattern: /^.{1,1000}$/ }]}
                                            >
                                                <Input style={{ width: "50ch" }} placeholder="Flag" />
                                            </Form.Item>

                                            {fields.length > 1 ? (
                                                <MinusCircleOutlined
                                                    className="dynamic-delete-button"
                                                    style={{ margin: '0 8px', color: "red" }}
                                                    onClick={() => {
                                                        remove(field.name);
                                                    }}
                                                />
                                            ) : null}
                                        </Space>
                                    ))}

                                    <Form.Item>
                                        <Button
                                            type="dashed"
                                            onLoad={() => { if (fields.length < 1) add() }}
                                            onClick={() => {
                                                add();
                                            }}
                                            block
                                            style={{ width: "50ch" }}
                                        >
                                            <PlusOutlined /> Add Flag
                                        </Button>
                                    </Form.Item>


                                </Card>
                            );
                        }}
                    </Form.List>

                    <Form.List name="tags">
                        {(fields, { add, remove }) => {
                            return (
                                <Card>
                                    <h1>Tags</h1>
                                    {fields.map(field => (
                                        <Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="start">

                                            <Form.Item
                                                {...field}
                                                name={[field.name]}
                                                fieldKey={[field.fieldKey]}
                                                rules={[{ required: true, message: 'Missing tag' }]}
                                            >
                                                <Input placeholder="Tag" style={{ width: "50ch" }} />
                                            </Form.Item>


                                            <MinusCircleOutlined
                                                className="dynamic-delete-button"
                                                style={{ margin: '0 8px', color: "red" }}
                                                onClick={() => {
                                                    remove(field.name);
                                                }}
                                            />
                                        </Space>
                                    ))}

                                    <Form.Item>
                                        <Button
                                            type="dashed"
                                            onClick={() => {
                                                add();
                                            }}
                                            block
                                            style={{ width: "50ch" }}
                                        >
                                            <PlusOutlined /> Add Tag
                                        </Button>
                                    </Form.Item>
                                </Card>
                            );
                        }}
                    </Form.List>
                </div>
            </div>

            <Divider />


            <div className="settings-responsive2" style={{ display: "flex", justifyContent: "space-around" }}>

                <div style={{ display: "flex", flexDirection: "column" }}>

                    <Form.List name="hints" >
                        {(fields, { add, remove }) => {
                            return (
                                <Card>
                                    <h1>Hints</h1>
                                    {fields.map(field => (
                                        <Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="start">
                                            <Form.Item
                                                {...field}
                                                name={[field.name, "hint"]}
                                                fieldKey={[field.fieldKey, "hint"]}
                                                rules={[{ required: true, message: 'Missing hint' }]}
                                            >
                                                <Input placeholder="Hint" style={{ width: "20vw" }} />
                                            </Form.Item>

                                            <Form.Item
                                                {...field}
                                                name={[field.name, "cost"]}
                                                fieldKey={[field.fieldKey, "cost"]}
                                                rules={[{ required: true, message: 'Missing cost for hint' }, {
                                                    type: 'integer',
                                                    message: "Please enter a valid integer between 0-10000",
                                                },]}
                                            >
                                                <InputNumber min={0} max={10000} placeholder="Cost"></InputNumber>
                                            </Form.Item>

                                            <MinusCircleOutlined
                                                style={{ color: "red" }}
                                                onClick={() => {
                                                    remove(field.name);
                                                }}
                                            />
                                        </Space>
                                    ))}

                                    <Form.Item>
                                        <Button
                                            type="dashed"
                                            onClick={() => {
                                                add();
                                            }}
                                            block
                                            style={{ width: "50ch" }}
                                        >
                                            <PlusOutlined /> Add Hint
                                        </Button>
                                    </Form.Item>
                                </Card>
                            );
                        }}
                    </Form.List>

                    <Card>
                        <h1>Writeup Link (Optional)</h1>
                        <Form.Item
                            name="writeup"
                            rules={[
                                {
                                    type: 'url',
                                    message: "Please enter a valid link",
                                }]}
                        >

                            <Input allowClear style={{ width: "50ch" }} placeholder="Enter a writeup link for this challenge" />
                        </Form.Item>
                        <div style={{ display: "flex", alignContent: "center" }}>
                            <h4 style={{ marginRight: "2ch" }}>Release Writeup Only After Completion: </h4>
                            <Form.Item
                                name="writeupComplete"
                            >
                                <Switch defaultChecked />
                            </Form.Item>
                        </div>
                    </Card>

                    <Card>
                        <h1>Visibility</h1>
                        <Form.Item
                            name="visibility"
                            rules={[{ required: true, message: 'Please set the challenge visibility' }]}
                            initialValue="false"
                        >
                            <Select style={{ width: "20ch" }}>
                                <Option value="false"><span style={{ color: "#d32029" }}>Hidden <EyeInvisibleOutlined /></span></Option>
                                <Option value="true"><span style={{ color: "#49aa19" }}>Visible <EyeOutlined /></span></Option>
                            </Select>

                        </Form.Item>
                    </Card>
                </div>

                <Divider type="vertical" style={{ height: "inherit" }} />

                <div style={{ display: "flex", flexDirection: "column" }}>

                    <Card>
                        <h1>Challenge Required: </h1>
                        <Form.Item
                            name="requires"
                        >

                            <Cascader
                                options={finalSortedChalls}
                                allowClear
                                showSearch
                                placeholder="Select an existing challenge" />

                        </Form.Item>
                        <p>Locks this challenge until the provided challenge above has been solved.</p>
                    </Card>

                    <Card>
                        <h1>Dynamic Scoring</h1>
                        <Form.Item
                            name="dynamic"
                            rules={[{ required: true, message: 'Please set whether the challenge uses dynamic scoring' }]}
                            initialValue="false"
                        >
                            <Select onSelect={(option) => { option === "false" ? props.setState({ dynamic: false }) : props.setState({ dynamic: true }) }} style={{ width: "20ch" }}>
                                <Option value="false"><span style={{ color: "#d32029" }}>Disabled</span></Option>
                                <Option value="true"><span style={{ color: "#49aa19" }}>Enabled</span></Option>
                            </Select>

                        </Form.Item>

                        <h1>Initial Points:</h1>
                        <Form.Item
                            name="initial"
                            rules={[{ required: props.state.dynamic, message: 'Please enter the initial challenge points' }, {
                                type: 'integer',
                                message: "Please enter a valid integer between 1-100000",
                            },]}
                            initialValue={500}
                        >
                            <InputNumber disabled={!props.state.dynamic} min={1} max={100000} ></InputNumber>
                        </Form.Item>
                        <p>Initial number of points when there are 0/1 solves on a challenge</p>

                        <h1>Minimum Points:</h1>
                        <Form.Item
                            name="minimum"
                            rules={[{ required: props.state.dynamic, message: 'Please enter the minimum challenge points' }, {
                                type: 'integer',
                                message: "Please enter a valid integer between 0-100000",
                            },]}
                            initialValue={100}
                        >
                            <InputNumber disabled={!props.state.dynamic} min={0} max={100000} ></InputNumber>
                        </Form.Item>
                        <p>Minimum amount of points that the challenge can decay too</p>

                        <h1>Solves to Minimum:</h1>
                        <Form.Item
                            name="minSolves"
                            rules={[{ required: props.state.dynamic, message: 'Please enter the solves to minimum' }, {
                                type: 'integer',
                                message: "Please enter a valid integer between 1-100000",
                            },]}
                            initialValue={50}
                        >
                            <InputNumber disabled={!props.state.dynamic} min={1} max={100000} ></InputNumber>
                        </Form.Item>
                        <p>Number of solves on the challenge till it decays to the minimum point.</p>
                    </Card>
                </div>

            </div>

            <Form.Item>
                <div style={{ display: "flex", justifyContent: "space-between", flexDirection: "row", marginTop: "2vh" }}>
                    <div>
                        <Button style={{ marginBottom: "1.5vh", marginRight: "2vw", backgroundColor: "#d4b106", borderColor: "", color: "white" }} onClick={() => { props.previewChallenge(form.getFieldsValue()); }}>Preview</Button>
                        <Button loading={props.loadingStatus} type="primary" htmlType="submit" className="login-form-button" style={{ marginBottom: "1.5vh" }}>Create Challenge</Button>
                    </div>
                    <div>
                        <Button style={{ marginRight: "2vw" }} type="primary" danger onClick={() => { form.resetFields() }}>Clear</Button>
                    </div>
                </div>
            </Form.Item>

        </Form>
    );
}
Example #16
Source File: HeatmapMetadataTrackSettings.jsx    From ui with MIT License 4 votes vote down vote up
HeatmapMetadataTrackSettings = (props) => {
  const dispatch = useDispatch();

  const { componentType } = props;
  const hierarchy = useSelector(getCellSetsHierarchy());

  const selectedTracks = useSelector(
    (state) => state.componentConfig[componentType]?.config?.selectedTracks,
    _.isEqual,
  );

  const [listData, setListData] = useState([]);

  useEffect(() => {
    if (hierarchy === null || _.isEmpty(hierarchy)) return;

    const selectedTracksListData = convertToReorderableListData(
      selectedTracks, true, hierarchy,
    );

    const unselectedTracks = _.difference(hierarchy.map(({ key }) => key), selectedTracks);
    const unselectedTracksListData = convertToReorderableListData(
      unselectedTracks, false, hierarchy,
    );

    setListData([...selectedTracksListData, ...unselectedTracksListData]);
  }, [selectedTracks]);

  const setTrackSelected = (selected, key) => {
    const newSelectedTracks = [...selectedTracks];

    if (selected) {
      newSelectedTracks.push(key);
    } else {
      _.pull(newSelectedTracks, key);
    }

    dispatch(
      updatePlotConfig(componentType, {
        selectedTracks: newSelectedTracks,
      }),
    );
  };

  const setTrackOrder = (reorderedTracks) => {
    const reorderedSelectedTrackKeys = reorderedTracks
      .filter(({ disabledReorder }) => !disabledReorder)
      .map(({ key }) => key);

    dispatch(
      updatePlotConfig(componentType, {
        selectedTracks: reorderedSelectedTrackKeys,
      }),
    );
  };

  const leftItem = (trackDataItem) => (
    <Switch
      checkedChildren={<EyeOutlined />}
      unCheckedChildren={<EyeInvisibleOutlined />}
      value={trackDataItem.key}
      checked={!trackDataItem.disabledReorder}
      onChange={(selected) => {
        setTrackSelected(selected, trackDataItem.key);
      }}
    />
  );

  const rightItem = (trackDataItem) => (
    hierarchy.filter((current) => current.key === trackDataItem.key)[0].name
  );

  return (
    <div style={{ padding: '5px' }}>
      <ReorderableList
        onChange={setTrackOrder}
        listData={listData}
        leftItem={leftItem}
        rightItem={rightItem}
      />
    </div>
  );
}
Example #17
Source File: OfflineSession.js    From next-terminal with GNU Affero General Public License v3.0 4 votes vote down vote up
render() {

        const columns = [{
            title: '序号',
            dataIndex: 'id',
            key: 'id',
            render: (id, record, index) => {
                return index + 1;
            },
        }, {
            title: '来源IP',
            dataIndex: 'clientIp',
            key: 'clientIp'
        }, {
            title: '接入方式',
            dataIndex: 'mode',
            key: 'mode',
            render: (text) => {
                return (
                    <Tag color={MODE_COLORS[text]}>{text}</Tag>
                )
            }
        }, {
            title: '用户昵称',
            dataIndex: 'creatorName',
            key: 'creatorName'
        }, {
            title: '资产名称',
            dataIndex: 'assetName',
            key: 'assetName'
        }, {
            title: '连接协议',
            dataIndex: 'protocol',
            key: 'protocol',
            render: (text, record) => {
                const title = `${record.username}@${record.ip}:${record.port}`;
                return (
                    <Tooltip title={title}>
                        <Tag color={PROTOCOL_COLORS[text]}>{text}</Tag>
                    </Tooltip>
                )
            }
        }, {
            title: '接入时间',
            dataIndex: 'connectedTime',
            key: 'connectedTime',
            render: (text, record) => {
                return (
                    <Tooltip title={text}>
                        {dayjs(text).fromNow()}
                    </Tooltip>
                )
            }
        }, {
            title: '接入时长',
            dataIndex: 'connectedTime',
            key: 'connectedTime',
            render: (text, record) => {
                return differTime(new Date(record['connectedTime']), new Date(record['disconnectedTime']));
            }
        },
            {
                title: '操作',
                key: 'action',
                render: (text, record) => {
                    let disabled = true;
                    if (record['recording'] && record['recording'] === '1') {
                        disabled = false
                    }

                    return (
                        <div>
                            <Button type="link" size='small'
                                    disabled={disabled}
                                    onClick={() => this.showPlayback(record)}>回放</Button>
                            <Button type="link" size='small'
                                    onClick={() => {
                                        confirm({
                                            title: '您确定要禁止该IP访问本系统吗?',
                                            content: '',
                                            okText: '确定',
                                            okType: 'danger',
                                            cancelText: '取消',
                                            onOk: async () => {
                                                // 向后台提交数据
                                                let formData = {
                                                    ip: record['clientIp'],
                                                    rule: 'reject',
                                                    priority: 99,
                                                }
                                                const result = await request.post('/securities', formData);
                                                if (result.code === 1) {
                                                    message.success('禁用成功');
                                                } else {
                                                    message.error(result.message, 10);
                                                }
                                            }
                                        });
                                    }}>禁用IP</Button>
                            <Button type="link" size='small' danger onClick={() => {
                                confirm({
                                    title: '您确定要删除此会话吗?',
                                    content: '',
                                    okText: '确定',
                                    okType: 'danger',
                                    cancelText: '取消',
                                    onOk: () => {
                                        this.del(record.id)
                                    }
                                });
                            }}>删除</Button>
                        </div>
                    )
                },
            }
        ];

        const selectedRowKeys = this.state.selectedRowKeys;
        const rowSelection = {
            selectedRowKeys: this.state.selectedRowKeys,
            onChange: (selectedRowKeys, selectedRows) => {
                this.setState({selectedRowKeys});
            },
        };
        const hasSelected = selectedRowKeys.length > 0;

        const userOptions = this.state.users.map(d => <Select.Option key={d.id}
                                                                     value={d.id}>{d.nickname}</Select.Option>);
        const assetOptions = this.state.assets.map(d => <Select.Option key={d.id}
                                                                       value={d.id}>{d.name}</Select.Option>);

        return (
            <>
                <Content className="site-layout-background page-content">
                    <div style={{marginBottom: 20}}>
                        <Row justify="space-around" align="middle" gutter={24}>
                            <Col span={4} key={1}>
                                <Title level={3}>离线会话列表</Title>
                            </Col>
                            <Col span={20} key={2} style={{textAlign: 'right'}}>
                                <Space>

                                    <Search
                                        ref={this.inputRefOfClientIp}
                                        placeholder="来源IP"
                                        allowClear
                                        onSearch={this.handleSearchByClientIp}
                                    />

                                    <Select
                                        style={{width: 140}}
                                        showSearch
                                        value={this.state.queryParams.userId}
                                        placeholder='用户昵称'
                                        onSearch={this.handleSearchByNickname}
                                        onChange={this.handleChangeByUserId}
                                        filterOption={false}
                                        allowClear
                                    >
                                        {userOptions}
                                    </Select>

                                    <Select
                                        style={{width: 140}}
                                        showSearch
                                        value={this.state.queryParams.assetId}
                                        placeholder='资产名称'
                                        onSearch={this.handleSearchByAssetName}
                                        onChange={this.handleChangeByAssetId}
                                        filterOption={false}
                                    >
                                        {assetOptions}
                                    </Select>

                                    <Select onChange={this.handleChangeByRead}
                                            value={this.state.queryParams.reviewed ? this.state.queryParams.reviewed : ''}
                                            style={{width: 100}}>
                                        <Select.Option value="">全部会话</Select.Option>
                                        <Select.Option value="true">只看已读</Select.Option>
                                        <Select.Option value="false">只看未读</Select.Option>
                                    </Select>

                                    <Select onChange={this.handleChangeByProtocol}
                                            value={this.state.queryParams.protocol ? this.state.queryParams.protocol : ''}
                                            style={{width: 100}}>
                                        <Select.Option value="">全部协议</Select.Option>
                                        <Select.Option value="rdp">rdp</Select.Option>
                                        <Select.Option value="ssh">ssh</Select.Option>
                                        <Select.Option value="vnc">vnc</Select.Option>
                                        <Select.Option value="telnet">telnet</Select.Option>
                                        <Select.Option value="kubernetes">kubernetes</Select.Option>
                                    </Select>

                                    <Tooltip title='重置查询'>

                                        <Button icon={<UndoOutlined/>} onClick={() => {
                                            this.inputRefOfClientIp.current.setValue('');
                                            this.loadTableData({
                                                pageIndex: 1,
                                                pageSize: 10,
                                                protocol: ''
                                            })
                                        }}>

                                        </Button>
                                    </Tooltip>

                                    <Divider type="vertical"/>

                                    <Tooltip title="刷新列表">
                                        <Button icon={<SyncOutlined/>} onClick={() => {
                                            this.loadTableData(this.state.queryParams)
                                        }}>

                                        </Button>
                                    </Tooltip>

                                    <Tooltip title="全部标为已阅">
                                        <Button icon={<CheckOutlined />}
                                                loading={this.state.reviewedAllBtnLoading}
                                                onClick={this.handleAllReviewed}>
                                        </Button>
                                    </Tooltip>

                                    <Tooltip title="标为已阅">
                                        <Button disabled={!hasSelected} icon={<EyeOutlined />}
                                                loading={this.state.reviewedBtnLoading}
                                                onClick={this.handleReviewed}>

                                        </Button>
                                    </Tooltip>

                                    <Tooltip title="标为未阅">
                                        <Button disabled={!hasSelected} icon={<EyeInvisibleOutlined />}
                                                loading={this.state.unreviewedBtnLoading}
                                                onClick={this.handleUnreviewed}>

                                        </Button>
                                    </Tooltip>

                                    <Tooltip title="批量删除">
                                        <Button type="primary" danger disabled={!hasSelected} icon={<DeleteOutlined/>}
                                                loading={this.state.delBtnLoading}
                                                onClick={() => {
                                                    const content = <div>
                                                        您确定要删除选中的<Text style={{color: '#1890FF'}}
                                                                       strong>{this.state.selectedRowKeys.length}</Text>条记录吗?
                                                    </div>;
                                                    confirm({
                                                        icon: <ExclamationCircleOutlined/>,
                                                        content: content,
                                                        onOk: () => {
                                                            this.batchDelete()
                                                        },
                                                        onCancel() {

                                                        },
                                                    });
                                                }}>
                                        </Button>
                                    </Tooltip>

                                    <Tooltip title="清空">
                                        <Button type="primary" danger icon={<ClearOutlined/>}
                                                loading={this.state.clearBtnLoading}
                                                onClick={() => {
                                                    const content = <Text style={{color: 'red'}}
                                                                          strong>您确定要清空全部的离线会话吗?</Text>;
                                                    confirm({
                                                        icon: <ExclamationCircleOutlined/>,
                                                        content: content,
                                                        okType: 'danger',
                                                        onOk: this.clearSession,
                                                        onCancel() {

                                                        },
                                                    });
                                                }}>

                                        </Button>
                                    </Tooltip>

                                </Space>
                            </Col>
                        </Row>
                    </div>

                    <Table rowSelection={rowSelection}
                           dataSource={this.state.items}
                           columns={columns}
                           position={'both'}
                           pagination={{
                               showSizeChanger: true,
                               current: this.state.queryParams.pageIndex,
                               pageSize: this.state.queryParams.pageSize,
                               onChange: this.handleChangPage,
                               total: this.state.total,
                               showTotal: total => `总计 ${total} 条`
                           }}
                           loading={this.state.loading}
                           rowClassName={(record, index) => {
                               return record['reviewed'] ? '' : 'unreviewed';
                           }}
                    />

                    {
                        this.state.playbackVisible ?
                            <Modal
                                className='modal-no-padding'
                                title={`会话回放 来源IP:${this.state.selectedRow['clientIp']} 用户昵称:${this.state.selectedRow['creatorName']} 资产名称:${this.state.selectedRow['assetName']} 网络:${this.state.selectedRow['username']}@${this.state.selectedRow['ip']}:${this.state.selectedRow['port']}`}
                                centered={true}
                                visible={this.state.playbackVisible}
                                onCancel={this.hidePlayback}
                                width={window.innerWidth * 0.8}
                                footer={null}
                                destroyOnClose
                                maskClosable={false}
                            >
                                {
                                    this.state.selectedRow['mode'] === 'native' || this.state.selectedRow['mode'] === 'terminal' ?
                                        <iframe
                                            title='recording'
                                            style={{
                                                width: '100%',
                                                // height: this.state.iFrameHeight,
                                                overflow: 'visible'
                                            }}
                                            onLoad={() => {
                                                // constant obj = ReactDOM.findDOMNode(this);
                                                // this.setState({
                                                //     "iFrameHeight": obj.contentWindow.document.body.scrollHeight + 'px'
                                                // });
                                            }}
                                            ref="iframe"
                                            src={'./asciinema.html?sessionId=' + this.state.selectedRow['id']}
                                            width="100%"
                                            height={window.innerHeight * 0.8}
                                            frameBorder="0"
                                        />
                                        : <Playback sessionId={this.state.selectedRow['id']}/>
                                }

                            </Modal> : undefined
                    }

                </Content>
            </>
        );
    }
Example #18
Source File: InstanceDetail.jsx    From juno with Apache License 2.0 4 votes vote down vote up
function InstanceDetail(props) {
  const { currentInstance, dispatch, config, appName, env } = props;
  const [visibleRestartModal, setVisibleRestartModal] = useState(false);
  const [loading, setLoading] = useState(false);
  const [content, setContent] = useState('');

  if (!currentInstance) {
    return <div />;
  }

  const {
    config_file_used,
    config_file_synced,
    config_file_take_effect,
    config_file_path,
    sync_at,
    version,
    change_log,
    host_name,
  } = currentInstance;

  let info = [
    {
      title: '接入状态',
      help: '当前应用是否在该实例上接入配置中心',
      content: config_file_used ? '已接入' : '未接入',
    },
    {
      title: '发布状态',
      help: '配置是否下发到机器上',
      content: config_file_synced ? '已下发' : '未下发',
    },
    {
      title: '生效状态',
      help: '配置是否在应用上生效(依赖Go框架支持)',
      content: config_file_take_effect ? '已生效' : '未生效',
    },
    {
      title: '文件路径',
      content: config_file_path
        ? config_file_path.split(';').map((item, idx) => {
            return (
              <div key={idx} className={styles.configPathItem}>
                <span>{item}</span>
                <CopyOutlined
                  onClick={() => {
                    copyToClipBoard(item);
                    message.success('已复制到剪切板');
                  }}
                  className={styles.configPathCopyBtn}
                />
              </div>
            );
          })
        : '---',
    },
    {
      title: '配置版本',
      content: version ? (
        <span>
          <Tag>{version}</Tag> {change_log}
        </span>
      ) : (
        '---'
      ),
    },
    {
      title: '同步时间',
      content: sync_at,
    },
  ];

  let showConfirm = (action, zoneCode, hostname, usedTyp) => {
    const descMap = {
      start: {
        title: '确定启动应用进程吗?',
        content: `应用进程会被执行 start 命令`,
      },
      restart: {
        title: '确定重启应用进程吗?',
        content: '应用进程会被执行 restart 命令',
      },
      stop: {
        title: '确定停止应用进程吗?',
        content: '应用进程会被执行 stop 命令',
      },
    };

    const desc = descMap[action] || {};
    confirm({
      title: desc.title,
      content: (
        <div>
          <p>{desc.content}</p>
          <h4>操作实例:</h4>
          <p>{hostname}</p>
        </div>
      ),
      onOk() {
        setVisibleRestartModal(true);

        doAction(action, zoneCode, hostname, usedTyp);
      },
      onCancel() {},
      okText: '确定',
      cancelText: '取消',
    });
  };

  let doAction = (action, zoneCode, hostname, usedTyp) => {
    if (usedTyp === 0) {
      setContent('配置文件未接入,无法进行重启操作');
      setLoading(false);
      return;
    }

    setLoading(true);
    ServiceAppAction({
      action: action,
      zone_code: zoneCode,
      node_name: hostname,
      typ: usedTyp,
      app_name: appName,
      env: env,
    }).then((res) => {
      if (res.code !== 0) {
        setContent(res.data);
        setLoading(false);
      } else {
        let result = [];
        for (const itemListKey in res.data) {
          let itemList = res.data[itemListKey];
          if (itemList['code'] !== 0) {
            result.push(<p>状态:重启失败</p>);
          } else {
            result.push(<p>状态:重启成功</p>);
          }
          for (const item in itemList) {
            result.push(<p>{item + ':' + itemList[item]}</p>);
          }
        }
        setContent(result);
        setLoading(false);
      }
    });
  };

  return (
    <div className={styles.instanceDetail}>
      <div className={styles.topHeader}>
        <div style={{ fontSize: '48px', textAlign: 'center', padding: '10px' }}>
          <DatabaseOutlined />
        </div>
        <div style={{ padding: '10px' }}>
          <div style={{ fontSize: '24px', fontWeight: 'bold' }}>{currentInstance.host_name}</div>
          <div>
            {currentInstance.region_name} {currentInstance.zone_name} {currentInstance.ip}
          </div>
          <div style={{ marginTop: '10px' }}>
            <Space>
              <Button
                size={'small'}
                type={'primary'}
                icon={<ReloadOutlined />}
                onClick={() => {
                  showConfirm(
                    'restart',
                    currentInstance.zone_code,
                    currentInstance.host_name,
                    currentInstance.config_file_used,
                  );
                }}
              >
                重启
              </Button>

              <Button
                size={'small'}
                icon={<EyeOutlined />}
                onClick={() => {
                  dispatch({
                    type: 'config/fetchInstanceConfig',
                    payload: {
                      id: config.id,
                      hostName: host_name,
                    },
                  });
                }}
              >
                实时配置
              </Button>
            </Space>
          </div>
        </div>
      </div>

      <ul className={styles.instanceInfoList}>
        {info.map((item, index) => (
          <li key={index}>
            <div className={styles.instanceInfoName}>
              <div className={styles.instanceInfoTitle}>{item.title}</div>
              <div className={styles.instanceInfoHelp}>{item.help}</div>
            </div>
            <div className={styles.instanceInfoContent}>{item.content}</div>
          </li>
        ))}
      </ul>

      <Modal
        title="操作面板"
        visible={visibleRestartModal}
        onOk={() => setVisibleRestartModal(false)}
        onCancel={() => setVisibleRestartModal(false)}
      >
        <div>
          <Spin spinning={loading} />
        </div>
        <div style={{ backgroundColor: 'black', borderRadius: '5px' }}>
          <p style={{ color: 'green' }}>{content}</p>
        </div>
      </Modal>
      <ModalRealtimeConfig />
    </div>
  );
}
Example #19
Source File: userChallengeCreate.js    From ctf_platform with MIT License 4 votes vote down vote up
CreateChallengeForm = (props) => {
    const [form] = Form.useForm();
    const [editorValue, setEditorValue] = React.useState("")
    const [existingCats, setExistingCats] = React.useState([])

    useEffect(() => {
        var currentValues = form.getFieldsValue()
        currentValues.flags = [""]

        form.setFieldsValue(currentValues)
        let existCats = []

        for (let i = 0; i < props.allCat.length; i++) {
            existCats.push(<Option key={props.allCat[i]} value={props.allCat[i]}>{props.allCat[i]}</Option>)
        }
        setExistingCats(existCats)
    }, [])



    return (
        <Form
            form={form}
            name="create_challenge_form"
            className="create_challenge_form"
            onFinish={async (values) => {
                props.setState({ edited: false })
                //console.log(values)
                if (typeof values.flags === "undefined") {
                    message.warn("Please enter at least 1 flag")
                }
                else {
                    //console.log(values)
                    props.setState({ loading: true })
                    if (values.visibility === "false") {
                        values.visibility = false
                    }
                    else {
                        values.visibility = true
                    }
                    const category = (typeof values.category1 !== "undefined") ? values.category1 : values.category2
                    if (typeof values.writeup !== "undefined") {
                        if (typeof values.writeupComplete === "undefined") {
                            values.writeupComplete = true
                        }
                    }
                    await fetch(window.ipAddress + "/v1/challenge/new", {
                        method: 'post',
                        headers: { 'Content-Type': 'application/json', "Authorization": window.IRSCTFToken },
                        body: JSON.stringify({
                            "name": values.name,
                            "category": category,
                            "description": values.description,
                            "points": values.points,
                            "flags": values.flags,
                            "tags": values.tags,
                            "hints": values.hints,
                            "max_attempts": values.max_attempts,
                            "visibility": values.visibility,
                            "writeup": values.writeup,
                            "writeupComplete": values.writeupComplete
                        })
                    }).then((results) => {
                        return results.json(); //return data in JSON (since its JSON data)
                    }).then((data) => {
                        //console.log(data)
                        if (data.success === true) {
                            message.success({ content: "Created challenge " + values.name + " successfully!" })
                            form.resetFields()
                        }
                        else {
                            message.error({ content: "Oops. Unknown error, please contact an admin." })
                        }



                    }).catch((error) => {
                        console.log(error)
                        message.error({ content: "Oops. Issue connecting with the server or client error, please check console and report the error. " });
                    })
                    props.setState({ loading: false })


                }

            }}
        >
            <h1>Challenge Name:</h1>
            <Form.Item
                name="name"
                rules={[{ required: true, message: 'Please enter a challenge name' }]}
            >

                <Input allowClear placeholder="Challenge name" />
            </Form.Item>

            <Divider />

            <h1>Challenge Category:</h1>
            <h4>Select an Existing Category: </h4>
            <Form.Item
                name="category1"
                rules={[{ required: !props.state.selectCatDisabled, message: 'Please enter a challenge category' }]}
            >

                <Select
                    disabled={props.state.selectCatDisabled}
                    allowClear
                    showSearch
                    placeholder="Select an existing Category"
                    onChange={(value) => {
                        if (value) {
                            props.setState({ inputCatDisabled: true })
                        }
                        else {
                            props.setState({ inputCatDisabled: false })
                        }
                    }}
                >
                    {existingCats}
                </Select>

            </Form.Item>
            <h4>Enter a New Category</h4>
            <Form.Item
                name="category2"
                rules={[{ required: !props.state.inputCatDisabled, message: 'Please enter a challenge category' }]}
            >

                <Input onChange={(e) => {
                    e.target.value.length > 0 ? props.setState({ selectCatDisabled: true }) : props.setState({ selectCatDisabled: false })
                }} disabled={props.state.inputCatDisabled} allowClear placeholder="Enter a new challenge category" />
            </Form.Item>

            <Divider />

            <Suspense fallback={<div style={{ height: "100%", width: "100%", display: "flex", justifyContent: "center", alignItems: "center", zIndex: 15 }}>
                <Ellipsis color="#177ddc" size={120} ></Ellipsis>
            </div>}>
                <h1>Challenge Description (Supports <a href="https://guides.github.com/features/mastering-markdown/" target="_blank" rel="noreferrer">Markdown</a> and <a href="https://github.com/rehypejs/rehype-raw" target="_blank" rel="noreferrer">HTML</a>)):</h1>
                <Form.Item
                    name="description"
                    rules={[{ required: true, message: 'Please enter a description' }]}
                    valuePropName={editorValue}
                >
                    <MDEditor value={editorValue} onChange={(value) => { setEditorValue(value) }} preview="edit" />
                </Form.Item>
                <h3>Challenge Description Preview</h3>
                <Card
                    type="inner"
                    bordered={true}
                    bodyStyle={{ backgroundColor: "#262626", textAlign: "center" }}
                    className="challengeModal"
                >
                    <MarkdownRender>{editorValue}</MarkdownRender>
                </Card>
            </Suspense>


            <Divider />

            <div style={{ display: "flex", flexDirection: "row", justifyItems: "space-evenly", marginLeft: "2vw" }}>

                <div style={{ display: "flex", flexDirection: "column", justifyContent: "center", width: "35vw" }}>
                    <h1>Challenge Points:</h1>
                    <Form.Item
                        name="points"
                        rules={[{ required: true, message: 'Please enter challenge points' }, {
                            type: 'integer',
                            message: "Please enter a valid integer between 1-100000",
                        },]}
                        initialValue={1}
                    >

                        <InputNumber min={1} max={100000} style={{ width: "30ch" }} ></InputNumber>
                    </Form.Item>

                    <h1>Maximum Number of Attempts (Set to 0 for unlimited)</h1>
                    <Form.Item
                        name="max_attempts"
                        rules={[{ required: true, message: 'Please enter the maximum number of attempts' }, {
                            type: 'integer',
                            message: "Please enter a valid integer between 0-10000",
                        },]}
                        style={{ alignText: 'center' }}
                        initialValue={0}
                    >

                        <InputNumber min={0} max={10000} style={{ width: "30ch" }}></InputNumber>
                    </Form.Item>
                </div>

                <Divider type="vertical" style={{ height: "inherit" }}></Divider>

                <div style={{ display: "flex", flexDirection: "column", width: "35vw", marginLeft: "2vw" }}>
                    <Form.List name="flags" >
                        {(fields, { add, remove }) => {
                            return (
                                <div>
                                    <h1>Flags</h1>
                                    {fields.map(field => (
                                        <Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="start">
                                            <Form.Item
                                                {...field}
                                                name={[field.name]}
                                                fieldKey={[field.fieldKey]}
                                                rules={[{ required: true, message: 'Missing flag' }]}
                                            >
                                                <Input style={{ width: "50ch" }} placeholder="Flag" />
                                            </Form.Item>

                                            {fields.length > 1 ? (
                                                <MinusCircleOutlined
                                                    className="dynamic-delete-button"
                                                    style={{ margin: '0 8px', color: "red" }}
                                                    onClick={() => {
                                                        remove(field.name);
                                                    }}
                                                />
                                            ) : null}
                                        </Space>
                                    ))}

                                    <Form.Item>
                                        <Button
                                            type="dashed"
                                            onLoad={() => { if (fields.length < 1) add() }}
                                            onClick={() => {
                                                add();
                                            }}
                                            block
                                            style={{ width: "50ch" }}
                                        >
                                            <PlusOutlined /> Add Flag
                                        </Button>
                                    </Form.Item>


                                </div>
                            );
                        }}
                    </Form.List>

                    <Form.List name="tags">
                        {(fields, { add, remove }) => {
                            return (
                                <div>
                                    <h1>Tags</h1>
                                    {fields.map(field => (
                                        <Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="start">

                                            <Form.Item
                                                {...field}
                                                name={[field.name]}
                                                fieldKey={[field.fieldKey]}
                                                rules={[{ required: true, message: 'Missing tag' }]}
                                            >
                                                <Input placeholder="Tag" style={{ width: "50ch" }} />
                                            </Form.Item>


                                            <MinusCircleOutlined
                                                className="dynamic-delete-button"
                                                style={{ margin: '0 8px', color: "red" }}
                                                onClick={() => {
                                                    remove(field.name);
                                                }}
                                            />
                                        </Space>
                                    ))}

                                    <Form.Item>
                                        <Button
                                            type="dashed"
                                            onClick={() => {
                                                add();
                                            }}
                                            block
                                            style={{ width: "50ch" }}
                                        >
                                            <PlusOutlined /> Add Tag
                                        </Button>
                                    </Form.Item>
                                </div>
                            );
                        }}
                    </Form.List>
                </div>
            </div>

            <Divider />

            <h1>Hints</h1>
            <Form.List name="hints" >
                {(fields, { add, remove }) => {
                    return (
                        <div>
                            {fields.map(field => (
                                <Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="start">
                                    <Form.Item
                                        {...field}
                                        name={[field.name, "hint"]}
                                        fieldKey={[field.fieldKey, "hint"]}
                                        rules={[{ required: true, message: 'Missing hint' }]}
                                    >
                                        <Input placeholder="Hint" style={{ width: "20vw" }} />
                                    </Form.Item>

                                    <Form.Item
                                        {...field}
                                        name={[field.name, "cost"]}
                                        fieldKey={[field.fieldKey, "cost"]}
                                        rules={[{ required: true, message: 'Missing cost for hint' }, {
                                            type: 'integer',
                                            message: "Please enter a valid integer between 0-10000",
                                        },]}
                                    >
                                        <InputNumber min={0} max={10000} placeholder="Cost"></InputNumber>
                                    </Form.Item>

                                    <MinusCircleOutlined
                                        style={{ color: "red" }}
                                        onClick={() => {
                                            remove(field.name);
                                        }}
                                    />
                                </Space>
                            ))}

                            <Form.Item>
                                <Button
                                    type="dashed"
                                    onClick={() => {
                                        add();
                                    }}
                                    block
                                    style={{ width: "50ch" }}
                                >
                                    <PlusOutlined /> Add Hint
                                </Button>
                            </Form.Item>
                        </div>
                    );
                }}
            </Form.List>

            <h1>Writeup Link (Optional)</h1>
            <Form.Item
                name="writeup"
                rules={[
                    {
                        type: 'url',
                        message: "Please enter a valid link",
                    }]}
            >

                <Input allowClear style={{ width: "50ch" }} placeholder="Enter a writeup link for this challenge" />
            </Form.Item>
            <div style={{ display: "flex", alignContent: "center" }}>
                <h4 style={{ marginRight: "2ch" }}>Release Writeup Only After Completion: </h4>
                <Form.Item
                    name="writeupComplete"
                >
                    <Switch defaultChecked />
                </Form.Item>
            </div>

            <h1>Visibility</h1>
            <Form.Item
                name="visibility"
                rules={[{ required: true, message: 'Please set the challenge visibility' }]}
                initialValue="false"
            >
                <Select style={{ width: "10vw" }}>
                    <Option value="false"><span style={{ color: "#d32029" }}>Hidden <EyeInvisibleOutlined /></span></Option>
                    <Option value="true"><span style={{ color: "#49aa19" }}>Visible <EyeOutlined /></span></Option>
                </Select>

            </Form.Item>

            <Form.Item>
                <div style={{ display: "flex", justifyContent: "space-between", flexDirection: "row" }}>
                    <div>
                        <Button style={{ marginBottom: "1.5vh", marginRight: "2vw", backgroundColor: "#d4b106", borderColor: "", color: "white" }} onClick={() => { props.previewChallenge(form.getFieldsValue()); }}>Preview</Button>
                        <Button loading={props.loadingStatus} type="primary" htmlType="submit" className="login-form-button" style={{ marginBottom: "1.5vh" }}>Create Challenge</Button>
                    </div>
                    <div>
                        <Button style={{ marginRight: "2vw" }} type="primary" danger onClick={() => { form.resetFields() }}>Clear</Button>
                    </div>
                </div>
            </Form.Item>

        </Form>
    );

}
Example #20
Source File: adminChallenges.js    From ctf_platform with MIT License 4 votes vote down vote up
render() {
        return (

            <Layout style={{ height: "100%", width: "100%", backgroundColor: "rgba(0, 0, 0, 0)" }}>

                <Modal title={<span><UploadOutlined/> Upload Challenges</span>} visible={this.state.uploadModalVisible} footer={null} onCancel={() => {this.setState({uploadModalVisible: false})}}>
                    <UploadChallengesForm handleRefresh={this.handleRefresh.bind(this)} closeUploadChallenges={() => {this.setState({uploadModalVisible: false})}}/>
                </Modal>
                <div style={{ display: (!this.state.challengeCreate && !this.state.editChallenge) ? "initial" : "none" }}>
                    <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
                        <div style={{ display: "flex", alignItems: "center", height: "2ch" }}>
                            <Button type="primary" style={{ marginBottom: "2vh", marginRight: "1ch" }} icon={<FlagOutlined />} onClick={() => { this.setState({ challengeCreate: true }, this.props.history.push("/Admin/Challenges/Create")) }}>Create New Challenge</Button>
                            <Button type="primary" style={{ marginBottom: "2vh", marginRight: "1ch" }} icon={<UploadOutlined />} onClick={() => { this.setState({uploadModalVisible: true}) }}>Upload Challenges</Button>
                            {this.state.loading && (
                                <div style={{ display: "flex", justifyContent: "center", alignItems: "center" }}>
                                    <Ellipsis color="#177ddc" size={60} />
                                    <h1>Loading Challenges</h1>
                                </div>
                            )}
                        </div>
                        <Button loading={this.state.loading} type="primary" shape="circle" size="large" style={{ marginBottom: "2vh", maxWidth: "25ch" }} icon={<RedoOutlined />} onClick={async () => { await this.handleRefresh(); message.success("Challenge list refreshed.") }} />

                    </div>
                    <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
                        <div style={{ display: "flex", alignItems: "center" }}>
                            <Button disabled={this.state.disableEditButtons} type="default" style={{ marginBottom: "2vh", marginRight: "1ch", backgroundColor: "#6e6e6e" }} icon={<EyeOutlined style={{ color: "#49aa19" }} />} onClick={() => { this.editChallengeVisibility(true, this.state.selectedTableKeys, this.state.selectedRows) }}>Show</Button>
                            <Button disabled={this.state.disableEditButtons} type="default" style={{ marginBottom: "2vh", marginRight: "1ch", backgroundColor: "#6e6e6e" }} icon={<EyeInvisibleOutlined style={{ color: "#d32029" }} />} onClick={() => { this.editChallengeVisibility(false, this.state.selectedTableKeys, this.state.selectedRows) }}>Hide</Button>
                            <Button disabled={this.state.disableEditButtons} style={{ marginBottom: "2vh", marginRight: "1ch", backgroundColor: "#a61d24" }} icon={<DeleteOutlined />} onClick={() => {
                                confirm({
                                    confirmLoading: this.state.disableEditButtons,
                                    title: 'Are you sure you want to delete the challenge(s) (' + this.state.selectedTableKeys.join(", ") + ')? This action is irreversible.',
                                    icon: <ExclamationCircleOutlined />,
                                    onOk: (close) => { this.deleteChallenge(close.bind(this), this.state.selectedTableKeys, this.state.selectedRows) },
                                    onCancel: () => { },
                                });
                            }}>Delete Challenges</Button>
                        </div>
                        <div>
                            <Button disabled={this.state.disableEditButtons} type="primary" style={{ marginBottom: "2vh", marginRight: "1ch" }} icon={<DownloadOutlined />} onClick={() => { this.downloadChallenges(this.state.selectedRows) }}>Download</Button>
                        </div>
                    </div>
                    <Table rowSelection={{ selectedRowKeys: this.state.selectedTableKeys, onChange: this.handleTableSelect.bind(this) }} style={{ overflow: "auto" }} dataSource={this.state.dataSource} locale={{
                        emptyText: (
                            <div style={{ display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", marginTop: "10vh" }}>
                                <FileUnknownTwoTone style={{ color: "#177ddc", fontSize: "400%", zIndex: 1 }} />
                                <h1 style={{ fontSize: "200%" }}>No Challenges Found/Created</h1>
                            </div>
                        )
                    }}>
                        <Column title="Name" dataIndex="name" key="name"
                            render={(text, row, index) => {
                                return <Link to={"/Challenges/" + row._id}><a style={{ fontWeight: 700 }}>{text}</a></Link>;
                            }}
                            filterDropdown={({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => (
                                <div style={{ padding: 8 }}>
                                    <Input
                                        autoFocus
                                        placeholder="Search Challenge Name"
                                        value={selectedKeys[0]}
                                        onChange={e => setSelectedKeys(e.target.value ? [e.target.value] : [])}
                                        onPressEnter={() => confirm()}
                                        style={{ marginBottom: 8, display: 'block' }}
                                    />
                                    <Space>
                                        <Button
                                            type="primary"
                                            onClick={() => { confirm() }}
                                            icon={<SearchOutlined />}
                                        >
                                            Search
                                        </Button>
                                        <Button onClick={() => clearFilters()}>
                                            Reset
                                        </Button>
                                    </Space>
                                </div>
                            )}
                            onFilter={(value, record) => record.name.toLowerCase().trim().includes(value.toLowerCase())}
                            filterIcon={filtered => <SearchOutlined style={{ color: filtered ? '#1890ff' : undefined }} />}
                            sorter={(a, b) => {
                                if (a.name < b.name) return -1
                                else return 1
                            }}
                        />
                        <Column filters={this.state.allCat.map(value => { return { text: value.key, value: value.key } })} onFilter={(value, record) => value === record.category} title="Category" dataIndex="category" key="category" render={(text, row, index) => {
                            return <Link to={"/Challenges/" + row.category}><a style={{ fontWeight: 700 }}>{text}</a></Link>;
                        }} />
                        <Column sorter={(a, b) => a.points - b.points} title="Points" dataIndex="points" key="points" />
                        <Column sorter={(a, b) => a.points - b.points} title="Initial Points" dataIndex="initial" key="initial" />
                        <Column sorter={(a, b) => a.points - b.points} title="Solves to Min." dataIndex="minSolves" key="minSolves" />
                        <Column sorter={(a, b) => a.points - b.points} title="Min. Points" dataIndex="minimum" key="minimum" />
                        <Column filters={[{ text: "Visible", value: "true" }, { text: "Hidden", value: "false" }]} onFilter={(value, record) => { return value === record.visibility.props.visibility }} title="Visbility" dataIndex="visibility" key="visibility" />
                        <Column title="Required Challenge" dataIndex="requires" key="requires"
                            render={(text, row, index) => {
                                return <Link to={"/Challenges/" + text}><a style={{ fontWeight: 700 }}>{this.state.IDNameMapping[text]}</a></Link>;
                            }}
                            filterDropdown={({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => (
                                <div style={{ padding: 8 }}>
                                    <Input
                                        autoFocus
                                        placeholder="Search Challenge Name"
                                        value={selectedKeys[0]}
                                        onChange={e => setSelectedKeys(e.target.value ? [e.target.value] : [])}
                                        onPressEnter={() => confirm()}
                                        style={{ marginBottom: 8, display: 'block' }}
                                    />
                                    <Space>
                                        <Button
                                            type="primary"
                                            onClick={() => { confirm() }}
                                            icon={<SearchOutlined />}
                                        >
                                            Search
                                        </Button>
                                        <Button onClick={() => clearFilters()}>
                                            Reset
                                        </Button>
                                    </Space>
                                </div>
                            )}
                            onFilter={(value, record) => { if (record.requires) return this.state.IDNameMapping[record.requires].toLowerCase().includes(value) }}
                            filterIcon={filtered => <SearchOutlined style={{ color: filtered ? '#1890ff' : undefined }} />}
                            sorter={(a, b) => {
                                if (!a.requires) return -1
                                if (!b.requires) return 1
                                if (this.state.IDNameMapping[a.requires] < this.state.IDNameMapping[b.requires]) return -1
                                else return 1
                            }}
                        />
                        <Column
                            title=""
                            key="edit"
                            render={(text, record) => (
                                <Button icon={<EditOutlined />} onClick={() => { this.setState({ editChallenge: true, id: record._id }); this.props.history.push("/Admin/Challenges/Edit") }}> Edit</Button>
                            )}
                        />
                    </Table>

                    <Divider />
                    <div style={{ display: "flex", alignItems: "center" }}>
                        <h1 style={{ fontSize: "150%" }}>Category Management </h1>{this.state.transferDisabled && (<Ellipsis color="#177ddc" size={50} />)}
                    </div>

                    <Card className="settings-card">
                        <h3>Category Meta Information Editor <EyeOutlined /></h3>
                        <p>Select a category to edit info such as Name, Cover Pictures etc.</p>

                        <Select style={{ width: "30ch" }} value={this.state.categorySelect} onChange={this.openCategoryEditor.bind(this)}>
                            {this.state.categoryOptions}
                        </Select>

                        {this.state.currentEditCategory && (
                            <div style={{ padding: "10px", marginTop: "20px", backgroundColor: "rgba(0, 0, 0, 0.3)", border: "5px solid transparent", borderRadius: "10px" }}>
                                <EditCategoryForm initialData={this.state.currentEditCategory} handleEditCategoryDone={this.handleEditCategoryDone.bind(this)} />
                            </div>
                        )}
                    </Card>
                    <Card className="settings-card">
                        <h3>Category Visibility <EyeOutlined /></h3>
                        <Transfer
                            dataSource={this.state.allCat}
                            titles={[<span style={{ color: "#49aa19" }}>Visible Categories <EyeOutlined /></span>, <span style={{ color: "#d32029" }} >Hidden Categories <EyeInvisibleOutlined /></span>]}
                            targetKeys={this.state.targetKeys}
                            selectedKeys={this.state.selectedKeys}
                            onChange={this.handleChange}
                            onSelectChange={this.handleSelectChange}
                            render={item => item.key}
                            pagination
                            disabled={this.state.transferDisabled}
                        />
                    </Card>

                    <Divider />

                    <div className="settings-responsive2" style={{ display: "flex", justifyContent: "space-around" }}>

                        <Card className="settings-card">
                            <h3>Disable Submissions:  <AntdSwitch disabled={this.state.disableLoading} onClick={(value) => this.disableSetting("submissionDisabled", value)} checked={this.state.submissionDisabled} /></h3>
                            <p>Prevents users from submitting any new submissions for all challenges. Hints can still be bought</p>
                        </Card>

                        <Divider type="vertical" style={{ height: "inherit" }} />

                        <Card className="settings-card">
                            <h3>Set Socket Limit:  <InputNumber
                                value={this.state.maxSockets}
                                disabled={this.state.disableLoading}
                                onChange={(value) => this.setState({ maxSockets: value })}
                                onPressEnter={(e) => { this.changeSetting("maxSockets", this.state.maxSockets) }} /></h3>
                            <p>Sets the maximum number of socket connections allowed <b>per account</b> to connect to the live scoreboard. <br /> <b>Press "Enter" to save</b></p>
                        </Card>

                        <Divider type="vertical" style={{ height: "inherit" }} />

                        <Card className="settings-card">
                        <h3>Disable First Blood for No Category:  <AntdSwitch disabled={this.state.disableLoading} onClick={(value) => this.disableSetting("disableNonCatFB", value)} checked={this.state.disableNonCatFB} /></h3>
                            <p>Prevents people with no categories from attaining first blood. Useful if you want to limit First Blood prizes to only eligible participants.</p>
                        </Card>


                    </div>


                </div>


                <Switch>
                    <Route exact path='/Admin/Challenges/Create' render={(props) => <AdminChallengeCreate {...props} challenges={this.state.dataSource} handleBack={this.handleBack.bind(this)} handleCreateBack={this.handleCreateBack.bind(this)} allCat={this.state.allCat} />} />
                    <Route exact path='/Admin/Challenges/Edit' render={(props) => <AdminChallengeEdit {...props} allCat={this.state.allCat} IDNameMapping={this.state.IDNameMapping} challenges={this.state.dataSource} id={this.state.id} handleEditBack={this.handleEditBack.bind(this)} handleEditChallBack={this.handleEditChallBack.bind(this)} />} />

                </Switch>

            </Layout>
        );
    }
Example #21
Source File: adminChallengeEdit.js    From ctf_platform with MIT License 4 votes vote down vote up
CreateChallengeForm = (props) => {
    const [form] = Form.useForm();
    const [editorValue, setEditorValue] = React.useState("")
    const [existingCats, setExistingCats] = React.useState([])
    const [finalSortedChalls, setFinalSortedChalls] = React.useState([])

    //Render existing categories select options

    useEffect(() => {
        let existingCats = []
        for (let i = 0; i < props.allCat.length; i++) {
            existingCats.push(<Option key={props.allCat[i].key} value={props.allCat[i].key}>{props.allCat[i].key}</Option>)
        }
        //Render existing challenges select options minus the challenge itself
        let existingChalls = {}
        for (let i = 0; i < props.challenges.length; i++) {
            if (props.challenges[i].name !== props.initialData.name) {
                if (!(props.challenges[i].category in existingChalls)) existingChalls[props.challenges[i].category] = []
                existingChalls[props.challenges[i].category].push({
                    value: props.challenges[i]._id,
                    label: props.challenges[i].name
                })
            }
        }
        setExistingCats(existingCats)
        let finalSortedChalls = []
        for (const category in existingChalls) {
            finalSortedChalls.push({
                value: category,
                label: category,
                children: existingChalls[category]
            })
        }
        setFinalSortedChalls(finalSortedChalls)
        let initialData = JSON.parse(JSON.stringify(props.initialData))

        if (props.initialData.visibility === false) {
            initialData.visibility = "false"
        }
        else if (props.initialData.visibility === true) {
            initialData.visibility = "true"
        }
        // if we put only props.initialData.requires, we are merely putting a reference to props.initialData.requires, which is this array, creating a "loop"

        if (props.initialData.requires) initialData.requires = [props.IDNameMapping[props.initialData.requires], props.initialData.requires]
        if (props.initialData.dynamic === false) {
            initialData.dynamic = "false"
        }
        else if (props.initialData.dynamic === true) {
            initialData.dynamic = "true"
            props.setState({ dynamic: true })
        }
        else {
            initialData.dynamic = "false"
        }
        initialData.category1 = initialData.category
        form.setFieldsValue(initialData)
        setEditorValue(initialData.description)
    }, [])

    return (
        <Form
            form={form}
            name="create_challenge_form"
            className="create_challenge_form"
            onValuesChange={() => { if (props.state.edited === false) props.setState({ edited: true }) }}
            onFinish={async (values) => {
                props.setState({ edited: false })
                if (typeof values.flags === "undefined") {
                    message.warn("Please enter at least 1 flag")
                }
                else {
                    if (values.visibility === "false") {
                        values.visibility = false
                    }
                    else {
                        values.visibility = true
                    }
                    if (values.dynamic === "false") {
                        values.dynamic = false
                    }
                    else {
                        values.dynamic = true
                    }
                    if (typeof values.writeup !== "undefined") {
                        if (typeof values.writeupComplete === "undefined") {
                            values.writeupComplete = true
                        }
                    }
                    const category = (typeof values.category1 !== "undefined") ? values.category1 : values.category2
                    props.setState({ editLoading: true })
                    let requires = ""
                    if (values.requires && values.requires.length > 0) requires = values.requires[1]
                    await fetch(window.ipAddress + "/v1/challenge/edit", {
                        method: 'post',
                        headers: { 'Content-Type': 'application/json', "Authorization": window.IRSCTFToken },
                        body: JSON.stringify({
                            "id": props.initialData._id,
                            "name": values.name,
                            "category": category,
                            "description": values.description,
                            "points": values.points,
                            "flags": values.flags,
                            "tags": values.tags,
                            "hints": values.hints,
                            "max_attempts": values.max_attempts,
                            "visibility": values.visibility,
                            "writeup": values.writeup,
                            "writeupComplete": values.writeupComplete,
                            "requires": requires,
                            "dynamic": values.dynamic,
                            "initial": values.initial,
                            "minSolves": values.minSolves,
                            "minimum": values.minimum
                        })
                    }).then((results) => {
                        return results.json(); //return data in JSON (since its JSON data)
                    }).then((data) => {
                        if (data.success === true) {
                            message.success({ content: "Edited challenge \"" + props.initialData.name + "\" successfully!" })
                            props.handleEditChallBack()
                            setEditorValue("")
                            form.resetFields()
                        }
                        else if (data.error === "exists") {
                            message.warn("A challenge with an existing name exists")
                        }
                        else {
                            message.error({ content: "Oops. Unknown error" })
                        }


                    }).catch((error) => {
                        console.log(error)
                        message.error({ content: "Oops. There was an issue connecting with the server" });
                    })
                    props.setState({ editLoading: false })

                }

            }}
        >
            <Prompt
                when={props.state.edited}
                message='The challenge details you modified have not been saved. Are you sure you want to leave?'
            />
            <p><b><u>ID:</u></b> <code>{props.initialData._id}</code></p>


            <h1>Challenge Name:</h1>
            <Form.Item
                name="name"
                rules={[{ required: true, message: 'Please enter a challenge name' }]}
            >

                <Input allowClear placeholder="Challenge name" />
            </Form.Item>


            <Divider />
            <h1>Challenge Category:</h1>
            <h4>Select an Existing Category: </h4>
            <Form.Item
                name="category1"
                initialValue={""}
                rules={[{ required: !props.state.selectCatDisabled, message: 'Please enter a challenge category' }]}
            >

                <Select
                    disabled={props.state.selectCatDisabled}
                    allowClear
                    showSearch
                    placeholder="Select an existing Category"
                    onChange={(value) => {
                        if (value) {
                            props.setState({ inputCatDisabled: true })
                        }
                        else {
                            props.setState({ inputCatDisabled: false })
                        }
                    }}
                >
                    {existingCats}
                </Select>

            </Form.Item>
            <h4>Enter a New Category</h4>
            <Form.Item
                name="category2"
                rules={[{ required: !props.state.inputCatDisabled, message: 'Please enter a challenge category' }]}
            >

                <Input onChange={(e) => {
                    e.target.value.length > 0 ? props.setState({ selectCatDisabled: true }) : props.setState({ selectCatDisabled: false })
                }} disabled={props.state.inputCatDisabled} allowClear placeholder="Enter a new challenge category" />
            </Form.Item>

            <Divider />

            <h1>Challenge Description (Supports <a href="https://guides.github.com/features/mastering-markdown/" target="_blank" rel="noreferrer">Markdown</a> and <a href="https://github.com/rehypejs/rehype-raw" target="_blank" rel="noreferrer">HTML</a>)):</h1>
            <Suspense fallback={<div style={{ height: "100%", width: "100%", display: "flex", justifyContent: "center", alignItems: "center", zIndex: 15 }}>
                <Ellipsis color="#177ddc" size={120} ></Ellipsis>
            </div>}>
                <Form.Item
                    name="description"
                    rules={[{ required: true, message: 'Please enter a description' }]}
                    valuePropName={editorValue}
                >
                    <MDEditor value={editorValue} onChange={(value) => { setEditorValue(value) }} preview="edit" />
                </Form.Item>

                <h3>Challenge Description Preview</h3>
                <Card
                    type="inner"
                    bordered={true}
                    bodyStyle={{ backgroundColor: "#262626", textAlign: "center" }}
                    className="challengeModal"
                >
                    <MarkdownRender>{editorValue}</MarkdownRender>
                </Card>
            </Suspense>


            <Divider />

            <div className="settings-responsive2" style={{ display: "flex", justifyContent: "space-around" }}>

                <div style={{ display: "flex", flexDirection: "column", justifyContent: "center", alignContent: "center" }}>

                    <Card className="settings-card">
                        <h1>Challenge Points:</h1>
                        <Form.Item
                            name="points"
                            rules={[{ required: true, message: 'Please enter challenge points' }, {
                                type: 'integer',
                                message: "Please enter a valid integer between 0-100000",
                            },]}
                            initialValue={0}
                        >

                            <InputNumber disabled={props.state.dynamic} min={0} max={100000} style={{ width: "30ch" }} ></InputNumber>
                        </Form.Item>
                    </Card>

                    <Card className="settings-card">
                        <h1>Maximum Number of Attempts (Set to 0 for unlimited)</h1>
                        <Form.Item
                            name="max_attempts"
                            rules={[{ required: true, message: 'Please enter the maximum number of attempts' }, {
                                type: 'integer',
                                message: "Please enter a valid integer between 0-10000",
                            },]}
                            style={{ alignText: 'center' }}
                            initialValue={0}
                        >

                            <InputNumber min={0} max={10000} style={{ width: "30ch" }}></InputNumber>
                        </Form.Item>
                    </Card>
                </div>

                <Divider type="vertical" style={{ height: "inherit" }}></Divider>

                <div style={{ display: "flex", flexDirection: "column" }}>
                    <Form.List name="flags" >
                        {(fields, { add, remove }) => {

                            return (
                                <Card className="settings-card">
                                    <h1>Flags</h1>
                                    {fields.map(field => (
                                        <Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="start">
                                            <Form.Item
                                                {...field}
                                                name={[field.name]}
                                                fieldKey={[field.fieldKey]}
                                                rules={[{ required: true, message: 'Missing flag' }, { message: "Please enter a flag that is < 1000 characters", pattern: /^.{1,1000}$/ }]}
                                            >
                                                <Input style={{ width: "50ch" }} placeholder="Flag" />
                                            </Form.Item>

                                            {fields.length > 1 ? (
                                                <MinusCircleOutlined
                                                    className="dynamic-delete-button"
                                                    style={{ margin: '0 8px', color: "red" }}
                                                    onClick={() => {
                                                        remove(field.name);
                                                    }}
                                                />
                                            ) : null}
                                        </Space>
                                    ))}

                                    <Form.Item>
                                        <Button
                                            type="dashed"
                                            onLoad={() => { if (fields.length < 1) add() }}
                                            onClick={() => {
                                                add();
                                            }}
                                            block
                                            style={{ width: "50ch" }}
                                        >
                                            <PlusOutlined /> Add Flag
                                        </Button>
                                    </Form.Item>


                                </Card>
                            );
                        }}
                    </Form.List>

                    <Form.List name="tags">
                        {(fields, { add, remove }) => {
                            return (
                                <Card className="settings-card">
                                    <h1>Tags</h1>
                                    {fields.map(field => (
                                        <Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="start">
                                            <Form.Item
                                                {...field}
                                                name={[field.name]}
                                                fieldKey={[field.fieldKey]}
                                                rules={[{ required: true, message: 'Missing tag' }]}
                                            >
                                                <Input placeholder="Tag" style={{ width: "50ch" }} />
                                            </Form.Item>


                                            <MinusCircleOutlined
                                                className="dynamic-delete-button"
                                                style={{ margin: '0 8px', color: "red" }}
                                                onClick={() => {
                                                    remove(field.name);
                                                }}
                                            />
                                        </Space>
                                    ))}

                                    <Form.Item>
                                        <Button
                                            type="dashed"
                                            onClick={() => {
                                                add();
                                            }}
                                            block
                                            style={{ width: "50ch" }}
                                        >
                                            <PlusOutlined /> Add Tag
                                        </Button>
                                    </Form.Item>
                                </Card>
                            );
                        }}
                    </Form.List>
                </div>
            </div>

            <Divider />
            <div className="settings-responsive2" style={{ display: "flex", justifyContent: "space-around" }}>

                <div style={{ display: "flex", flexDirection: "column" }}>

                    <Form.List name="hints" >
                        {(fields, { add, remove }) => {
                            return (
                                <Card className="settings-card">
                                    <h1>Hints</h1>
                                    {fields.map(field => (
                                        <Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="start">
                                            <Form.Item
                                                {...field}
                                                name={[field.name, "hint"]}
                                                fieldKey={[field.fieldKey, "hint"]}
                                                rules={[{ required: true, message: 'Missing hint' }]}
                                            >
                                                <Input placeholder="Hint" style={{ width: "20vw" }} />
                                            </Form.Item>

                                            <Form.Item
                                                {...field}
                                                name={[field.name, "cost"]}
                                                fieldKey={[field.fieldKey, "cost"]}
                                                rules={[{ required: true, message: 'Missing cost for hint' }, {
                                                    type: 'integer',
                                                    message: "Please enter a valid integer between 0-10000",
                                                },]}
                                            >
                                                <InputNumber min={0} max={10000} placeholder="Cost"></InputNumber>
                                            </Form.Item>

                                            <MinusCircleOutlined
                                                style={{ color: "red" }}
                                                onClick={() => {
                                                    remove(field.name);
                                                }}
                                            />
                                        </Space>
                                    ))}

                                    <Form.Item>
                                        <Button
                                            type="dashed"
                                            onClick={() => {
                                                add();
                                            }}
                                            block
                                            style={{ width: "50ch" }}
                                        >
                                            <PlusOutlined /> Add Hint
                                        </Button>
                                    </Form.Item>
                                </Card>
                            );
                        }}
                    </Form.List>

                    <Card className="settings-card">
                        <h1>Writeup Link (Optional)</h1>
                        <Form.Item
                            name="writeup"
                            rules={[
                                {
                                    type: 'url',
                                    message: "Please enter a valid link",
                                }]}
                        >

                            <Input allowClear style={{ width: "50ch" }} placeholder="Enter a writeup link for this challenge" />
                        </Form.Item>
                        <div style={{ display: "flex", alignContent: "center" }}>
                            <h4 style={{ marginRight: "2ch" }}>Release Writeup Only After Completion: </h4>
                            <Form.Item
                                name="writeupComplete"
                            >
                                <Switch defaultChecked />
                            </Form.Item>
                        </div>
                    </Card>

                    <Card className="settings-card">
                        <h1>Visibility</h1>
                        <Form.Item
                            name="visibility"
                            rules={[{ required: true, message: 'Please set the challenge visibility' }]}
                            initialValue="false"
                        >
                            <Select style={{ width: "20ch" }}>
                                <Option value="false"><span style={{ color: "#d32029" }}>Hidden <EyeInvisibleOutlined /></span></Option>
                                <Option value="true"><span style={{ color: "#49aa19" }}>Visible <EyeOutlined /></span></Option>
                            </Select>

                        </Form.Item>
                    </Card>

                </div>

                <Divider type="vertical" style={{ height: "inherit" }} />


                <div style={{ display: "flex", flexDirection: "column" }}>
                    <Card>
                        <h1>Challenge Required: </h1>
                        <Form.Item
                            name="requires"
                        >
                            {/*
                        The issue with this is that displayRender is supposed to return an array, 
                        but setting a value causes it to become a string and error out
                        */}
                            <Cascader
                                options={finalSortedChalls}
                                allowClear
                                showSearch
                                placeholder="Select an existing challenge" />

                        </Form.Item>
                        <p>Locks this challenge until the provided challenge above has been solved.</p>
                    </Card>

                    <Card className="settings-card">
                        <h1>Dynamic Scoring</h1>
                        <Form.Item
                            name="dynamic"
                            rules={[{ required: props.state.dynamic, message: 'Please set whether the challenge uses dynamic scoring' }]}
                            initialValue="false"
                        >
                            <Select style={{ width: "20ch" }} onSelect={(option) => { option === "false" ? props.setState({ dynamic: false }) : props.setState({ dynamic: true }) }}>
                                <Option value="false"><span style={{ color: "#d32029" }}>Disabled</span></Option>
                                <Option value="true"><span style={{ color: "#49aa19" }}>Enabled</span></Option>
                            </Select>

                        </Form.Item>

                        <h1>Initial Points:</h1>
                        <Form.Item
                            name="initial"
                            rules={[{ required: props.state.dynamic, message: 'Please enter the initial challenge points' }, {
                                type: 'integer',
                                message: "Please enter a valid integer between 1-100000",
                            },]}
                            initialValue={500}
                        >
                            <InputNumber disabled={!props.state.dynamic} min={1} max={100000} ></InputNumber>
                        </Form.Item>
                        <p>Initial number of points when there are 0/1 solves on a challenge</p>

                        <h1>Minimum Points:</h1>
                        <Form.Item
                            name="minimum"
                            rules={[{ required: props.state.dynamic, message: 'Please enter the minimum challenge points' }, {
                                type: 'integer',
                                message: "Please enter a valid integer between 0-100000",
                            },]}
                            initialValue={100}
                        >
                            <InputNumber disabled={!props.state.dynamic} min={0} max={100000} ></InputNumber>
                        </Form.Item>
                        <p>Minimum amount of points that the challenge can decay too</p>

                        <h1>Solves to Minimum:</h1>
                        <Form.Item
                            name="minSolves"
                            rules={[{ required: props.state.dynamic, message: 'Please enter the solves to minimum' }, {
                                type: 'integer',
                                message: "Please enter a valid integer between 1-100000",
                            },]}
                            initialValue={50}
                        >
                            <InputNumber disabled={!props.state.dynamic} min={1} max={100000} ></InputNumber>
                        </Form.Item>
                        <p>Number of solves on the challenge till it decays to the minimum point.</p>
                    </Card>
                </div>
            </div>

            <Form.Item>
                <div style={{ display: "flex", justifyContent: "space-between", flexDirection: "row", marginTop: "3ch" }}>
                    <div>
                        <Button style={{ marginBottom: "1.5vh", marginRight: "2vw", backgroundColor: "#d4b106", borderColor: "", color: "white" }} onClick={() => { props.previewChallenge(form.getFieldsValue()) }}>Preview</Button>
                        <Button type="primary" htmlType="submit" className="login-form-button" style={{ marginBottom: "1.5vh" }} loading={props.editLoading}>Edit Challenge</Button>
                    </div>
                    <div>
                        <Button style={{ marginRight: "2vw" }} type="primary" danger onClick={() => { form.resetFields() }}>Clear</Button>
                    </div>
                </div>
            </Form.Item>

        </Form>
    );
}