@ant-design/icons#EyeInvisibleOutlined JavaScript Examples

The following examples show how to use @ant-design/icons#EyeInvisibleOutlined. 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: 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 #2
Source File: password-input.jsx    From virtuoso-design-system with MIT License 6 votes vote down vote up
storiesOf('antd/Input', module).add('password-input', () => 
  <Space direction="vertical">
    <Input.Password placeholder="input password" />
    <Input.Password
      placeholder="input password"
      iconRender={visible => (visible ? <EyeTwoTone /> : <EyeInvisibleOutlined />)}
    />
  </Space>,
  { docs: { page: () => (<><h1 id="enus">en-US</h1>
<p>Input type of password.</p></>) } });
Example #3
Source File: Login.js    From Peppermint with GNU General Public License v3.0 5 votes vote down vote up
Login = () => {
  const history = useHistory();
  const [password, setPassword] = useState("");
  const [email, setEmail] = useState("");

  const { signin } = useContext(GlobalContext);

  const onSubmit = async () => {
    signin(email, password);
  };

  return (
    <div>
      <Form
        style={{ position: "absolute" }}
        name="normal_login"
        className="login-form"
        initialValues={{
          remember: true,
        }}
      >
        <div className="logo-login">
          <Image alt="logo" src={logo} width={300} preview={false} />
        </div>
        <Form.Item
          name="username"
          rules={[
            {
              required: true,
              message: "Please input your Email!",
            },
          ]}
        >
          <Input
            style={{ width: 300 }}
            prefix={<UserOutlined className="site-form-item-icon" />}
            placeholder="Email"
            onChange={(e) => setEmail(e.target.value)}
          />
        </Form.Item>
        <Form.Item
          name="password"
          rules={[
            {
              required: true,
              message: "Please input your Password!",
            },
          ]}
        >
          <Input.Password
            style={{ width: 300 }}
            prefix={<LockOutlined className="site-form-item-icon" />}
            type="password"
            placeholder="Password"
            iconRender={(visible) =>
              visible ? <EyeTwoTone /> : <EyeInvisibleOutlined />
            }
            onChange={(e) => setPassword(e.target.value)}
          />
        </Form.Item>

        <Form.Item>
          <Button
            type="primary"
            htmlType="submit"
            className="login-form-button"
            onClick={() => {
              onSubmit();
              setTimeout(() => history.push("/"), 1000);
            }}
          >
            Log in
          </Button>
        </Form.Item>
      </Form>
    </div>
  );
}
Example #4
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 #5
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 #6
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>
    );
}
Example #7
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 #8
Source File: challenges.js    From ctf_platform with MIT License 4 votes vote down vote up
render() {
    return (
      <Layout className="layout-style">
        <div id="Header" className="challenge-header-style">

          <h1 style={{
            color: "white",
            fontSize: "280%",
            letterSpacing: ".3rem",
            fontWeight: 300,
            marginBottom: "10px"
          }}> CHALLENGES

          </h1>
          {this.state.currentCategory && (<h4 className="category-header">{this.state.currentCategory}</h4>)}
        </div>
        <div style={{ display: "flex", justifyContent: "space-between", alignContent: "center", marginBottom: "10px", textAlign: "center" }}>

          <Button size="large" disabled={!this.state.currentCategory} icon={<LeftCircleOutlined />} style={{ backgroundColor: "#1f1f1f" }} onClick={() => { this.props.history.push("/Challenges"); this.setState({ currentCategory: false, foundChallenge: false }) }}>Back</Button>

          {this.state.currentCategory && this.state.countDownTimerStrings[this.state.currentCategory] && (
            <h1 style={{
              color: "white",
              fontSize: "170%",
              letterSpacing: ".3rem",
              fontWeight: 300,
              color: "#d89614",
            }}>
              {this.state.countDownTimerStrings[this.state.currentCategory]}
            </h1>
          )}
          <div>
            <Select disabled={!this.state.currentCategory} defaultValue="points" style={{ width: "20ch", backgroundColor: "#1f1f1f" }} onChange={this.sortCats.bind(this)}>
              <Option value="points">Sort by ↑Points</Option>
              <Option value="pointsrev">Sort by ↓Points</Option>
              <Option value="abc">Sort A→Z</Option>
              <Option value="abcrev">Sort Z→A</Option>
            </Select>

          </div>
        </div>


        <div>
          <Transition
            items={this.state.loadingChall}
            from={{ opacity: 0 }}
            enter={{ opacity: 1 }}
            leave={{ opacity: 0 }}>
            {(props, toggle) => {
              if (toggle === true) {
                return (<animated.div style={{ ...props, position: "absolute", left: "55%", transform: "translate(-55%, 0%)", zIndex: 10 }}>
                  <Ellipsis color="#177ddc" size={120} ></Ellipsis>
                </animated.div>)
              }
              else {
                return (<animated.div style={{ ...props }}>
                  {!this.state.currentCategory && (
                    <List
                      grid={{
                        xs: 1,
                        sm: 2,
                        md: 2,
                        lg: 3,
                        xl: 3,
                        xxl: 4,
                        gutter: 20
                      }}
                      dataSource={this.state.categories}
                      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%" }}>Oops, no challenges have been created.</h1>
                          </div>
                        )
                      }}
                      renderItem={item => {
                        return (
                          <List.Item key={item._id}>
                            <Link to={"/Challenges/" + item._id}>
                              <div onClick={() => {
                                this.setState({ currentCategory: item._id, currentSolvedStatus: item.challenges, currentCategoryChallenges: [this.state.originalData[item._id]] });

                              }}>
                                <Card
                                  hoverable
                                  type="inner"
                                  bordered={true}
                                  className="card-design hover"
                                  cover={<img style={{ overflow: "hidden" }} alt="Category Card" src={"/static/category/" + item._id + ".webp"} />}
                                >
                                  <Meta
                                    title={
                                      <div style={{ display: "flex", flexDirection: "column", textAlign: "center" }}>
                                        <div id="Title" style={{ display: "flex", color: "#f5f5f5", alignItems: "center", marginBottom: "2ch" }}>
                                          <h1 style={{ color: "white", fontSize: "2.5ch", width: "40ch", textOverflow: "ellipsis", overflow: "hidden" }}>{item._id}</h1>
                                          <div style={{ display: "flex", justifyContent: "center", alignItems: "center", flexDirection: "column" }}>
                                            <h2 style={{ fontSize: "2.5ch", marginLeft: "1vw", color: "#faad14", fontWeight: 700 }}>{item.challenges.solved}/{item.challenges.challenges}</h2>
                                            <Progress type="circle" percent={item.challenges.percentage} width="7ch" strokeColor={{
                                              '0%': '#177ddc',
                                              '100%': '#49aa19',
                                            }} style={{ marginLeft: "1vw", fontSize: "2ch" }} />
                                          </div>
                                        </div>
                                        <div>
                                          {"time" in item.meta && (
                                            <span style={{
                                              color: "#d89614",
                                              letterSpacing: ".1rem",
                                              fontWeight: 300,
                                              whiteSpace: "initial"
                                            }}>{this.state.countDownTimerStrings[item._id]}</span>
                                          )}
                                          {item.meta.visibility === false && (
                                            <h4 style={{ color: "#d9d9d9" }}>Hidden Category <EyeInvisibleOutlined /></h4>
                                          )}
                                        </div>
                                      </div>
                                    }
                                  />
                                </Card> {/*Pass entire datasource as prop*/}
                              </div>
                            </Link>
                          </ List.Item>
                        )
                      }
                      }
                    />
                  )}

                  {this.state.currentCategory && (
                    <ChallengesTagSort originalData={this.state.originalData} permissions={this.props.permissions} disableNonCatFB={this.state.disableNonCatFB} userCategories={this.state.userCategories} obtainScore={this.props.obtainScore.bind(this)} match={this.props.match} history={this.props.history} foundChallenge={this.state.foundChallenge} currentCategoryChallenges={this.state.currentCategoryChallenges} handleRefresh={this.handleRefresh.bind(this)} ref={this.tagSortRef} category={this.state.currentCategory}></ChallengesTagSort>
                  )}
                </animated.div>)
              }
            }
            }
          </Transition>
        </div>
      </Layout>

    );
  }
Example #9
Source File: challengesTagSort.js    From ctf_platform with MIT License 4 votes vote down vote up
render() {
    return (
      <Layout className="pageTransition" style={{ height: "100%", width: "100%", backgroundColor: "rgba(0, 0, 0, 0)" }}>

        <Modal
          title="Hint"
          visible={this.state.hintModal}
          onCancel={() => { this.setState({ hintModal: false }) }}
          footer={null}
        >
          <p>{this.state.hintContent}</p>
        </Modal>


        <Modal
          title={null}
          visible={this.state.challengeModal}
          footer={null}
          bodyStyle={{ textAlign: "center" }}
          onCancel={() => { this.setState({ challengeModal: false }); this.props.history.push("/Challenges/" + this.props.category); }}
        >
          <Tabs defaultActiveKey="challenge">
            <TabPane
              tab={<span><ProfileOutlined /> Challenge</span>}
              key="challenge"
            >

              {this.state.challengeWriteup !== "" && this.state.challengeWriteup !== "CompleteFirst" && (
                <Tooltip title="View writeups for this challenge">
                  <Button shape="circle" size="large" style={{ position: "absolute", right: "2ch" }} type="primary" icon={<SolutionOutlined />} onClick={() => { window.open(this.state.challengeWriteup) }} />
                </Tooltip>
              )}
              {this.state.challengeWriteup === "" && (
                <Tooltip title="Writeups are not available for this challenge">
                  <Button disabled shape="circle" size="large" style={{ position: "absolute", right: "2ch" }} type="primary" icon={<SolutionOutlined />} />
                </Tooltip>
              )}
              {this.state.challengeWriteup === "CompleteFirst" && (
                <Tooltip title="Writeups are available for this challenge but you must complete the challenge first to view it.">
                  <Button shape="circle" size="large" style={{ position: "absolute", right: "2ch", color: "#13a8a8" }} icon={<SolutionOutlined />} />
                </Tooltip>
              )}
              <Suspense fallback={<div style={{ height: "100%", width: "100%", display: "flex", justifyContent: "center", alignItems: "center", zIndex: 15 }}>
                <Ellipsis color="#177ddc" size={120} ></Ellipsis>
              </div>}>

                <div style={{ display: "flex", justifyContent: "center" }}>
                  <h1 style={{ fontSize: "150%", maxWidth: "35ch", whiteSpace: "initial" }}>{this.state.viewingChallengeDetails.name}
                    <Tooltip title="Copy challenge link to clipboard.">
                      <LinkOutlined style={{ color: "#1890ff", marginLeft: "0.5ch" }} onClick={
                        async () => {
                          await navigator.clipboard.writeText(window.location.href);
                          message.success("Challenge link copied to clipboard.")
                        }} /></Tooltip>
                  </h1>
                </div>
                <div>
                  {this.state.challengeTags}
                </div>
                <h2 style={{ color: "#1765ad", marginTop: "2vh", marginBottom: "6vh", fontSize: "200%" }}>{this.state.viewingChallengeDetails.points}</h2>

                <div className="challengeModal">
                  <MarkdownRender >{this.state.viewingChallengeDetails.description}</MarkdownRender>
                </div>



                <div style={{ marginTop: "6vh", display: "flex", flexDirection: "column" }}>
                  {this.state.challengeHints}
                </div>
              </Suspense>


              <div style={{ display: "flex" }}>
                <SubmitFlagForm submitFlag={this.submitFlag.bind(this)} currentChallengeStatus={this.state.currentChallengeStatus} currentChallengeSolved={this.state.currentChallengeSolved}></SubmitFlagForm>
              </div>
              <div style={{ display: "flex", flexDirection: "row", justifyContent: "space-between", marginTop: "-1vh" }}>
                <p>Challenge Author: <em>{this.state.viewingChallengeDetails.author}</em></p>
                <p style={{ color: "#d87a16", fontWeight: 500 }}>Attempts Remaining: {this.state.viewingChallengeDetails.max_attempts}</p>
              </div>
            </TabPane>
            <TabPane
              tab={<span><UnlockOutlined /> Solves ({this.state.viewingChallengeDetails.solves.length}) </span>}
              key="solves"
            >
              <List
                itemLayout="horizontal"
                dataSource={this.state.viewingChallengeDetails.solves}
                locale={{
                  emptyText: (
                    <div>
                      <SmileOutlined style={{ fontSize: "500%" }} />
                      <br />
                      <br />
                      <p style={{ fontSize: "150%" }}>No solves yet. Maybe you can be the first!</p>
                    </div>
                  )
                }}
                renderItem={item => {
                  return (
                    <List.Item key={item}>
                      <List.Item.Meta
                        avatar={<Avatar src={"/static/profile/" + item + ".webp"} />}
                        title={<Link to={"/Profile/" + item}><a style={{ fontSize: "110%", fontWeight: 700 }} onClick={() => { this.setState({ challengeModal: false }) }}>{item}</a></Link>}
                      />
                    </List.Item>
                  )
                }
                } />
            </TabPane>
          </Tabs>


        </Modal>
        <Divider style={{ marginTop: "0px" }}>Select Tags</Divider>

        <span className="tag-holder" >
          {Object.keys(this.state.tag).map((tag) => {
            return (
              <CheckableTag className="tag-select-style" key={tag} checked={this.state.selectedTags.indexOf(tag) !== -1}
                onChange={(checked) => {

                  let selectedTags = this.state.selectedTags
                  if (!checked) selectedTags.splice(selectedTags.indexOf(tag), 1)
                  else selectedTags.push(tag)

                  if (selectedTags.length === 0) this.sortCats(this.state.sortType, true)

                  this.setState({ selectedTags: selectedTags })
                }}>{tag} <span style={{ color: "#d89614" }}>({this.state.tag[tag].length})</span></CheckableTag>
            )
          })}
        </span>

        <Divider />
        {this.state.tag && this.state.selectedTags.length > 0 ? (
          <ChallengesTagSortList tag={this.state.tag} selectedTags={this.state.selectedTags} permissions={this.props.permissions} loadChallengeDetails={this.loadChallengeDetails.bind(this)} loadingChallenge={this.state.loadingChallenge} currentChallenge={this.state.currentChallenge} />
        ) : (
          <List
            grid={{
              xs: 1,
              sm: 2,
              md: 2,
              lg: 3,
              xl: 4,
              xxl: 5,
              gutter: 20
            }}
            dataSource={this.state.challenges}
            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 have been released yet</h1>
                </div>
              )
            }}
            renderItem={item => {
              if (item.solves.length === 0) item.firstBlood = "No First Blood Yet!"
              else {
                if (this.props.disableNonCatFB) {
                  item.firstBlood = "No First blood Yet"
                  for (let i = 0; i < item.solves.length; i++) {
                    if (this.props.userCategories[item.solves[i]] !== "none") {
                      item.firstBlood = item.solves[i]
                      break
                    }
                  }
                }
                else item.firstBlood = item.solves[0]
              }

              if (item.requires && !item.requiresSolved && this.props.permissions < 2) {

                return (
                  <List.Item key={item._id}>
                    <Tooltip title={<span>Please solve "<b><u>{item.requiresName}</u></b>" to unlock this challenge.</span>}>
                      <div id={item._id}>
                        <Card
                          type="inner"
                          bordered={true}
                          className="card-design"
                        >

                          <Meta
                            description={
                              <div className="card-design-body" >
                                <LockOutlined className="disabled-style" />
                                <h1 className="card-design-name" >{item.name}</h1>
                                <h1 className="card-design-points">{item.points}</h1>
                                <h1 className="card-design-firstblood"><img alt="First Blood" src={require("./../assets/blood.svg").default} /> {item.firstBlood}</h1>
                                {this.state.loadingChallenge && this.state.currentChallenge === item._id && (
                                  <div style={{ width: "100%", height: "100%", backgroundColor: "red", zIndex: 1 }}>
                                    <LoadingOutlined style={{ color: "#177ddc", fontSize: "500%", position: "absolute", zIndex: 1, left: "40%", top: "30%" }} />
                                  </div>
                                )}
                                {item.visibility === false && (
                                  <h1 style={{ color: "#d9d9d9" }}>Hidden Challenge <EyeInvisibleOutlined /></h1>
                                )}
                              </div>


                            }
                          />
                        </Card> {/*Pass entire datasource as prop*/}
                      </div>
                    </Tooltip>
                  </List.Item>
                )

              }
              else if (!item.solved) {
                return (
                  <List.Item key={item._id}>
                    <div id={item._id} onClick={() => { this.loadChallengeDetails(item._id, item.solved, item.firstBlood) }}>
                      <Card
                        hoverable
                        type="inner"
                        bordered={true}
                        className="card-design hover"
                      >
                        <Meta
                          description={
                            <div className="card-design-body">
                              <h1 className="card-design-name">{item.name}</h1>
                              <h1 className="card-design-points">{item.points}</h1>
                              <h1 className="card-design-firstblood"><img alt="First Blood" src={require("./../assets/blood.svg").default} /> {item.firstBlood}</h1>
                              {this.state.loadingChallenge && this.state.currentChallenge === item._id && (
                                <div style={{ width: "100%", height: "100%", backgroundColor: "red", zIndex: 1 }}>
                                  <LoadingOutlined style={{ color: "#177ddc", fontSize: "500%", position: "absolute", zIndex: 1, left: "40%", top: "30%" }} />
                                </div>
                              )}
                              {item.visibility === false && (
                                <h1 style={{ color: "#d9d9d9" }}>Hidden Challenge <EyeInvisibleOutlined /></h1>
                              )}
                            </div>


                          }
                        />
                      </Card> {/*Pass entire datasource as prop*/}
                    </div>
                  </List.Item>
                )
              }
              else {
                return (
                  <List.Item key={item._id}>
                    <div id={item._id} onClick={() => { this.loadChallengeDetails(item._id, item.solved) }}>
                      <Card
                        hoverable
                        type="inner"
                        bordered={true}
                        className="card-design solved hover"
                      >
                        <Meta
                          description={
                            <div className="card-design-body">
                              <CheckOutlined className="correct-style" />
                              <h1 className="card-design-name">{item.name}</h1>
                              <h1 className="card-design-points">{item.points}</h1>
                              <h1 className="card-design-firstblood"><img alt="First Blood" src={require("./../assets/blood.svg").default} /> {item.firstBlood}</h1>
                              {this.state.loadingChallenge && this.state.currentChallenge === item._id && (
                                <div style={{ width: "100%", height: "100%", backgroundColor: "red", zIndex: 1 }}>
                                  <LoadingOutlined style={{ color: "#177ddc", fontSize: "500%", position: "absolute", zIndex: 1, left: "40%", top: "30%" }} />
                                </div>
                              )}
                              {item.visibility === false && (
                                <h1 style={{ color: "#d9d9d9" }}>Hidden Challenge <EyeInvisibleOutlined /></h1>
                              )}
                            </div>


                          }
                        />
                      </Card> {/*Pass entire datasource as prop*/}
                    </div>
                  </List.Item>
                )
              }
            }
            }
          />)}
      </Layout>

    );
  }
Example #10
Source File: challengesTagSortList.js    From ctf_platform with MIT License 4 votes vote down vote up
render() {
    return (
      <Collapse bordered={false} defaultActiveKey={Object.keys(this.props.tag)}>
        {

          this.props.selectedTags.map((category) => {
            const key = category
            const value = this.props.tag[category]
            return (
              <Panel header={<span style={{ color: "#177ddc", fontSize: "120%", textTransform: "capitalize", textAlign: "center", fontWeight: 700 }}>{key} - <span style={{ color: "#d89614" }}>{"(" + String(value.length) + ")"}</span> </span>} key={key}>
                <List
                  grid={{
                    xs: 1,
                    sm: 2,
                    md: 2,
                    lg: 3,
                    xl: 4,
                    xxl: 5,
                    gutter: 20
                  }}
                  dataSource={value}
                  key={key + "cat"}
                  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%" }}>Oops, no challenges have been created.</h1>
                      </div>
                    )
                  }}
                  renderItem={item => {
                    if (!("firstBlood" in item)) {
                      item.firstBlood = "No Solves Yet!"
                    }

                    if (item.requires && !item.requiresSolved && this.props.permissions < 2) {

                      return (
                        <List.Item key={item._id}>
                          <Tooltip title={<span>Please solve "<b><u>{item.requiresName}</u></b>" to unlock this challenge.</span>}>
                          <div id={item._id}>
                            <Card
                              type="inner"
                              bordered={true}
                              className="card-design"
                            >
                              <Meta
                                description={
                                  <div className="card-design-body" >
                                    <LockOutlined className="disabled-style"/>
                                    <h1 className="card-design-name" >{item.name}</h1>
                                    <h1 className="card-design-points">{item.points}</h1>
                                    <h1 className="card-design-firstblood"><img alt="First Blood" src={require("./../assets/blood.svg").default} /> {item.firstBlood}</h1>
                                    {this.state.loadingChallenge && this.state.currentChallenge === item._id && (
                                      <div style={{ width: "100%", height: "100%", backgroundColor: "red", zIndex: 1 }}>
                                        <LoadingOutlined style={{ color: "#177ddc", fontSize: "500%", position: "absolute", zIndex: 1, left: "40%", top: "30%" }} />
                                      </div>
                                    )}
                                    {item.visibility === false && (
                                      <h1 style={{ color: "#d9d9d9" }}>Hidden Challenge <EyeInvisibleOutlined /></h1>
                                    )}
                                  </div>
      
      
                                }
                              />
                            </Card> {/*Pass entire datasource as prop*/}
                          </div>
                          </Tooltip>
                        </List.Item>
                      )
      
                    }
                    else if (item.solved === false) {
                      return (
                        <List.Item key={item._id}>
                          <div id={item._id} onClick={() => { this.props.loadChallengeDetails(item._id, item.solved); }}>
                            <Card
                              hoverable
                              type="inner"
                              bordered={true}
                              className="card-design hover"
                            >
                              <Meta
                                description={
                                  <div  className="card-design-body">
                                    <h1 className="card-design-name">{item.name}</h1>
                                    <h1 className="card-design-points">{item.points}</h1>
                                    <h1 className="card-design-firstblood"><img alt="First Blood" src={require("./../assets/blood.svg").default} /> {item.firstBlood}</h1>
                                    {this.props.loadingChallenge && this.props.currentChallenge === item._id && (
                                      <div style={{ width: "100%", height: "100%", backgroundColor: "red", zIndex: 1 }}>
                                        <LoadingOutlined style={{ color: "#177ddc", fontSize: "500%", position: "absolute", zIndex: 1, left: "40%", top: "30%" }} />
                                      </div>
                                    )}
                                    {item.visibility === false && (
                                      <h1 style={{ color: "#d9d9d9" }}>Hidden Challenge <EyeInvisibleOutlined /></h1>
                                    )}
                                  </div>


                                }
                              />
                            </Card> {/*Pass entire datasource as prop*/}
                          </div>
                        </List.Item>
                      )
                    }
                    else {
                      return (
                        <List.Item key={item._id}>
                          <div id={item._id} onClick={() => { this.props.loadChallengeDetails(item._id, item.solved);}}>
                            <Card
                              hoverable
                              type="inner"
                              bordered={true}
                              className="card-design solved hover"
                            >
                              <Meta
                                description={
                                  <div  className="card-design-body">
                                    <CheckOutlined className="correct-style"/>
                                    <h1 className="card-design-name">{item.name}</h1>
                                    <h1 className="card-design-points">{item.points}</h1>
                                    <h1 className="card-design-firstblood"><img alt="First Blood" src={require("./../assets/blood.svg").default} /> {item.firstBlood}</h1>
                                    {this.props.loadingChallenge && this.props.currentChallenge === item._id && (
                                      <div style={{ width: "100%", height: "100%", backgroundColor: "red", zIndex: 1 }}>
                                        <LoadingOutlined style={{ color: "#177ddc", fontSize: "500%", position: "absolute", zIndex: 1, left: "40%", top: "30%" }} />
                                      </div>
                                    )}
                                    {item.visibility === false && (
                                      <h1 style={{ color: "#d9d9d9" }}>Hidden Challenge <EyeInvisibleOutlined /></h1>
                                    )}
                                  </div>

                                }
                              />
                            </Card> {/*Pass entire datasource as prop*/}
                          </div>
                        </List.Item>
                      )
                    }
                  }
                  }
                />
              </Panel>
            )
          })

        }
      </Collapse>
    )

  }
Example #11
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 #12
Source File: Reg.js    From Peppermint with GNU General Public License v3.0 4 votes vote down vote up
Reg = () => {
  const history = useHistory();

  const [password, setPassword] = useState("");
  const [email, setEmail] = useState("");
  const [name, setName] = useState("");

  const PostData = async () => {
    await fetch(`/api/v1/auth/Signup`, {
      method: "post",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        name,
        email,
        password,
      }),
    })
      .then((res) => res.json())
      .then((data) => {
        if (!data.error) {
          history.push("/login");
        } else {
          console.log(data.error);
        }
      });
  };

  return (
    <div>
      <div>
        <Form
          style={{ position: "absolute" }}
          name="normal_login"
          className="login-form"
          initialValues={{
            remember: true,
          }}
        >
          <div className="logo-login">
            <Image alt="logo" src={logo} width={300} preview={false} />
          </div>
          <Form.Item
            name="username"
            rules={[
              {
                required: true,
                message: "Please input your Email!",
              },
            ]}
          >
            <Input
              style={{ width: 300 }}
              prefix={<UserOutlined className="site-form-item-icon" />}
              placeholder="Email"
              onChange={(e) => setEmail(e.target.value)}
            />
          </Form.Item>
          <Form.Item
            name="name"
            rules={[
              {
                required: true,
                message: "Please input your name!",
              },
            ]}
          >
            <Input
              style={{ width: 300 }}
              prefix={<UserOutlined className="site-form-item-icon" />}
              placeholder="Name"
              onChange={(e) => setName(e.target.value)}
            />
          </Form.Item>
          <Form.Item
            name="password"
            rules={[
              {
                required: true,
                message: "Please input your Password!",
              },
            ]}
          >
            <Input.Password
              style={{ width: 300 }}
              prefix={<LockOutlined className="site-form-item-icon" />}
              type="password"
              placeholder="Password"
              iconRender={(visible) =>
                visible ? <EyeTwoTone /> : <EyeInvisibleOutlined />
              }
              onChange={(e) => setPassword(e.target.value)}
            />
          </Form.Item>

          <Form.Item>
            <Button
              type="primary"
              htmlType="submit"
              className="login-form-button"
              onClick={() => {
                PostData();
                setTimeout(() => history.push("/"), 4000);
              }}
            >
              Log in
            </Button>
          </Form.Item>
        </Form>
      </div>
    </div>
  );
}
Example #13
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 #14
Source File: [id].js    From zeroqueue with GNU General Public License v3.0 4 votes vote down vote up
export default function Queue() {
  const user = useUser({ redirectTo: '/' });

  const router = useRouter();
  const { id } = router.query;

  const [queue, setQueue] = useState(null);
  const [loadingQueue, setLoadingQueue] = useState(false);
  useEffect(() => {
    const fetchQueue = async () => {
      try {
        if (!user) return;

        setLoadingQueue(true);
        const res = await fetch(`/api/queue/${id}`);
        const { data, error } = await res.json();

        switch (res.status) {
          case 200:
            setQueue(data);
            break;
          default:
            throw new Error(error);
        }
      } catch (error) {
        message.error(error.message);
      } finally {
        setLoadingQueue(false);
      }
    };
    fetchQueue();
  }, [user]);

  const [showNewJobsForm, setShowNewJobsForm] = useState(false);
  const [jobs, setJobs] = useState(null);
  const [loadingAddJobs, setLoadingAddJobs] = useState(false);
  const onAddJob = async () => {
    try {
      if (!user) return;

      setLoadingAddJobs(true);
      const res = await fetch(`/api/queue/${id}`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: jobs,
      });
      const { error } = await res.json();

      switch (res.status) {
        case 200:
          location.reload();
          break;
        default:
          throw new Error(error);
      }
    } catch (error) {
      message.error(error.message);
    } finally {
      setLoadingAddJobs(false);
    }
  };

  const [showWorkerCodeSample, setShowWorkerCodeSample] = useState(false);
  const onDropdownClick = ({ key }) => {
    switch (key) {
      case DROPDOWN_KEYS.CODE_SAMPLE:
        return setShowWorkerCodeSample(true);
      default:
        break;
    }
  };

  const queueName = () => (queue && queue.name) || '...';

  const [redis, setRedis] = useState(null);
  const [loadingSecret, setLoadingSecret] = useState(null);
  const onShowSecret = async (checked) => {
    if (!checked) return setRedis(null);

    try {
      if (!user) return;

      setLoadingSecret(true);
      const res = await fetch(`/api/config`);
      const { data, error } = await res.json();

      switch (res.status) {
        case 200:
          setRedis(data.REDIS_URL);
          break;
        default:
          throw new Error(error);
      }
    } catch (error) {
      message.error(error.message);
    } finally {
      setLoadingSecret(false);
    }
  };

  return (
    <div>
      <Head>
        <title>Zero Queue</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>
      {user && (
        <Layout className="dashboard-layout">
          <Sidebar />
          <Layout className="dashboard-layout">
            <Header className="dashboard-header">
              <div className="dashboard-header__space" />
              <Button type="link" href="/api/auth/logout">
                Logout
              </Button>
            </Header>
            <Content className="dashboard-content">
              <Breadcrumb className="dashboard-content__breadcrumb">
                <Breadcrumb.Item>ZeroQueue</Breadcrumb.Item>
                <Breadcrumb.Item>
                  <Link href={`/dashboard`}>
                    <a>Queue</a>
                  </Link>
                </Breadcrumb.Item>
                <Breadcrumb.Item>{id}</Breadcrumb.Item>
              </Breadcrumb>
              <div className="dashboard-content__background">
                <div className="dashboard-overview-header">
                  <Title className="dashboard-overview-header__title" level={3}>
                    {queueName()}
                  </Title>
                  <Button
                    type="primary"
                    icon={<PlusOutlined />}
                    onClick={() => setShowNewJobsForm(true)}
                  >
                    New Jobs
                  </Button>
                  <Dropdown
                    overlay={
                      <Menu onClick={onDropdownClick}>
                        <Menu.Item key={DROPDOWN_KEYS.CODE_SAMPLE}>
                          <ApiOutlined /> Code sample
                        </Menu.Item>
                      </Menu>
                    }
                  >
                    <Button className="dashboard-overview-header__last-button">
                      More <DownOutlined />
                    </Button>
                  </Dropdown>
                </div>
                <Table
                  rowKey="name"
                  loading={loadingQueue}
                  columns={columns(id)}
                  dataSource={(queue && queue.status) || []}
                />
              </div>
            </Content>
            <Footer className="dashboard-footer">
              <Button
                type="link"
                href="https://github.com/thezeroqueue/zeroqueue"
                target="blank"
                icon={<GithubFilled />}
              />
            </Footer>
          </Layout>
          <Modal
            title="Add new jobs"
            visible={showNewJobsForm}
            onCancel={() => setShowNewJobsForm(false)}
            footer={null}
          >
            <Dragger {...uploadProps(setJobs)}>
              <p className="ant-upload-drag-icon">
                <InboxOutlined />
              </p>
              <p className="ant-upload-text">Click or drag JSON file to this area to upload</p>
              <p className="ant-upload-hint">See docs to learn more...</p>
            </Dragger>
            <br />
            <Button
              loading={loadingAddJobs}
              disabled={!jobs}
              type="primary"
              block
              onClick={onAddJob}
            >
              Add Jobs
            </Button>
          </Modal>
          <Modal
            title="Worker code sample"
            width="45%"
            visible={showWorkerCodeSample}
            onCancel={() => setShowWorkerCodeSample(false)}
            footer={null}
          >
            <p>Install dependencies:</p>
            <InstallDependencies />
            <div className="modal-inline-text">
              <p>Use the following template:</p>
              <p>
                <Switch
                  unCheckedChildren={<EyeInvisibleOutlined />}
                  loading={loadingSecret}
                  onChange={onShowSecret}
                />
              </p>
            </div>
            <Worker queue={queueName()} redis={redis} />
          </Modal>
        </Layout>
      )}
    </div>
  );
}
Example #15
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 #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>
  );
}