@ant-design/icons#CloseOutlined JavaScript Examples

The following examples show how to use @ant-design/icons#CloseOutlined. 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: text.jsx    From virtuoso-design-system with MIT License 6 votes vote down vote up
storiesOf('antd/switch', module).add('text', () => 
  <>
    <Switch checkedChildren="开启" unCheckedChildren="关闭" defaultChecked />
    <br />
    <Switch checkedChildren="1" unCheckedChildren="0" />
    <br />
    <Switch
      checkedChildren={<CheckOutlined />}
      unCheckedChildren={<CloseOutlined />}
      defaultChecked
    />
  </>,
  { docs: { page: () => (<><h1 id="enus">en-US</h1>
<p>With text and icon.</p></>) } });
Example #2
Source File: MosaicCloseButton.jsx    From ui with MIT License 6 votes vote down vote up
CloseButton = () => {
  const remove = (mosaicWindowActions, mosaicActions) => {
    mosaicActions.remove(mosaicWindowActions.getPath());
  };

  return (
    <MosaicWindowContext.Consumer>
      {({ mosaicWindowActions }) => (
        <MosaicContext.Consumer>
          {({ mosaicActions }) => (
            <Tooltip title='Close'>
              <Button
                type='text'
                className='bp3-button bp3-minimal'
                icon={<CloseOutlined />}
                onClick={() => remove(mosaicWindowActions, mosaicActions)}
              />
            </Tooltip>
          )}
        </MosaicContext.Consumer>
      )}
    </MosaicWindowContext.Consumer>
  );
}
Example #3
Source File: topAd.js    From ant-simple-pro with MIT License 6 votes vote down vote up
TopAd = memo(function TopAd({imageUrl,linkUrl,bg}) {

  const [visible,setVisible] = useState(true);

  const close = (event)=>{
    event.preventDefault();
    setVisible(false);
  }

  return (
    <CSSTransition in={visible} classNames="fade" timeout={200} unmountOnExit>
      <div className={style.TopAd}>
        <a href={linkUrl} style={{background:bg}}>
          <div className={style.image} style={{backgroundImage:`url(${imageUrl})`}}>
            <CloseOutlined className={style.close} onClick={e=>close(e)} />
          </div>
        </a>
      </div>
    </CSSTransition>
  )
})
Example #4
Source File: popus.js    From ant-simple-pro with MIT License 6 votes vote down vote up
Popus = memo(function Popus({ visible, close,imageUrl,linkUrl }) {
  return (
    <div className={style.popus}>
      <CSSTransition in={visible} classNames="fade" timeout={200} unmountOnExit>
        <div className={style.mask}></div>
      </CSSTransition>
      <CSSTransition in={visible} classNames="alert" timeout={200} unmountOnExit>
        <div className={style.content}>
          <div className={style.box}>
            <CloseOutlined onClick={() => close(false)} className={style.close}/>
            <a href={linkUrl}>
              <img src={imageUrl} alt="image"/>
            </a>
          </div>
        </div>
      </CSSTransition>
    </div>
  );
})
Example #5
Source File: index.jsx    From mixbox with GNU General Public License v3.0 5 votes vote down vote up
SortableContainerList = SortableContainer(props => {
    const {
        className,
        dataSource,
        activeKey,
        itemClass,
        onClose,
        onClick,
        itemWrapper,
        isSorting,
        ...others
    } = props;

    return (
        <div className={classNames('draggable-tabs-bar-root', className, {sorting: isSorting})} {...others}>
            {dataSource.map((item, index) => {
                const {key, title, closable} = item;
                const isActive = activeKey === key;
                let itemJsx = [
                    (
                        <div key="item" className="item-inner" onClick={(e) => onClick && onClick(item, e)}>
                            {title}
                        </div>
                    ),
                    (
                        closable ? (
                            <div key="close" className="close-wrapper" onClick={(e) => onClose && onClose(item, e)}>
                                <CloseOutlined/>
                            </div>
                        ) : null
                    ),
                ];

                if (itemWrapper) {
                    itemJsx = itemWrapper(itemJsx, item, 'draggable-tabs-bar-wrapper');
                } else {
                    itemJsx = <div className="draggable-tabs-bar-wrapper">{itemJsx}</div>;
                }
                return (
                    <SortableItem
                        key={key}
                        className={classNames(itemClass, {'active': isActive})}
                        index={index}
                    >
                        <div className="draggable-tabs-bar-horizontal-item-inner">{itemJsx}</div>
                    </SortableItem>
                );
            })}
        </div>
    );
})
Example #6
Source File: UserStatus.js    From react-chat-app with MIT License 5 votes vote down vote up
UserStatus = (props) => {
const { conn } = useContext(ChatEngineContext);
  const [userStatusAvailable, setUserStatusAvailable] = useState(false);
  const [editing, setEditing] = useState(false);
  const { userObject, convertedName } = useAuth();
  const [currentStatus, setCurrentStatus] = useState(props.userStatus)

  useEffect(() => {
    setUserStatusAvailable(true);
  }, [editing])

  const updateProfile = (newStatus) => {
    const myHeaders = new Headers();
    myHeaders.append("Project-ID", process.env.REACT_APP_PROJECT_ID);
    myHeaders.append("User-Name", convertedName);
    myHeaders.append("User-Secret", userObject.uid);

    const formdata = new FormData();
    formdata.append("first_name", newStatus);

    const requestOptions = {
      method: "PATCH",
      headers: myHeaders,
      body: formdata,
      redirect: "follow",
    };

    fetch("https://api.chatengine.io/users/me/", requestOptions).then(() => {
      setCurrentStatus(newStatus)
    });
  };

  return (
    <div className="chat-list-user-status">
      {editing ?
        <EditProfile
          userstatus={currentStatus}
          close={() => {
            setEditing(false)
          }}
          onSubmit={(newStatus) => {
            updateProfile(newStatus)
            setEditing(false)
          }}
        />
        :
        <>
          <div className="user-status">
            {/* Anti-spam to make demo account possible
            currentStatus ? currentStatus : "" */}
             {(conn.userName === "john%20doe") ? "sample status" : <>{currentStatus ? currentStatus : ""}</>   }  
             </div>
        </>}
      {!editing ?
        <EditOutlined onClick={() => setEditing(true)} /> :
        <CloseOutlined onClick={() => setEditing(false)} />
      }
    </div>
  )
}
Example #7
Source File: PaymentModeForm.jsx    From erp-crm with MIT License 5 votes vote down vote up
export default function PaymentModeForm({ isUpdateForm = false }) {
  return (
    <>
      <Form.Item
        label="Payment Mode Name"
        name="name"
        rules={[
          {
            required: true,
          },
        ]}
      >
        <Input />
      </Form.Item>
      <Form.Item
        label="Description"
        name="description"
        rules={[
          {
            required: true,
          },
        ]}
      >
        <Input />
      </Form.Item>

      <Form.Item
        label="Mode enabled"
        name="enabled"
        style={{
          display: 'inline-block',
          width: 'calc(50%)',
          paddingRight: '5px',
        }}
        valuePropName="checked"
        initialValue={true}
      >
        <Switch checkedChildren={<CheckOutlined />} unCheckedChildren={<CloseOutlined />} />
      </Form.Item>
      <Form.Item
        label="Is Default Mode"
        name="isDefault"
        style={{
          display: 'inline-block',
          width: 'calc(50%)',
          paddingLeft: '5px',
        }}
        valuePropName="checked"
      >
        <Switch checkedChildren={<CheckOutlined />} unCheckedChildren={<CloseOutlined />} />
      </Form.Item>
    </>
  );
}
Example #8
Source File: DeleteTeam.js    From video-journal-for-teams-fe with MIT License 5 votes vote down vote up
DeleteTeam = () => {
	const [showModal, setShowModal] = useState(false);
	const [values, setValues] = useState(null);
	const { team_id } = useParams();
	const dispatch = useDispatch();
	const history = useHistory();

	const handleOpen = () => {
		setShowModal(true);
	};

	const handleOk = () => {
		if (values) {
			const updates = { name: values };
			AxiosWithAuth()
				.put(`/v2/teams/${team_id}`, updates)
				.then((res) => {
					dispatch(fetchTeamById(team_id));
					setShowModal(!showModal);
				})
				.catch((err) => console.log(err));
		}
	};

	const handleCancel = () => {
		setShowModal(false);
	};

	const handleChange = (e) => {
		setValues(e.target.value);
	};
	function iDelete() {
		AxiosWithAuth()
			.delete(`/v2/teams/${team_id}`)
			.then((res) => {
				setShowModal(false);
				history.push("/user-dashboard");
			})
			.catch((err) => console.log(err));
	}

	return (
		<div>
			<Button
				type="primary"
				style={{
					color: "#6954EA",
					border: "hidden",
					fontSize: "1rem",
					textAlign: "left",
					borderStyle: "none",
					backgroundColor: "transparent",
					boxShadow: "none",
				}}
				onClick={handleOpen}>
				<CloseOutlined style={{ fontSize: "1.6rem" }} />
			</Button>

			<Modal
				title="Delete this team"
				visible={showModal}
				onOk={iDelete}
				onCancel={handleCancel}
				okText="Delete"
				okButtonProps={{ style: { backgroundColor: "#6954EA", color: "white", border: "none" } }}>
				<Form name="basic" initialValues={{ remember: true }}>
					<Form.Item onChange={handleChange}>Are you sure that you want to delete this team?</Form.Item>
				</Form>
			</Modal>
		</div>
	);
}
Example #9
Source File: tag.js    From ant-simple-pro with MIT License 5 votes vote down vote up
render() {
    const { location } = this.props;
    const { tagsList, isHiddleTag } = this.state;
    return (
      <>
        <CSSTransition in={!isHiddleTag} classNames="fade" timeout={100} unmountOnExit>
          <div className={style['tag-wrapper']}>
            <div className={style.slider}>
              {
                tagsList.length ? (<ul className={`${style["tags"]}`}>
                  {
                    tagsList.map((item, index) => {
                      return (
                        <li className={item.path === location.pathname ? `${style['tags-li']} ${style['selected']}` : `${style['tags-li']}`} key={index}>
                          <NavLink to={item.path} className={style['tags-li-title']} title={item.title}>
                            {item.title}
                          </NavLink>
                          {
                            this.state.tagsList.length > 1 && <CloseOutlined className={style['del']} onClick={(e) => this.closeTags(index, item.path, e)} />
                          }
                        </li>
                      )
                    })
                  }
                </ul>) : <p className={style["tags"]}>未匹配到相关的路径~</p>
              }
            </div>
            <div className={style.option}>
              <Dropdown overlay={this.menu} arrow trigger={['click']}>
                <a onClick={e => e.preventDefault()}>
                  <span className={style.title}>标签设置</span>
                  <DownOutlined />
                </a>
              </Dropdown>
            </div>
          </div>
        </CSSTransition>
      </>
    );
  }
Example #10
Source File: PaymentMode.jsx    From erp-crm with MIT License 4 votes vote down vote up
export default function PaymentMode() {
  const entity = 'paymentMode';
  const searchConfig = {
    displayLabels: ['name'],
    searchFields: 'name',
    outputValue: '_id',
  };

  const entityDisplayLabels = ['name'];

  const readColumns = [
    {
      title: 'Payment Mode',
      dataIndex: 'name',
    },
    {
      title: 'Description',
      dataIndex: 'description',
    },
    {
      title: 'Is Default',
      dataIndex: 'isDefault',
    },
    {
      title: 'enabled',
      dataIndex: 'enabled',
    },
  ];
  const dataTableColumns = [
    {
      title: 'Payment Mode',
      dataIndex: 'name',
    },
    {
      title: 'Description',
      dataIndex: 'description',
    },
    {
      title: 'Is Default',
      dataIndex: 'isDefault',
      key: 'isDefault',
      render: (text, row) => {
        return {
          props: {
            style: {
              width: '60px',
            },
          },
          children: (
            <Switch
              checked={text}
              checkedChildren={<CheckOutlined />}
              unCheckedChildren={<CloseOutlined />}
            />
          ),
        };
      },
    },
    {
      title: 'Enabled',
      dataIndex: 'enabled',
      key: 'enabled',
      render: (text, row) => {
        return {
          props: {
            style: {
              width: '60px',
            },
          },
          children: (
            <Switch
              checked={text}
              checkedChildren={<CheckOutlined />}
              unCheckedChildren={<CloseOutlined />}
            />
          ),
        };
      },
    },
  ];

  const ADD_NEW_ENTITY = 'Add new payment mode';
  const DATATABLE_TITLE = 'payment modes List';
  const ENTITY_NAME = 'payment mode';
  const CREATE_ENTITY = 'Create payment mode';
  const UPDATE_ENTITY = 'Update payment mode';
  const PANEL_TITLE = 'Currency Panel';

  const config = {
    entity,
    PANEL_TITLE,
    ENTITY_NAME,
    CREATE_ENTITY,
    ADD_NEW_ENTITY,
    UPDATE_ENTITY,
    DATATABLE_TITLE,
    readColumns,
    dataTableColumns,
    searchConfig,
    entityDisplayLabels,
  };
  return (
    <CrudModule
      createForm={<PaymentModeForm />}
      updateForm={<PaymentModeForm isUpdateForm={true} />}
      config={config}
    />
  );
}
Example #11
Source File: AddProduct.js    From react-admin-portal with MIT License 4 votes vote down vote up
function AddProduct() {
  const [form] = Form.useForm();

  const handleSave = values => {
    console.log('onFinish', values);
    // call save API
  };

  const requiredFieldRule = [{ required: true, message: 'Required Field' }];

  const ownerArray = [
    {
      id: 1,
      value: 'John Nash',
    },
    {
      id: 2,
      value: 'Leonhard Euler',
    },
    {
      id: 3,
      value: 'Alan Turing',
    },
  ];

  const categoryArray = [
    {
      id: 1,
      value: 'Clothing',
    },
    {
      id: 2,
      value: 'Jewelery',
    },
    {
      id: 3,
      value: 'Accessory',
    },
  ];

  return (
    <Card title="Add Product" loading={false}>
      <Row justify="center">
        <Col span={12}>
          <Form
            labelCol={{ span: 4 }}
            wrapperCol={{ span: 16 }}
            form={form}
            name="product-form"
            onFinish={handleSave}
          >
            <Form.Item label="Name" name="name" rules={requiredFieldRule}>
              <Input />
            </Form.Item>
            <Form.Item label="Description" name="description">
              <Input />
            </Form.Item>
            <Form.Item label="Owner" name="owner">
              <Select>
                {ownerArray.map(item => (
                  <Option key={item.id} value={item.id}>
                    {item.value}
                  </Option>
                ))}
              </Select>
            </Form.Item>
            <Form.Item label="Category" name="category">
              <Select>
                {categoryArray.map(item => (
                  <Option key={item.id} value={item.id}>
                    {item.value}
                  </Option>
                ))}
              </Select>
            </Form.Item>
            <Form.Item label="Quantity" name="qty">
              <InputNumber />
            </Form.Item>
            <Form.Item
              label="Status"
              name="active"
              valuePropName="checked"
              initialValue={false}
            >
              <Switch
                checkedChildren={<CheckOutlined />}
                unCheckedChildren={<CloseOutlined />}
              />
            </Form.Item>
            <Divider />
            <Row justify="center">
              <Button type="primary" htmlType="submit">
                Save
              </Button>
            </Row>
          </Form>
        </Col>
      </Row>
    </Card>
  );
}
Example #12
Source File: index.js    From the-eye-knows-the-garbage with MIT License 4 votes vote down vote up
SettingDrawer = function SettingDrawer(props) {
  var _props$settings = props.settings,
      propsSettings = _props$settings === void 0 ? undefined : _props$settings,
      _props$hideLoading = props.hideLoading,
      hideLoading = _props$hideLoading === void 0 ? false : _props$hideLoading,
      hideColors = props.hideColors,
      hideHintAlert = props.hideHintAlert,
      hideCopyButton = props.hideCopyButton,
      getContainer = props.getContainer,
      onSettingChange = props.onSettingChange,
      _props$prefixCls = props.prefixCls,
      prefixCls = _props$prefixCls === void 0 ? 'ant-pro' : _props$prefixCls;
  var firstRender = useRef(true);

  var _useMergeValue = useMergeValue(false, {
    value: props.collapse,
    onChange: props.onCollapseChange
  }),
      _useMergeValue2 = _slicedToArray(_useMergeValue, 2),
      show = _useMergeValue2[0],
      setShow = _useMergeValue2[1];

  var _useState = useState(getLanguage()),
      _useState2 = _slicedToArray(_useState, 2),
      language = _useState2[0],
      setLanguage = _useState2[1];

  var _useMergeValue3 = useMergeValue(function () {
    return getParamsFromUrl(propsSettings);
  }, {
    value: propsSettings,
    onChange: onSettingChange
  }),
      _useMergeValue4 = _slicedToArray(_useMergeValue3, 2),
      settingState = _useMergeValue4[0],
      setSettingState = _useMergeValue4[1];

  var preStateRef = useRef(settingState);

  var _ref3 = settingState || {},
      _ref3$navTheme = _ref3.navTheme,
      navTheme = _ref3$navTheme === void 0 ? 'dark' : _ref3$navTheme,
      _ref3$primaryColor = _ref3.primaryColor,
      primaryColor = _ref3$primaryColor === void 0 ? 'daybreak' : _ref3$primaryColor,
      _ref3$layout = _ref3.layout,
      layout = _ref3$layout === void 0 ? 'sidemenu' : _ref3$layout,
      colorWeak = _ref3.colorWeak;

  useEffect(function () {
    // 语言修改,这个是和 locale 是配置起来的
    var onLanguageChange = function onLanguageChange() {
      if (language !== getLanguage()) {
        setLanguage(getLanguage());
      }
    }; // 记住默认的选择,方便做 diff,然后保存到 url 参数中


    oldSetting = Object.assign(Object.assign({}, defaultSettings), propsSettings);
    /**
     * 如果不是浏览器 都没有必要做了
     */

    if (!isBrowser()) {
      return function () {
        return null;
      };
    }

    initState(settingState, setSettingState, props.publicPath);
    window.addEventListener('languagechange', onLanguageChange, {
      passive: true
    });
    return function () {
      return window.removeEventListener('languagechange', onLanguageChange);
    };
  }, []);
  /**
   * 修改设置
   * @param key
   * @param value
   * @param hideMessageLoading
   */

  var changeSetting = function changeSetting(key, value, hideMessageLoading) {
    var nextState = Object.assign({}, preStateRef.current);
    nextState[key] = value;

    if (key === 'navTheme') {
      updateTheme(value === 'realDark', undefined, hideMessageLoading, props.publicPath);
      nextState.primaryColor = 'daybreak';
    }

    if (key === 'primaryColor') {
      updateTheme(nextState.navTheme === 'realDark', value === 'daybreak' ? '' : value, hideMessageLoading, props.publicPath);
    }

    if (key === 'layout') {
      nextState.contentWidth = value === 'top' ? 'Fixed' : 'Fluid';
    }

    if (key === 'layout' && value !== 'mix') {
      nextState.splitMenus = false;
    }

    if (key === 'layout' && value === 'mix') {
      nextState.navTheme = 'light';
    }

    if (key === 'colorWeak' && value === true) {
      var dom = document.querySelector('body div');

      if (!dom) {
        return;
      }

      dom.dataset.prosettingdrawer = dom.style.filter;
      dom.style.filter = 'invert(80%)';
    }

    if (key === 'colorWeak' && value === false) {
      var _dom = document.querySelector('body div');

      if (!_dom) {
        return;
      }

      _dom.style.filter = _dom.dataset.prosettingdrawer || 'none';
      delete _dom.dataset.prosettingdrawer;
    }

    preStateRef.current = nextState;
    setSettingState(nextState);
  };

  var formatMessage = getFormatMessage();
  var themeList = getThemeList(settingState);
  useEffect(function () {
    /**
     * 如果不是浏览器 都没有必要做了
     */
    if (!isBrowser()) {
      return;
    }

    if (firstRender.current) {
      firstRender.current = false;
      return;
    }

    var browserHistory = createBrowserHistory();
    var params = {};

    if (window.location.search) {
      params = parse(window.location.search.replace('?', ''));
    }

    var diffParams = getDifferentSetting(Object.assign(Object.assign({}, params), settingState));

    if (Object.keys(settingState).length < 1) {
      return;
    }

    browserHistory.replace({
      search: stringify(diffParams)
    });
  }, [JSON.stringify(settingState)]);
  var baseClassName = "".concat(prefixCls, "-setting");
  return React.createElement(_Drawer, {
    visible: show,
    width: 300,
    onClose: function onClose() {
      return setShow(false);
    },
    placement: "right",
    getContainer: getContainer,
    handler: React.createElement("div", {
      className: "".concat(baseClassName, "-drawer-handle"),
      onClick: function onClick() {
        return setShow(!show);
      }
    }, show ? React.createElement(CloseOutlined, {
      style: {
        color: '#fff',
        fontSize: 20
      }
    }) : React.createElement(SettingOutlined, {
      style: {
        color: '#fff',
        fontSize: 20
      }
    })),
    style: {
      zIndex: 999
    }
  }, React.createElement("div", {
    className: "".concat(baseClassName, "-drawer-content")
  }, React.createElement(Body, {
    title: formatMessage({
      id: 'app.setting.pagestyle',
      defaultMessage: 'Page style setting'
    }),
    prefixCls: baseClassName
  }, React.createElement(BlockCheckbox, {
    prefixCls: baseClassName,
    list: themeList.themeList,
    value: navTheme,
    key: "navTheme",
    onChange: function onChange(value) {
      return changeSetting('navTheme', value, hideLoading);
    }
  })), React.createElement(Body, {
    title: formatMessage({
      id: 'app.setting.themecolor',
      defaultMessage: 'Theme color'
    }),
    prefixCls: baseClassName
  }, React.createElement(ThemeColor, {
    value: primaryColor,
    colors: hideColors ? [] : themeList.colorList[navTheme === 'realDark' ? 'dark' : 'light'],
    formatMessage: formatMessage,
    onChange: function onChange(color) {
      return changeSetting('primaryColor', color, hideLoading);
    }
  })), React.createElement(_Divider, null), React.createElement(Body, {
    prefixCls: baseClassName,
    title: formatMessage({
      id: 'app.setting.navigationmode'
    })
  }, React.createElement(BlockCheckbox, {
    prefixCls: baseClassName,
    value: layout,
    key: "layout",
    list: [{
      key: 'side',
      url: 'https://gw.alipayobjects.com/zos/antfincdn/XwFOFbLkSM/LCkqqYNmvBEbokSDscrm.svg',
      title: formatMessage({
        id: 'app.setting.sidemenu'
      })
    }, {
      key: 'top',
      url: 'https://gw.alipayobjects.com/zos/antfincdn/URETY8%24STp/KDNDBbriJhLwuqMoxcAr.svg',
      title: formatMessage({
        id: 'app.setting.topmenu'
      })
    }, {
      key: 'mix',
      url: 'https://gw.alipayobjects.com/zos/antfincdn/x8Ob%26B8cy8/LCkqqYNmvBEbokSDscrm.svg',
      title: formatMessage({
        id: 'app.setting.mixmenu'
      })
    }],
    onChange: function onChange(value) {
      return changeSetting('layout', value, hideLoading);
    }
  })), React.createElement(LayoutSetting, {
    settings: settingState,
    changeSetting: changeSetting
  }), React.createElement(_Divider, null), React.createElement(Body, {
    prefixCls: baseClassName,
    title: formatMessage({
      id: 'app.setting.regionalsettings'
    })
  }, React.createElement(RegionalSetting, {
    settings: settingState,
    changeSetting: changeSetting
  })), React.createElement(_Divider, null), React.createElement(Body, {
    prefixCls: baseClassName,
    title: formatMessage({
      id: 'app.setting.othersettings'
    })
  }, React.createElement(_List, {
    split: false,
    renderItem: renderLayoutSettingItem,
    dataSource: [{
      title: formatMessage({
        id: 'app.setting.weakmode'
      }),
      action: React.createElement(_Switch, {
        size: "small",
        checked: !!colorWeak,
        onChange: function onChange(checked) {
          return changeSetting('colorWeak', checked);
        }
      })
    }]
  })), hideHintAlert && hideCopyButton ? null : React.createElement(_Divider, null), hideHintAlert ? null : React.createElement(_Alert, {
    type: "warning",
    message: formatMessage({
      id: 'app.setting.production.hint'
    }),
    icon: React.createElement(NotificationOutlined, null),
    showIcon: true,
    style: {
      marginBottom: 16
    }
  }), hideCopyButton ? null : React.createElement(CopyToClipboard, {
    text: genCopySettingJson(settingState),
    onCopy: function onCopy() {
      return _message.success(formatMessage({
        id: 'app.setting.copyinfo'
      }));
    }
  }, React.createElement(_Button, {
    block: true
  }, React.createElement(CopyOutlined, null), " ", formatMessage({
    id: 'app.setting.copy'
  })))));
}
Example #13
Source File: tasks.js    From hashcat.launcher with MIT License 4 votes vote down vote up
render() {
		const { taskKey, task } = this.state;

		return (
			<>
				<PageHeader
					title="Tasks"
				/>
				<Content style={{ padding: '16px 24px' }}>
					<Row gutter={16} className="height-100 tree-height-100">
						<Col className="max-height-100" span={5}>
							<Tree
								showIcon
								blockNode
								treeData={this.state.data}
								onSelect={this.onSelect}
								selectedKeys={[taskKey]}
								style={{
									height: '100%',
									paddingRight: '.5rem',
									overflow: 'auto',
									background: '#0a0a0a',
									border: '1px solid #303030'
								}}
							/>
						</Col>
						<Col className="max-height-100" span={19}>
							{task ? (
								<Row gutter={[16, 14]} className="height-100" style={{ flexDirection: "column", flexWrap: "nowrap" }}>
									<Col flex="0 0 auto">
										<Row gutter={[16, 14]}>
											<Col span={24}>
												<PageHeader
													title={task.id}
													tags={
														task.stats.hasOwnProperty("status") ? (	
															HASHCAT_STATUS_BADGE_WARNING.indexOf(task.stats["status"]) > -1 ? (
																<Tag color="warning">{HASHCAT_STATUS_MESSAGES[task.stats["status"]]}</Tag>
															) : HASHCAT_STATUS_BADGE_PROCESSING.indexOf(task.stats["status"]) > -1 ? (
																<Tag color="processing">{HASHCAT_STATUS_MESSAGES[task.stats["status"]]}</Tag>
															) : HASHCAT_STATUS_BADGE_ERROR.indexOf(task.stats["status"]) > -1 ? (
																<Tag color="error">{HASHCAT_STATUS_MESSAGES[task.stats["status"]]}</Tag>
															) : HASHCAT_STATUS_BADGE_SUCCESS.indexOf(task.stats["status"]) > -1 ? (
																<Tag color="success">{HASHCAT_STATUS_MESSAGES[task.stats["status"]]}</Tag>
															) : HASHCAT_STATUS_BADGE_PINK.indexOf(task.stats["status"]) > -1 ? (
																<Tag color="pink">{HASHCAT_STATUS_MESSAGES[task.stats["status"]]}</Tag>
															) : HASHCAT_STATUS_BADGE_YELLOW.indexOf(task.stats["status"]) > -1 ? (
																<Tag color="yellow">{HASHCAT_STATUS_MESSAGES[task.stats["status"]]}</Tag>
															) : (
																<Tag color="default">{HASHCAT_STATUS_MESSAGES[task.stats["status"]]}</Tag>
															)
														) : null
													}
													style={{ padding: 0 }}
													extra={
														<Form layout="inline">
															<Form.Item
																label="Priority"
															>
																<InputNumber
																	min={-1}
																	max={999}
																	value={task.priority}
																	onChange={this.onChangePriority}
																	readOnly={this.state.isReadOnlyPriority}
																	bordered={false}
																/>
															</Form.Item>
															<Button
																icon={<ControlOutlined />}
																onClick={this.onClickArguments}
																style={{ marginRight: '1rem' }}
															>
																Arguments
															</Button>
															<Popconfirm
																placement="topRight"
																title="Are you sure you want to delete this task?"
																onConfirm={this.onClickDelete}
																okText="Yes"
																cancelText="No"
															>
																<Button
																	type="danger"
																	icon={<DeleteOutlined />}
																	loading={this.state.isLoadingDelete}
																>
																	Delete
																</Button>
															</Popconfirm>
														</Form>
													}
												/>
											</Col>
											<Col span={24}>
												{task.stats.hasOwnProperty("progress") ? (
													<Progress type="line" percent={Math.trunc((task.stats["progress"][0] / task.stats["progress"][1])*100)} />
												) : (
													<Progress type="line" percent={0} />
												)}
											</Col>
											<Col span={24}>
												<Row gutter={[12, 10]}>
													<Col>
														<Button
															type="primary"
															icon={<PlayCircleOutlined />}
															onClick={this.onClickStart}
															loading={this.state.isLoadingStart}
														>
															Start
														</Button>
													</Col>
													<Col>
														<Button
															icon={<ReloadOutlined />}
															onClick={this.onClickRefresh}
															loading={this.state.isLoadingRefresh}
														>
															Refresh
														</Button>
													</Col>
													<Col>
														<Button
															icon={<PauseOutlined />}
															onClick={this.onClickPause}
															loading={this.state.isLoadingPause}
														>
															Pause
														</Button>
													</Col>
													<Col>
														<Button
															icon={<CaretRightOutlined />}
															onClick={this.onClickResume}
															loading={this.state.isLoadingResume}
														>
															Resume
														</Button>
													</Col>
													<Col>
														<Button
															icon={<EnvironmentOutlined />}
															onClick={this.onClickCheckpoint}
															loading={this.state.isLoadingCheckpoint}
														>
															Checkpoint
														</Button>
													</Col>
													<Col>
														<Button
															icon={<StepForwardOutlined />}
															onClick={this.onClickSkip}
															loading={this.state.isLoadingSkip}
														>
															Skip
														</Button>
													</Col>
													<Col>
														<Popconfirm
															placement="topRight"
															title="Are you sure you want to quit this task?"
															onConfirm={this.onClickQuit}
															okText="Yes"
															cancelText="No"
														>
															<Button
																type="danger"
																icon={<CloseOutlined />}
																loading={this.state.isLoadingQuit}
															>
																Quit
															</Button>
														</Popconfirm>
													</Col>
												</Row>
											</Col>
										</Row>
									</Col>
									<Col flex="1 1 auto">
										<Row gutter={[16, 14]} className="height-100">
											<Col className="max-height-100" span={16}>
												<Descriptions
													column={2}
													layout="horizontal"
													bordered
												>
													{task.stats.hasOwnProperty("status") && (
														<Descriptions.Item label="Status" span={2}>
															{HASHCAT_STATUS_BADGE_WARNING.indexOf(task.stats["status"]) > -1 ? (
																<Badge status="warning" text={HASHCAT_STATUS_MESSAGES[task.stats["status"]]} />
															) : HASHCAT_STATUS_BADGE_PROCESSING.indexOf(task.stats["status"]) > -1 ? (
																<Badge status="processing" text={HASHCAT_STATUS_MESSAGES[task.stats["status"]]} />
															) : HASHCAT_STATUS_BADGE_ERROR.indexOf(task.stats["status"]) > -1 ? (
																<Badge status="error" text={HASHCAT_STATUS_MESSAGES[task.stats["status"]]} />
															) : HASHCAT_STATUS_BADGE_SUCCESS.indexOf(task.stats["status"]) > -1 ? (
																<Badge status="success" text={HASHCAT_STATUS_MESSAGES[task.stats["status"]]} />
															) : HASHCAT_STATUS_BADGE_PINK.indexOf(task.stats["status"]) > -1 ? (
																<Badge color="pink" text={HASHCAT_STATUS_MESSAGES[task.stats["status"]]} />
															) : HASHCAT_STATUS_BADGE_YELLOW.indexOf(task.stats["status"]) > -1 ? (
																<Badge color="yellow" text={HASHCAT_STATUS_MESSAGES[task.stats["status"]]} />
															) : (
																<Badge status="default" text={HASHCAT_STATUS_MESSAGES[task.stats["status"]]} />
															)}
														</Descriptions.Item>
													)}
													{task.stats.hasOwnProperty("target") && (
														<Descriptions.Item label="Target" span={2}>
															{task.stats["target"]}
														</Descriptions.Item>
													)}
													{task.stats.hasOwnProperty("progress") && (
														<Descriptions.Item label="Progress" span={2}>
															{task.stats["progress"][0] + " / " + task.stats["progress"][1] + " (" + Math.trunc((task.stats["progress"][0] / task.stats["progress"][1])*100) + "%)"}
															{task.stats.hasOwnProperty("guess") && (
																<Tooltip title={
																	<Descriptions bordered size="small" column={1} layout="horizontal">
																		{task.stats.guess.guess_base !== null ? (
																			<Descriptions.Item label="Guess Base">{task.stats.guess.guess_base} ({task.stats.guess.guess_base_offset}/{task.stats.guess.guess_base_count})</Descriptions.Item>
																		) : (
																			<Descriptions.Item label="Guess Base">-</Descriptions.Item>
																		)}
																		{task.stats.guess.guess_mod !== null ? (
																			<Descriptions.Item label="Guess Mod">{task.stats.guess.guess_mod} ({task.stats.guess.guess_mod_offset}/{task.stats.guess.guess_mod_count})</Descriptions.Item>
																		) : (
																			<Descriptions.Item label="Guess Mod">-</Descriptions.Item>
																		)}
																	</Descriptions>
																}>
																	<InfoCircleOutlined style={{ marginLeft: ".5rem" }} />
																</Tooltip>
															)}
														</Descriptions.Item>
													)}
													{task.stats.hasOwnProperty("rejected") && (
														<Descriptions.Item label="Rejected" span={1}>
															{task.stats["rejected"]}
														</Descriptions.Item>
													)}
													{task.stats.hasOwnProperty("restore_point") && (
														<Descriptions.Item label="Restore point" span={1}>
															{task.stats["restore_point"]}
														</Descriptions.Item>
													)}
													{task.stats.hasOwnProperty("recovered_hashes") && (
														<Descriptions.Item label="Recovered hashes" span={1}>
															{task.stats["recovered_hashes"][0] + " / " + task.stats["recovered_hashes"][1] + " (" + Math.trunc((task.stats["recovered_hashes"][0] / task.stats["recovered_hashes"][1])*100) + "%)"}
														</Descriptions.Item>
													)}
													{task.stats.hasOwnProperty("recovered_salts") && (
														<Descriptions.Item label="Recovered salts" span={1}>
															{task.stats["recovered_salts"][0] + " / " + task.stats["recovered_salts"][1] + " (" + Math.trunc((task.stats["recovered_salts"][0] / task.stats["recovered_salts"][1])*100) + "%)"}
														</Descriptions.Item>
													)}
													{task.stats.hasOwnProperty("devices") && (
														<Descriptions.Item label="Speed" span={2}>
															{humanizeSpeed(totalSpeed(task.stats["devices"]))}
															<Tooltip title={
																<Table
																	columns={[
																		{
																			title: 'ID',
																			dataIndex: 'id',
																			key: 'ID'
																		},
																		{
																			title: 'Speed',
																			dataIndex: 'speed',
																			key: 'Speed'
																		},
																		{
																			title: 'Temp',
																			dataIndex: 'temp',
																			key: 'Temp'
																		},
																		{
																			title: 'Util',
																			dataIndex: 'util',
																			key: 'Util'
																		}
																	]}
																	dataSource={task.stats["devices"].map(device =>
																		({
																			key: device.device_id,
																			id: device.device_id,
																			speed: humanizeSpeed(device.speed),
																			temp: device.hasOwnProperty("temp") ? device.temp + " °C": "-",
																			util: device.util + "%",
																		})
																	)}
																	size="small"
																	pagination={false}
																	style={{ overflow: 'auto' }}
																/>
															}>
																<InfoCircleOutlined style={{ marginLeft: ".5rem" }} />
															</Tooltip>
														</Descriptions.Item>
													)}
													{task.stats.hasOwnProperty("time_start") && (
														<Descriptions.Item label="Started" span={1}>
															<Tooltip title={moment.unix(task.stats["time_start"]).format("MMMM Do YYYY, HH:mm")}>
																{moment.unix(task.stats["time_start"]).fromNow()}
															</Tooltip>
														</Descriptions.Item>
													)}
													{task.stats.hasOwnProperty("estimated_stop") && (
														<Descriptions.Item label="ETA" span={1}>
															<Tooltip title={moment.unix(task.stats["estimated_stop"]).format("MMMM Do YYYY, HH:mm")}>
																{moment.unix(task.stats["estimated_stop"]).fromNow()}
															</Tooltip>
														</Descriptions.Item>
													)}
												</Descriptions>
											</Col>
											<Col className="max-height-100" span={8}>
												<div className="height-100" style={{ display: "flex", flexDirection: "column" }}>
												<span><CodeOutlined /> Terminal</span>
												<pre style={{
													flex: 'auto',
													overflow: 'auto',
													padding: '.5rem',
													margin: '0',
													border: '1px solid #303030'
												}}>
													{task.journal.map(j => j.message + "\n")}
												</pre>
												</div>
											</Col>
										</Row>
									</Col>
								</Row>
							) : (
								"No selected task."
							)}
						</Col>
					</Row>
				</Content>
			</>
		)
	}
Example #14
Source File: build_record_table.js    From art-dashboard-ui with Apache License 2.0 4 votes vote down vote up
render() {

        const table_column = [
            {
                title: 'Brew Build',
                dataIndex: "build_id",
                key: "build_id",
                render: (text, record) => (
                    <div>
                        <a href={process.env.REACT_APP_BREW_BUILD_LINK+record["build_id"]}
                           target="_blank" rel="noopener noreferrer">
                            {record["build_id"]}
                        </a>
                    </div>
                )
            },
            {
                title: "Build Status",
                dataIndex: "fault_code",
                key: "fault_code",
                render: (text, record) =>{
                    if(record["fault_code"] === "0"){
                        return(
                            <div>
                                <CheckOutlined style = {{color:  "#52c41a"}}/>
                            </div>
                        )
                    }

                    else{
                        return(
                            <div>
                                <Tooltip title={"Fault Code is " + record["fault_code"]}>
                                    <CloseOutlined style = {{color: "#f55d42"}}/>
                                </Tooltip>
                            </div>
                        )
                    }
                }
            },
            {
                title: "Brew Task",
                dataIndex: "task_id",
                key: "task_id",
                render: (data, record) => {
                    return(
                        <div>
                            <a href={process.env.REACT_APP_BREW_TASK_LINK+record["task_id"]}
                               target="_blank" rel="noopener noreferrer">{record["task_id"]}</a>
                        </div>
                    )

                }
            },
            {
              title: "Jenkins Build URL",
              dataIndex: "jenkins_build_url",
              key: "jenkins_build_url",
              render: (data, record) =>{
                  return (
                      <div>
                          <p><a href={record["jenkins_build_url"]}>{<LinkOutlined/>}</a></p>
                      </div>
                  )
              }
            },
            {
                title: "DistGit Name",
                dataIndex: "label_name",
                key: "label_name",
                filters: this.state.label_name_filter,
                onFilter: (value, record) => record.label_name === value,
                width: "20%",
                sorter: (a, b) => a.label_name.length - b.label_name.length

            },
            {
                title: "OpenShift Group",
                dataIndex: "group",
                key: "group",
                filters: this.state.group_filter,
                onFilter: (value, record) => record.group === value,
                width: "20%",
                sorter: (a, b) => parseFloat(a.group.split("-")[1]) - parseFloat(b.group.split("-")[1])

            },
            {
                title: "Build Time",
                dataIndex: "iso_time",
                key: "iso_time",
                render: (data, record) => {
                    let date = new Date(record["iso_time"])
                    return (
                        <p>{date.getFullYear()+'-' + this.render_single_digit_to_double_datetime((date.getMonth()+1)) + '-'+this.render_single_digit_to_double_datetime(date.getDate()) + ' ' + this.render_single_digit_to_double_datetime(date.getHours()) + ':' + this.render_single_digit_to_double_datetime(date.getMinutes()) + ":" + this.render_single_digit_to_double_datetime(date.getSeconds())}</p>
                    )
                }
            }
        ]

        return (
            <div>
                <Table dataSource={this.state.data} columns={table_column} style={{padding: "30px"}} loading={this.state.loading}/>
            </div>
        );
    }
Example #15
Source File: build_history_table.js    From art-dashboard-ui with Apache License 2.0 4 votes vote down vote up
render() {

        const columns = [

            {
                title: 'Brew Build',
                dataIndex: "build_id",
                key: "build_id",
                render: (text, record) => (

                    <div>
                        <a href={process.env.REACT_APP_BREW_BUILD_LINK+record["build_id"]}
                           target="_blank" rel="noopener noreferrer">
                            {record["build_id"] !== null && record["build_id"]}
                            {record["build_id"] === null && "Not Available"}
                        </a>
                    </div>
                )
            },
            {
                title:()=>{
                    return (
                        <Row>
                            <Col span={24} className="left">
                                Build Status
                            </Col>
                            <Col span={24}>
                                <Run_status_filter search_callback={this.props.simple_filter_callback}/>
                            </Col>
                        </Row>
                    )
                },
                dataIndex: "fault_code",
                key: "fault_code",
                align: "center",
                render: (text, record) =>{
                    if(record["fault_code"] === 0){
                        return(
                            <div>
                                <a href={process.env.REACT_APP_BREW_TASK_LINK+record["task_id"]}
                                   target="_blank" rel="noopener noreferrer"><CheckOutlined style = {{color:  "#52c41a"}}/></a>
                            </div>
                        )
                    }

                    else{
                        return(
                            <div>
                                <a href={process.env.REACT_APP_BREW_TASK_LINK+record["task_id"]}
                                   target="_blank" rel="noopener noreferrer">
                                    <Tooltip title={"Fault Code is " + record["fault_code"]}>
                                        <CloseOutlined style = {{color: "#f55d42"}}/>
                                    </Tooltip>
                                </a>
                            </div>
                        )
                    }
                }
            },
            {
                title:()=>{
                    return (
                        <Row>
                            <Col span={24} className="left">
                                Package
                            </Col>
                            <Col span={24}>
                                <Autocomplete_filter placeholder={"Package Name"} type={"nvr"} search_callback={this.props.simple_filter_callback}/>
                            </Col>
                        </Row>
                    )
                },
                dataIndex: "dg_name",
                key: "dg_name"
            },
            {
                title: "Version",
                key: "label_version",
                dataIndex: "label_version"
            },
            {
                title: "CGIT Link",
                dataIndex: "build_0_source",
                key: "build_0_source",
                render: (data, record) => {

                    const http_link = "http://pkgs.devel.redhat.com/cgit/" + record["dg_namespace"] + "/" + record["dg_name"] + "/tree/?id=" + record["dg_commit"];
                    return (
                        <a href={http_link} target="_blank" rel="noopener noreferrer">{"#"+record["dg_commit"]}</a>
                    )

                }
            },
            {
                title: "Source Commit",
                align: "center",
                dataIndex: "build_commit_url_github",
                key: "build_commit_url_github",
                render: (data, record) => {
                    if(record["build_commit_url_github"] !== null)
                        return(
                            <a href={record["build_commit_url_github"]} target="_blank" rel="noopener noreferrer">{"#" + record["build_commit_url_github"].slice(-8)}</a>
                        )
                    else
                        return(
                            <p>Not Available</p>
                        )
                }
            },
            {
                title: ()=>{
                    return (
                        <Row>
                            <Col span={24} className="left">
                                Build Time ISO
                            </Col>
                            <Col span={24}>
                                <Datepicker_filter placeholder={"Build Date"} search_callback={this.props.simple_filter_callback}/>
                            </Col>
                        </Row>
                    )
                },
                dataIndex: "iso_time",
                key: "iso_time",
                render: (data, record) => {
                    //let date = new Date(record["iso_time"])
                    return (
                        <p>{record["iso_time"].split("T")[0] + " " + record["iso_time"].split("T")[1].split(".")[0]}</p>
                        // <p>{date.getFullYear()+'-' + this.render_single_digit_to_double_datetime((date.getMonth()+1)) + '-'+this.render_single_digit_to_double_datetime(date.getDate()) + ' ' + this.render_single_digit_to_double_datetime(date.getHours()) + ':' + this.render_single_digit_to_double_datetime(date.getMinutes()) + ":" + this.render_single_digit_to_double_datetime(date.getSeconds())}</p>
                    )
                }
            },
            {
                title: 'More Details',
                align: "center",
                render: (text, record) => (
                    <div>
                        <a>
                            <ExpandOutlined  onClick={() => this.showBuildDescriptionModal(record)}/>
                        </a>
                        <Modal
                            title= {"Build Details"}
                            visible= {this.state["visible_modal_"+record["build_id"]]}
                            onOk={() => this.handleOkBuildDescriptionModal(record)}
                            onCancel={() => this.handleOkBuildDescriptionModal(record)}
                            footer={null}
                        >

                            <p><a href={record["jenkins_build_url"]}>{"Jenkins Build Url"}</a></p>
                            <p>{"Jenkins Build Number: " + record["jenkins_build_number"]}</p>
                            <p>{"Jenkins Job Name: " + record["jenkins_job_name"]}</p>
                            <p>{"Build Name: " + record["build_name"]}</p>
                            <p>{"Build Version: " + record["build_version"]}</p>

                        </Modal>
                    </div>
                )
            }

        ]

        return (
            <div>
                <Table dataSource={this.state.data} columns={columns}/>
            </div>
        );
    }
Example #16
Source File: ChatList.js    From react-chat-app with MIT License 4 votes vote down vote up
ChatList = props => {
    const didMountRef = useRef(false)
    const [hasMoreChats, setHasMoreChats] = useState(true)
    const [editingProfile, setEditingProfile] = useState(false)
    const [logoSource, setLogoSource] = useState(chatLogo);
    const [theme, setTheme] = useState("dark");
    const { conn, chats, setChats, setActiveChat, activeChat } = useContext(ChatEngineContext)
    const chat = chats && chats[activeChat];

    const name = props.chatAppState.userName
    const secret = props.chatAppState.userSecret

    useEffect(() => {

        const themeValue = localStorage.getItem("theme");

        if (themeValue === "light") {
            document.querySelector(".app").classList.add("light");
            setLogoSource(chatLogoWhite)

        } else if (themeValue === "dark") {
            document.querySelector(".app").classList.remove("light");
            setLogoSource(chatLogo)

        } else {
            localStorage.setItem("theme", theme);
        }
    }, [theme]);

    function deleteActiveChat(chatID) {
        var myHeaders = new Headers();

        let otherPerson = chat.people.find(
            (person) => person.person.username !== name
        )
            ? chat.people.find((person) => person.person.username !== name)
            : chat.people.find((person) => person.person.username === name);

        myHeaders.append("Project-ID", process.env.REACT_APP_PROJECT_ID);
        myHeaders.append("User-Name", name);
        myHeaders.append("User-Secret", secret);

        var raw = `{"username": "${name}"}`;
        var raw2 = `{"username": "${otherPerson.person.username}"}`;

        var firstUser = {
            method: "DELETE",
            headers: myHeaders,
            body: raw,
            redirect: "follow",
        };
        var secondUser = {
            method: "DELETE",
            headers: myHeaders,
            body: raw2,
            redirect: "follow",
        };

        fetch(`https://api.chatengine.io/chats/${chatID}/people/`, firstUser)
            .then((response) => response.text())
            .then((result) => console.log(result))
            .catch((error) => console.log("error", error));

        fetch(`https://api.chatengine.io/chats/${chatID}/people/`, secondUser)
            .then((response) => response.text())
            .then((result) => console.log(result))
            .catch((error) => console.log("error", error));
    }
    function getDateTime(date, offset) {
        if (!date) return ''

        date = date.replace(' ', 'T')
        offset = offset ? offset : 0

        const year = date.substr(0, 4)
        const month = date.substr(5, 2)
        const day = date.substr(8, 2)
        const hour = date.substr(11, 2)
        const minute = date.substr(14, 2)
        const second = date.substr(17, 2)

        var d = new Date(`${year}-${month}-${day}T${hour}:${minute}:${second}`)
        d.setHours(d.getHours() + offset)
        return d
    }

    function renderChats(chats) {
        return chats.map((chat, index) => {
            if (!chat) {
                return <div key={`chat_${index}`} />

            } else if (props.chatAppState.renderChatCard) {
                return <div key={`chat_${index}`}>{props.chatAppState.renderChatCard(chat, index)}</div>

            } else {
                return (""
                )
            }
        })
    }

    function sortChats(chats) {
        return chats.sort((a, b) => {
            const aDate = a.last_message && a.last_message.created ? getDateTime(a.last_message.created, props.chatAppState.offset) : getDateTime(a.created, props.chatAppState.offset)
            const bDate = b.last_message && b.last_message.created ? getDateTime(b.last_message.created, props.chatAppState.offset) : getDateTime(b.created, props.chatAppState.offset)
            return new Date(bDate) - new Date(aDate);
        })
    }

    function onGetChats(chatList) {
        const oldChats = chats !== null ? chats : {}
        const newChats = _.mapKeys({ ...chatList }, 'id')
        const allChats = { ...oldChats, ...newChats }
        setChats(allChats);
        (count && count > Object.keys(allChats).length) && setHasMoreChats(false);
    }

    useEffect(() => {
        if (!didMountRef.current && name && secret) {
            didMountRef.current = true

            getLatestChats(
                props.chatAppState,
                count,
                (chats) => {
                    onGetChats(chats)
                    const chatList = sortChats(chats)
                    chatList.length > 0 && setActiveChat(chatList[0].id)
                }
            )
        }
    })

    useEffect(() => {
        if (!activeChat) {
            activeConversation()
        }
    }, [chats, activeChat])

    const chatList = sortChats(
        chats ?
            Object.values(chats) :
            [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}]
    )
    function activeConversation() {
        if (chatList[0]) {
            setActiveChat(chatList[0].id)
        }
    }
    if (chats == null) return <div />;
    return (
        <div className="chat-left-wing">
            <div className="chat-bar">
                <div className="chat-bar-logo">
                    {(window.screen.availWidth > 700) ?
                        <img src={logoSource} alt="" /> :
                        <div className="mobile-toggler">
                            <CloseOutlined
                                onClick={() => {
                                    document.querySelector(".chat-container").children[0].children[1].children[0].style.display = "none";
                                    document.querySelector(".chat-container").children[0].children[1].children[1].style.display = "block";
                                }}
                            />
                        </div>
                    }
                </div>
                <div className="chat-bar-options">
                    <div className="chat-bar-option">
                        <UserOutlined
                            onClick={
                                () => {
                                    if (editingProfile && (window.screen.availWidth > 1150)) {
                                        setEditingProfile(!editingProfile)
                                        document.querySelector(".ce-chats-container").style.height = "530px"
                                    }
                                    else if (!editingProfile && (window.screen.availWidth > 1150)) {
                                        setEditingProfile(!editingProfile)
                                        document.querySelector(".ce-chats-container").style.height = "425px"
                                    }
                                    else if (editingProfile && (window.screen.availWidth <= 1150)) {
                                        setEditingProfile(!editingProfile)
                                        document.querySelector(".ce-chats-container").style.height = "calc(100vh - 76px)"
                                    } else {
                                        setEditingProfile(!editingProfile)
                                        document.querySelector(".ce-chats-container").style.height = "calc(100vh - 166px)"
                                    }

                                }
                            }
                        />
                    </div>
                    <div className="chat-bar-option">
                        <BgColorsOutlined onClick={() => {
                            const themeValue = localStorage.getItem("theme");
                            if (themeValue === "dark") {
                                setTheme("light")
                                localStorage.setItem("theme", "light");
                                document.querySelector(".app").classList.add("light");
                                setLogoSource(chatLogoWhite)
                            } else if (themeValue === "light") {
                                setTheme("dark")
                                localStorage.setItem("theme", "dark");
                                document.querySelector(".app").classList.remove("light");
                                setLogoSource(chatLogo)
                            }
                        }} />
                    </div>
                    <div className="chat-bar-option">
                    
                    <a href="https://github.com/matt765/react-chat-app" target="_blank"><GithubOutlined /></a>
                    </div>
                    <div className="chat-bar-option">
                        <DeleteOutlined onClick={() => {
                            if (name === "john%20doe") {
                                alert("Deleting conversations is disabled on sample account, sorry!");
                                return
                            }

                            if (window.confirm("Press OK if you want to delete active chat. Conversation with this person will be lost")) {
                                deleteActiveChat(activeChat)
                            }

                        }} />
                    </div>
                    <div className="chat-bar-option"> <LogoutOutlined onClick={() => {
                        if (window.confirm("Press OK if you want to logout")) {
                            fb.auth.signOut().then(console.log("logged out"))
                            document.querySelector(".app").classList.remove("light");
                        }
                    }} /></div>
                </div>
            </div>
            <div className="chat-left-wing-list">
                {editingProfile ?
                    <ChatProfile
                        chat={chat}
                        conn={conn}
                        name={props.chatAppState.userName}
                        secret={props.chatAppState.userSecret}
                    /> : ""}
                <div style={styles.chatListContainer} className='ce-chat-list'>
                    {
                        props.chatAppState.renderNewChatForm ?
                            props.chatAppState.renderNewChatForm(conn) :
                            <NewChatForm onClose={props.chatAppState.onClose ? () => props.chatAppState.onClose() : undefined} />
                    }
                    <div style={styles.chatsContainer} className='ce-chats-container'>
                        {renderChats(chatList)}
                        {
                            hasMoreChats && chatList.length > 0 &&
                            <div>

                                <div style={{ height: '8px' }} />
                            </div>
                        }
                    </div>
                </div>
            </div>
        </div>
    )
}
Example #17
Source File: AiSample.js    From network-rc with Apache License 2.0 4 votes vote down vote up
render() {
    const {
      clear,
      download,
      upload,
      props: { onFinish, cameraEnabled },
    } = this;
    const { sampleList } = this.state;
    return (
      <div className="ai-sample">
        <Form layout="inline" className="ai-sample-form">
          {Object.keys(aiAction).map((key) => (
            <Form.Item>
              <Button
                icon={aiAction[key].icon}
                onClick={() => this.add({ action: key })}
                disabled={!cameraEnabled}
              >{aiAction[key].name}</Button>
            </Form.Item>
          ))}
          <Form.Item>
            <Upload
              customRequest={upload}
              accept="application/json"
              showUploadList={false}
            >
              <Button icon={<ImportOutlined />}>导入</Button>
            </Upload>
          </Form.Item>
          <Form.Item>
            <Button
              icon={<ExportOutlined />}
              disabled={!sampleList.length}
              onClick={download}
            >
              导出
            </Button>
          </Form.Item>
          <Form.Item>
            <Button type="danger" disabled={!sampleList.length} onClick={clear}>
              清除
            </Button>
          </Form.Item>
          <Form.Item>
            <Link to="../train">
              <Button
                type="primary"
                disabled={sampleList.length < 10}
                onClick={() => {
                  onFinish(sampleList);
                }}
              >
                下一步
              </Button>
            </Link>
          </Form.Item>
        </Form>
        <List
          size="small"
          className="ai-example-list"
          grid={{ gutter: 16, column: 4 }}
          itemLayout="vertical"
          pagination={{
            pageSize: 12,
          }}
          dataSource={sampleList}
          renderItem={({ img, action }, index) => (
            <List.Item>
              <Card
                size="small"
                title={aiAction[action].icon}
                actions={[
                  <Button
                    size="small"
                    icon={<CloseOutlined />}
                    type="danger"
                    onClick={() => this.remove(index)}
                  />,
                ]}
              >
                <img
                  style={{ width: "100%" }}
                  src={img}
                  alt="example"
                  onLoad={function ({ target }) {
                    target.height = target.width * 0.75;
                  }}
                />
              </Card>
            </List.Item>
          )}
        />
      </div>
    );
  }
Example #18
Source File: Currency.jsx    From erp-crm with MIT License 4 votes vote down vote up
export default function Currency() {
  const entity = 'currency';
  const searchConfig = {
    displayLabels: ['name'],
    searchFields: 'name',
    outputValue: '_id',
  };

  const entityDisplayLabels = ['name'];

  const readColumns = [
    {
      title: 'Currency Name',
      dataIndex: 'name',
    },
    {
      title: 'Symbol',
      dataIndex: 'symbol',
    },
    {
      title: 'Decimal Sep',
      dataIndex: 'decimalSeparator',
    },
    {
      title: 'Thousand Sep',
      dataIndex: 'thousandSeparator',
    },
    {
      title: 'Default',
      dataIndex: 'isDefault',
    },
  ];
  const dataTableColumns = [
    {
      title: 'Currency Name',
      dataIndex: 'name',
    },
    {
      title: 'Symbol',
      dataIndex: 'symbol',
    },
    {
      title: 'Decimal Sep',
      dataIndex: 'decimalSeparator',
    },
    {
      title: 'Thousand Sep',
      dataIndex: 'thousandSeparator',
    },
    {
      title: 'Default',
      dataIndex: 'isDefault',
      key: 'isDefault',
      render: (text, row) => {
        return {
          props: {
            style: {
              width: '60px',
            },
          },
          children: (
            <Switch
              checked={text}
              checkedChildren={<CheckOutlined />}
              unCheckedChildren={<CloseOutlined />}
            />
          ),
        };
      },
    },
  ];

  const ADD_NEW_ENTITY = 'Add new currency';
  const DATATABLE_TITLE = 'currencys List';
  const ENTITY_NAME = 'currency';
  const CREATE_ENTITY = 'Create currency';
  const UPDATE_ENTITY = 'Update currency';
  const PANEL_TITLE = 'Currency Panel';

  const config = {
    entity,
    PANEL_TITLE,
    ENTITY_NAME,
    CREATE_ENTITY,
    ADD_NEW_ENTITY,
    UPDATE_ENTITY,
    DATATABLE_TITLE,
    readColumns,
    dataTableColumns,
    searchConfig,
    entityDisplayLabels,
  };
  return (
    <CrudModule
      createForm={<CurrencyForm />}
      updateForm={<CurrencyForm isUpdateForm={true} />}
      config={config}
    />
  );
}
Example #19
Source File: CurrencyForm.jsx    From erp-crm with MIT License 4 votes vote down vote up
export default function CurrencyForm({ isUpdateForm = false }) {
  return (
    <>
      <Form.Item
        label="Currency Name"
        name="name"
        rules={[
          {
            required: true,
            message: 'Please input your currency name!',
          },
        ]}
      >
        <Input />
      </Form.Item>
      <Form.Item
        label="Symbol"
        name="symbol"
        rules={[
          {
            required: true,
            message: 'Please input your surname!',
          },
        ]}
        style={{
          display: 'inline-block',
          width: 'calc(50%)',
          paddingRight: '5px',
        }}
      >
        <Input />
      </Form.Item>
      <Form.Item
        label="Decimal Separator"
        name="decimalSeparator"
        rules={[
          {
            required: true,
          },
        ]}
        style={{
          display: 'inline-block',
          width: 'calc(50%)',
          paddingLeft: '5px',
        }}
      >
        <Input />
      </Form.Item>

      <Form.Item
        label="Thousand Separator"
        name="thousandSeparator"
        rules={[
          {
            required: true,
          },
        ]}
        style={{
          display: 'inline-block',
          width: 'calc(50%)',
          paddingRight: '5px',
        }}
      >
        <Input />
      </Form.Item>
      <Form.Item
        label="Is Default Currency"
        name="isDefault"
        rules={[
          {
            required: true,
          },
        ]}
        style={{
          display: 'inline-block',
          width: 'calc(50%)',
          paddingLeft: '5px',
        }}
        valuePropName="checked"
      >
        <Switch checkedChildren={<CheckOutlined />} unCheckedChildren={<CloseOutlined />} />
      </Form.Item>
    </>
  );
}
Example #20
Source File: index.jsx    From ui with MIT License 4 votes vote down vote up
DataProcessingPage = ({ experimentId, experimentData }) => {
  const dispatch = useDispatch();
  const { navigateTo } = useAppRouter();

  const pipelineStatus = useSelector(getBackendStatus(experimentId))?.status?.pipeline;

  const processingConfig = useSelector((state) => state.experimentSettings.processing);
  const sampleKeys = useSelector((state) => state.experimentSettings.info.sampleIds);
  const samples = useSelector((state) => state.samples);

  const pipelineStatusKey = pipelineStatus?.status;
  const pipelineRunning = pipelineStatusKey === 'RUNNING';

  // Pipeline is not loaded (either running or in an errored state)
  const pipelineErrors = ['FAILED', 'TIMED_OUT', 'ABORTED'];
  const pipelineHadErrors = pipelineErrors.includes(pipelineStatusKey);
  const pipelineNotFinished = pipelineRunning || pipelineHadErrors;

  const completedSteps = pipelineStatus?.completedSteps || [];

  const changedQCFilters = useSelector(
    (state) => state.experimentSettings.processing.meta.changedQCFilters,
  );

  const changesOutstanding = Boolean(changedQCFilters.size);

  const [stepIdx, setStepIdx] = useState(0);
  const [runQCModalVisible, setRunQCModalVisible] = useState(false);
  const [inputsList, setInputsList] = useState([]);

  useEffect(() => {
    // If processingConfig is not loaded then reload
    if (Object.keys(processingConfig).length <= 1) {
      dispatch(loadProcessingSettings(experimentId));
    }

    dispatch(loadSamples(experimentId));
    dispatch(loadCellSets(experimentId));
  }, []);

  // Checks if the step is in the 'completed steps' list we get from the pipeline status
  const isStepComplete = (stepName) => {
    if (stepName === undefined) {
      return true;
    }

    const lowerCaseStepName = stepName.toLowerCase();

    const stepAppearances = _.filter(
      completedSteps,
      (stepPipelineName) => stepPipelineName.toLowerCase().includes(lowerCaseStepName),
    );

    return stepAppearances.length > 0;
  };

  const onConfigChange = useCallback((key) => {
    dispatch(addChangedQCFilter(key));
  });

  const prefixSampleName = (name) => {
    // eslint-disable-next-line no-param-reassign
    if (!name.match(/$sample/ig)) name = `Sample ${name}`;
    return name;
  };

  useEffect(() => {
    if (sampleKeys && sampleKeys.length > 0 && Object.keys(samples).filter((key) => key !== 'meta').length > 0) {
      const list = sampleKeys?.map((sampleId) => ({
        key: sampleId,
        headerName: prefixSampleName(samples[sampleId].name),
        params: { key: sampleId },
      }));
      setInputsList(list);
    }
  }, [samples, sampleKeys]);

  const steps = [
    {

      key: 'classifier',
      name: getUserFriendlyQCStepName('classifier'),
      description: 'The Classifier filter is based on the ‘emptyDrops’ method which distinguishes between droplets containing cells and ambient RNA. Droplets are filtered based on the False Discovery Rate (FDR) value - the red line on the density plot. In the knee plot, the ‘mixed’ population shown in grey contains some cells that are filtered out and some that remain and can be filtered further in the next filter.',
      multiSample: true,
      render: (key) => (
        <SingleComponentMultipleDataContainer
          defaultActiveKey={sampleKeys}
          inputsList={inputsList}
          baseComponentRenderer={(sample) => (
            <Classifier
              id='classifier'
              experimentId={experimentId}
              filtering
              key={key}
              sampleId={sample.key}
              sampleIds={sampleKeys}
              onConfigChange={() => onConfigChange(key)}
              stepDisabled={!processingConfig[key]?.enabled}
            />
          )}
        />
      ),
    },
    {
      key: 'cellSizeDistribution',
      name: getUserFriendlyQCStepName('cellSizeDistribution'),
      description: 'The number of unique molecular identifiers (#UMIs) per cell distinguishes real cells (high #UMIs per cell) from empty droplets (low #UMIs per cell). This filter is used to detect empty droplets and fine-tunes the Classifier filter. In some datasets this filter might be used instead of the Classifier filter.',
      multiSample: true,
      render: (key) => (
        <SingleComponentMultipleDataContainer
          defaultActiveKey={sampleKeys}
          inputsList={inputsList}
          baseComponentRenderer={(sample) => (
            <CellSizeDistribution
              experimentId={experimentId}
              filtering
              key={key}
              sampleId={sample.key}
              sampleIds={sampleKeys}
              onConfigChange={() => onConfigChange(key)}
              stepDisabled={!processingConfig[key].enabled}
            />
          )}
        />
      ),
    },
    {
      key: 'mitochondrialContent',
      name: getUserFriendlyQCStepName('mitochondrialContent'),
      description: 'A high percentage of mitochondrial reads is an indicator of cell death. UMIs mapped to mitochondrial genes are calculated as a percentage of total UMIs. The percentage of mitochondrial reads depends on the cell type. The typical cut-off range is 10-50%, with the default cut-off set to 3 median absolute deviations above the median.',
      multiSample: true,
      render: (key) => (
        <SingleComponentMultipleDataContainer
          defaultActiveKey={sampleKeys}
          inputsList={inputsList}
          baseComponentRenderer={(sample) => (
            <MitochondrialContent
              experimentId={experimentId}
              filtering
              key={key}
              sampleId={sample.key}
              sampleIds={sampleKeys}
              onConfigChange={() => onConfigChange(key)}
              stepDisabled={!processingConfig[key].enabled}
            />
          )}
        />
      ),
    },
    {
      key: 'numGenesVsNumUmis',
      name: getUserFriendlyQCStepName('numGenesVsNumUmis'),
      description: 'The number of expressed genes per cell and number of UMIs per cell is expected to have a linear relationship. This filter is used to exclude outliers (e.g. many UMIs originating from only a few genes).',
      multiSample: true,
      render: (key) => (
        <SingleComponentMultipleDataContainer
          defaultActiveKey={sampleKeys}
          inputsList={inputsList}
          baseComponentRenderer={(sample) => (
            <GenesVsUMIs
              experimentId={experimentId}
              filtering
              key={key}
              sampleId={sample.key}
              sampleIds={sampleKeys}
              onConfigChange={() => onConfigChange(key)}
              stepDisabled={!processingConfig[key].enabled}
            />
          )}
        />
      ),
    },
    {
      key: 'doubletScores',
      name: getUserFriendlyQCStepName('doubletScores'),
      description:
        <span>
          Droplets may contain more than one cell.
          In such cases, it is not possible to distinguish which reads came from which cell.
          Such “cells” cause problems in the downstream analysis as they appear as an intermediate type.
          “Cells” with a high probability of being a doublet should be excluded.
          The probability of being a doublet is calculated using ‘scDblFinder’.
          For each sample, the default threshold tries to minimize both the deviation in the
          expected number of doublets and the error of a trained classifier. For more details see
          {' '}
          <a href='https://bioconductor.org/packages/devel/bioc/vignettes/scDblFinder/inst/doc/scDblFinder.html#thresholding' rel='noreferrer' target='_blank'>scDblFinder thresholding</a>
          .
        </span>,
      multiSample: true,
      render: (key) => (
        <SingleComponentMultipleDataContainer
          defaultActiveKey={sampleKeys}
          inputsList={inputsList}
          baseComponentRenderer={(sample) => (
            <DoubletScores
              experimentId={experimentId}
              filtering
              key={key}
              sampleId={sample.key}
              sampleIds={sampleKeys}
              onConfigChange={() => onConfigChange(key)}
              stepDisabled={!processingConfig[key].enabled}
            />
          )}
        />
      ),
    },
    {
      key: 'dataIntegration',
      name: getUserFriendlyQCStepName('dataIntegration'),
      multiSample: false,
      render: (key, expId) => (
        <DataIntegration
          experimentId={expId}
          key={key}
          onConfigChange={() => onConfigChange(key)}
          disableDataIntegration={sampleKeys && sampleKeys.length === 1}
        />
      ),
    },
    {
      key: 'configureEmbedding',
      name: getUserFriendlyQCStepName('configureEmbedding'),
      description: 'Cells and clusters are visualized in a 2-dimensional embedding. The UMAP or t-SNE embedding plot can be selected and customized. The clustering method (e.g. Louvain) and resolution are set here.',
      multiSample: false,
      render: (key, expId) => (
        <ConfigureEmbedding
          experimentId={expId}
          key={key}
          onConfigChange={() => onConfigChange(key)}
        />
      ),
    },
  ];

  const currentStep = steps[stepIdx];

  // check that the order and identities of the QC steps above match
  // the canonical representation
  console.assert(_.isEqual(qcSteps, steps.map((s) => s.key)));

  const changeStepId = (newStepIdx) => {
    setStepIdx(newStepIdx);
  };

  const renderRunButton = (runMessage, useSmall = true) => (
    <Tooltip title='Run data processing with the changed settings'>
      <Button
        data-testid='runFilterButton'
        type='primary'
        onClick={() => setRunQCModalVisible(true)}
        style={{ minWidth: '80px' }}
        size={useSmall ? 'small' : 'medium'}
      >
        {runMessage}
      </Button>
    </Tooltip>
  );

  const renderRunOrDiscardButtons = () => {
    if (pipelineHadErrors) {
      return renderRunButton('Run Data Processing', false);
    } if (changesOutstanding) {
      return (
        <Alert
          message={<>Your new settings are not yet applied</>}
          type='info'
          showIcon
          style={{
            paddingTop: '3px', paddingBottom: '3px', paddingLeft: '10px', paddingRight: '10px',
          }}
          action={(
            <Space size='small'>
              {renderRunButton('Run', true)}
              <Tooltip title='Discard your changes since the last run'>
                <Button
                  id='discardChangesButton'
                  data-testid='discardChangesButton'
                  type='primary'
                  onClick={() => { dispatch(discardChangedQCFilters()); }}
                  style={{ width: '80px' }}
                  size='small'
                >
                  Discard
                </Button>
              </Tooltip>
            </Space>
          )}
        />
      );
    }
  };

  // Called when the pipeline is triggered to be run by the user.
  const onPipelineRun = () => {
    setRunQCModalVisible(false);
    dispatch(runQC(experimentId));
  };

  const renderTitle = () => {
    const stepEnabled = processingConfig[currentStep.key]?.enabled;
    const prefiltered = processingConfig[currentStep.key]?.prefiltered || false;

    return (
      <>
        <Row justify='space-between'>
          <Col style={{ paddingBottom: '8px' }}>
            {/* Should be just wide enough that no ellipsis appears */}
            <Row>
              <Col style={{ paddingBottom: '8px', paddingRight: '8px' }}>
                <Space size='small'>
                  <Select
                    value={stepIdx}
                    onChange={(idx) => {
                      changeStepId(idx);
                    }}
                    style={{ fontWeight: 'bold', width: 290 }}
                    placeholder='Jump to a step...'
                  >
                    {
                      steps.map(
                        ({ name, key }, i) => {
                          const disabledByPipeline = (pipelineNotFinished && !isStepComplete(key));
                          const text = `${i + 1}. ${name}`;

                          return (
                            <Option
                              value={i}
                              key={key}
                              disabled={
                                disabledByPipeline
                              }
                            >
                              {processingConfig[key]?.enabled === false ? (
                                <>
                                  {/* disabled */}
                                  <Text
                                    type='secondary'
                                  >
                                    <CloseOutlined />
                                  </Text>
                                  <span
                                    style={{ marginLeft: '0.25rem', textDecoration: 'line-through' }}
                                  >
                                    {text}
                                  </span>
                                </>
                              ) : !disabledByPipeline ? (
                                <>
                                  {/* finished */}
                                  <Text
                                    type='success'
                                  >
                                    <CheckOutlined />
                                  </Text>
                                  <span
                                    style={{ marginLeft: '0.25rem' }}
                                  >
                                    {text}
                                  </span>
                                </>
                              ) : pipelineRunning && !isStepComplete(key) ? (
                                <>
                                  {/* incomplete */}
                                  <Text
                                    type='warning'
                                    strong
                                  >
                                    <EllipsisOutlined />
                                  </Text>
                                  <span style={{ marginLeft: '0.25rem' }}>{text}</span>
                                </>
                              ) : pipelineNotFinished
                                && !pipelineRunning
                                && !isStepComplete(key) ? (
                                <>
                                  <Text
                                    type='danger'
                                    strong
                                  >
                                    <WarningOutlined />
                                  </Text>
                                  <span style={{ marginLeft: '0.25rem' }}>{text}</span>
                                </>
                              ) : <></>}
                            </Option>
                          );
                        },
                      )
                    }
                  </Select>
                  {currentStep.description && (
                    <Tooltip title={currentStep.description}>
                      <Button icon={<InfoCircleOutlined />} />
                    </Tooltip>
                  )}
                  {currentStep.multiSample && (
                    <Tooltip title={`${!stepEnabled ? 'Enable this filter' : 'Disable this filter'}`}>
                      <Button
                        disabled={prefiltered}
                        data-testid='enableFilterButton'
                        onClick={async () => {
                          await dispatch(saveProcessingSettings(experimentId, currentStep.key));
                          if (!processingConfig.meta.saveSettingsError) {
                            dispatch(setQCStepEnabled(
                              currentStep.key, !stepEnabled,
                            ));
                          }
                        }}
                      >
                        {
                          stepEnabled ? 'Disable' : 'Enable'
                        }
                      </Button>
                    </Tooltip>
                  )}
                </Space>
              </Col>
              <Col>
                {renderRunOrDiscardButtons()}
              </Col>
            </Row>
          </Col>
          <Col>
            <Row align='middle' justify='space-between'>
              <Col>
                <StatusIndicator
                  experimentId={experimentId}
                  allSteps={steps}
                  currentStep={stepIdx}
                  completedSteps={completedSteps}
                />
                <Space size='small'>
                  <Tooltip title='Previous'>
                    <Button
                      data-testid='pipelinePrevStep'
                      disabled={stepIdx === 0}
                      icon={<LeftOutlined />}
                      onClick={() => changeStepId(Math.max(stepIdx - 1, 0))}
                      size='small'
                    />
                  </Tooltip>
                  {stepIdx !== steps.length - 1 ? (
                    <Tooltip title='Next'>
                      <Button
                        data-testid='pipelineNextStep'
                        onClick={() => {
                          const newStepIdx = Math.min(stepIdx + 1, steps.length - 1);
                          changeStepId(newStepIdx);
                        }}
                        disabled={steps[stepIdx + 1] !== undefined
                          && pipelineNotFinished
                          && !isStepComplete(steps[stepIdx + 1].key)}
                        icon={<RightOutlined />}
                        size='small'
                      />
                    </Tooltip>
                  )
                    : (
                      <Tooltip title='Finish QC'>
                        <Button
                          type='primary'
                          disabled={steps[stepIdx + 1]
                            && pipelineNotFinished
                            && !isStepComplete(steps[stepIdx + 1].key)}
                          icon={<CheckOutlined />}
                          size='small'
                          onClick={() => navigateTo(modules.DATA_EXPLORATION, { experimentId })}
                        />
                      </Tooltip>
                    )}
                </Space>
              </Col>
            </Row>
          </Col>
        </Row>
      </>
    );
  };

  const renderContent = () => {
    const { render, key } = currentStep;

    if (pipelineRunning && !isStepComplete(key)) {
      return <div><PipelineRedirectToDataProcessing pipelineStatus='runningStep' /></div>;
    }

    if (pipelineNotFinished && !isStepComplete(key)) {
      return (
        <div>
          <div style={{ display: 'flex', justifyContent: 'center' }}>
            <PlatformError
              description={'We don\'t have anything for this step.'}
              reason='The last run ended before this step could be finished.'
              onClick={() => { onPipelineRun(); }}
            />
          </div>
        </div>
      );
    }

    if (samples.meta.loading
      || processingConfig.meta.loading
      || Object.keys(processingConfig).length <= 1
    ) {
      return (
        <div className='preloadContextSkeleton' style={{ padding: '16px 0px' }}>
          <Skeleton.Input style={{ width: '100%', height: 400 }} active />
        </div>
      );
    }

    if (samples.meta.error || processingConfig.meta.loadingSettingsError) {
      return (
        <PlatformError
          error={samples.meta.error.toString()
            || processingConfig.meta.loadingSettingsError.toString()}
          onClick={() => { dispatch(loadSamples(experimentId)); }}
        />
      );
    }

    return (
      <Space direction='vertical' style={{ width: '100%' }}>
        {
          'enabled' in processingConfig[key] && !processingConfig[key].enabled ? (
            <Alert
              message={processingConfig[key]?.prefiltered
                ? 'This filter is disabled because the one of the sample(s) is pre-filtered. Click \'Next\' to continue processing your data.'
                : 'This filter is disabled. You can still modify and save changes, but the filter will not be applied to your data.'}
              type='info'
              showIcon
            />
          ) : <></>
        }

        {render(key, experimentId)}
      </Space>
    );
  };

  return (
    <>
      <Header
        experimentId={experimentId}
        experimentData={experimentData}
        title='Data Processing'
      />
      <Space direction='vertical' style={{ width: '100%', padding: '0 10px' }}>

        {runQCModalVisible && (
          <Modal
            title='Run data processing with the changed settings'
            visible
            onCancel={() => setRunQCModalVisible(false)}
            onOk={() => onPipelineRun()}
            okText='Start'
          >
            <p>
              This might take several minutes.
              Your navigation within Cellenics will be restricted during this time.
              Do you want to start?
            </p>
          </Modal>
        )}
        <Card
          title={renderTitle()}
        >
          {renderContent()}
        </Card>
      </Space>
    </>
  );
}
Example #21
Source File: GeneReorderTool.jsx    From ui with MIT License 4 votes vote down vote up
GeneReorderTool = (props) => {
  const { plotUuid } = (props);

  const dispatch = useDispatch();

  const config = useSelector((state) => state.componentConfig[plotUuid]?.config);

  const experimentId = useSelector((state) => state.componentConfig[plotUuid]?.experimentId);

  const loadedMarkerGenes = useSelector(
    (state) => state.genes.expression.views[plotUuid]?.data,
  );

  // Tree from antd requires format [{key: , title: }], made from gene names from loadedMarkerGenes and config
  const composeGeneTree = (treeGenes) => {
    if (!treeGenes) {
      return [];
    }

    const data = [];
    Object.entries(treeGenes).forEach(([key, value]) => {
      data.push({ key: `${key}`, title: `${value}` });
    });
    return data;
  };

  const [geneTreeData, setGeneTreeData] = useState(composeGeneTree(loadedMarkerGenes));

  useEffect(() => {
    setGeneTreeData(composeGeneTree(config?.selectedGenes));
  }, [config?.selectedGenes]);

  // geneKey is equivalent to it's index, moves a gene from pos geneKey to newPosition
  // dispatches an action to update selectedGenes in config
  const onGeneReorder = (geneKey, newPosition) => {
    const oldOrder = geneTreeData.map((treeNode) => treeNode.title);

    const newOrder = arrayMoveImmutable(Object.values(oldOrder), geneKey, newPosition);

    dispatch(updatePlotConfig(plotUuid, { selectedGenes: newOrder }));
  };

  const onNodeDelete = (geneKey) => {
    const genes = geneTreeData.map((treeNode) => treeNode.title);
    genes.splice(geneKey, 1);

    dispatch(loadGeneExpression(experimentId, genes, plotUuid));
  };

  const renderTitles = (data) => {
    // replace every title (gene name) in tree data with a modified title (name + button)
    const toRender = data.map((treeNode) => {
      // modified needs to be a copy of a given node
      const modified = { ...treeNode };
      modified.title = (
        <Space>
          {treeNode.title}
          <Button
            type='text'
            onClick={() => {
              onNodeDelete(treeNode.key);
            }}
          >
            <CloseOutlined />
          </Button>
        </Space>
      );
      return modified;
    });
    return toRender;
  };

  const [renderedTreeData, setRenderedTreeData] = useState([]);

  useEffect(() => {
    setRenderedTreeData(renderTitles(geneTreeData));
  }, [geneTreeData]);

  return (
    <HierarchicalTreeGenes
      treeData={renderedTreeData}
      onGeneReorder={onGeneReorder}
      onNodeDelete={onNodeDelete}
    />
  );
}
Example #22
Source File: AdvancedFilteringModal.jsx    From ui with MIT License 4 votes vote down vote up
AdvancedFilteringModal = (props) => {
  const { onCancel, onLaunch } = props;

  const [availablePresetFilters, setAvailablePresetFilters] = useState(presetFilters);
  const [availableCriteriaOptions, setAvailableCriteriaOptions] = useState(criteriaOptions);

  const [form] = Form.useForm();
  const advancedFilters = useSelector((state) => (
    state.differentialExpression.comparison.advancedFilters)) || [];
  const {
    loading: diffExprLoading,
    data: diffExprData,
  } = useSelector((state) => state.differentialExpression.properties);

  const availableColumns = Object.keys(diffExprData[0] || {});

  useEffect(() => {
    if (!availableColumns.length) return;

    const filteredPresetFilters = presetFilters
      .filter((filter) => availableColumns.includes(filter.columnName));

    const filteredCriteriaOptions = criteriaOptions
      .filter((option) => availableColumns.includes(option.value));

    setAvailablePresetFilters(filteredPresetFilters);
    setAvailableCriteriaOptions(filteredCriteriaOptions);
  }, [availableColumns.length]);

  const renderPresetFilters = (add) => (
    <Menu
      onClick={(e) => {
        const selectedFilter = availablePresetFilters.find((filter) => filter.label === e.key);
        add(selectedFilter);
      }}
    >
      {availablePresetFilters.map((filter) => (
        <Menu.Item key={filter.label}>
          {filter.label}
        </Menu.Item>
      ))}
    </Menu>
  );

  const applyFilters = (filters) => {
    const filtersDataToRun = filters.map(({ columnName, comparison, value }) => ({
      type: 'numeric', columnName, comparison, value,
    }));

    onLaunch(filtersDataToRun);
  };

  return (
    <Modal
      visible
      title='Advanced filters'
      onCancel={onCancel}
      footer={null}
      width='530px'
    >
      <Form form={form} onFinish={({ filterForm }) => applyFilters(filterForm)}>
        <Form.List
          name='filterForm'
          initialValue={advancedFilters}

        >
          {(fields, { add, remove }) => (
            <>
              <Row>
                {fields.map((field, index) => {
                  const { columnName } = form.getFieldValue('filterForm')[index];
                  return (
                    <Space key={field.key} align='baseline'>
                      <Form.Item
                        name={[field.name, 'columnName']}
                        rules={[{ required: true, message: 'Please select a property' }]}
                      >
                        <Select
                          placeholder='Select property'
                          style={{ width: 140 }}
                          onChange={() => form.setFieldsValue({})}
                          options={availableCriteriaOptions}
                        />
                      </Form.Item>

                      <Form.Item
                        name={[field.name, 'comparison']}
                        rules={[{ required: true, message: 'Please select a comparison' }]}
                      >
                        <Select
                          placeholder='Select comparison'
                          options={comparisonOptions}
                          style={{ width: 150 }}
                        />
                      </Form.Item>

                      <Form.Item
                        name={[field.name, 'value']}
                        rules={[{ required: true, message: 'Please input a value' }]}
                      >
                        <InputNumber
                          style={{ width: 140 }}
                          step={columnName ? valueRestrictions[columnName][1] / 100 : 1}
                          min={columnName ? valueRestrictions[columnName][0] : 0}
                          max={columnName ? valueRestrictions[columnName][1] : 0}
                          placeholder='Insert value'
                        />
                      </Form.Item>

                      <CloseOutlined onClick={() => remove(field.name)} style={{ margin: '8px' }} />
                    </Space>
                  );
                })}
              </Row>
              <Row>
                <Space direction='horizontal'>
                  <Button onClick={add} icon={<PlusOutlined />}>
                    Add custom filter
                  </Button>
                  <Dropdown overlay={renderPresetFilters(add)}>
                    <Button icon={<PlusOutlined />}>
                      Add preset filter
                    </Button>
                  </Dropdown>
                </Space>
              </Row>
              <Divider style={{ marginBottom: '10px' }} />
              <div align='end' style={{ marginTop: '0px', width: '100%' }}>
                <Form.Item style={{ marginBottom: '-10px', marginTop: '0px' }}>
                  <Button type='primary' htmlType='submit' disabled={diffExprLoading}>
                    Apply filters
                  </Button>
                </Form.Item>
              </div>
            </>
          )}
        </Form.List>
      </Form>
    </Modal>
  );
}
Example #23
Source File: EditableField.jsx    From ui with MIT License 4 votes vote down vote up
EditableField = (props) => {
  const {
    value,
    deleteEnabled,
    showEdit,
    onAfterSubmit,
    onAfterCancel,
    renderBold,
    defaultEditing,
    validationFunc,
    onEditing,
  } = props;

  const [editing, setEditing] = useState(defaultEditing);
  const [editedValue, setEditedValue] = useState(value);
  const [isValid, setIsValid] = useState(true);
  const saveButton = useRef(null);
  const editButton = useRef(null);

  useEffect(() => {
    setEditedValue(value);
  }, [value]);

  useEffect(() => {
    if (!onEditing) return;

    onEditing(editing);
  }, [editing]);

  const deleteEditableField = (e) => {
    e.stopPropagation();
    props.onDelete(e, editedValue);
  };

  const onKeyDown = (e) => {
    if (e.key === 'Enter') {
      onSubmit(e);
    }

    if (e.key === 'Escape') {
      onCancel(e);
    }
  };

  const onChange = (e) => {
    const { value: newValue } = e.target;

    if (validationFunc) {
      const valid = value === newValue || validationFunc(newValue);

      // Validation func may not return false on invalid
      setIsValid(valid === true);
    }

    setEditedValue(newValue);
  };

  const onSubmit = (e) => {
    e.stopPropagation();

    if (!isValid) return null;

    onAfterSubmit(editedValue);
    toggleEditing(e);
  };

  const onCancel = (e) => {
    e.stopPropagation();
    if (!isValid) setIsValid(true);
    setEditedValue(value);
    toggleEditing(e);
    onAfterCancel();
  };

  const toggleEditing = (e) => {
    e.stopPropagation();
    setEditing(!editing);
  };

  const renderEditState = () => {
    if (editing) {
      return (
        <>
          <Input
            data-testid='editableFieldInput'
            autoFocus
            onChange={onChange}
            size='small'
            defaultValue={editedValue}
            onKeyDown={onKeyDown}
          />

          <Tooltip placement='top' title='Save' mouseLeaveDelay={0} ref={saveButton}>
            <Button
              aria-label='Save'
              size='small'
              shape='circle'
              icon={<CheckOutlined />}
              onClick={(e) => {
                saveButton.current.onMouseLeave();
                onSubmit(e);
              }}
            />
          </Tooltip>

          <Tooltip placement='top' title='Cancel' mouseLeaveDelay={0}>
            <Button aria-label='Cancel' size='small' shape='circle' icon={<CloseOutlined />} onClick={onCancel} />
          </Tooltip>

        </>
      );
    }

    return (
      <>
        {renderBold ? <strong>{value}</strong> : <span>{value}</span>}
        {
          showEdit
            ? (
              <Tooltip placement='top' title='Edit' mouseLeaveDelay={0} ref={editButton}>
                <Button
                  aria-label='Edit'
                  size='small'
                  shape='circle'
                  icon={<EditOutlined />}
                  onClick={(e) => {
                    editButton.current.onMouseLeave();
                    toggleEditing(e);
                  }}
                />
              </Tooltip>
            ) : <></>
        }
      </>
    );
  };

  return (
    <>
      <Space direction='vertical'>
        <Space align='start'>
          {renderEditState()}
          {
            deleteEnabled
              ? (
                <Tooltip placement='top' title='Delete' mouseLeaveDelay={0}>
                  <Button
                    data-test-class={integrationTestConstants.classes.EDITABLE_FIELD_DELETE_BUTTON}
                    aria-label='Delete'
                    size='small'
                    shape='circle'
                    icon={<DeleteOutlined />}
                    onClick={deleteEditableField}
                  />
                </Tooltip>
              ) : <></>
          }
        </Space>
        {!isValid ? (
          <Text type='danger' style={{ fontSize: 12, fontWeight: 600 }}>
            {validationFunc(editedValue) === false ? 'Invalid input' : validationFunc(editedValue)}
          </Text>
        ) : <></>}
      </Space>
    </>
  );
}
Example #24
Source File: ParticipantsList.js    From react-portal with MIT License 4 votes vote down vote up
ParticipantsList = props => {
	const [participants, setParticipants] = useState([]);
	const [allParticipants, setAllParticipants] = useState([]);
	const [viewDrawer, setViewDrawer] = useState(false);
	const [participantId, setParticipantId] = useState(null);
	const [eId, setEID] = useState(null);
	const [refresh, toggleRefresh] = useState(false);
	const [isLoading, setIsLoading] = useState(false);
	const [branch, setBranch] = useState(null);
	const [year, setYear] = useState(null);
	const [query, setQuery] = useState(null);
	const [page, setPage] = useState(1);
	const [count, setCount] = useState(0);
	const userData = getRole();

	// const [allEvents, setAllEvents] = useState([]);

	useEffect(() => {
		(async () => {
			setIsLoading(true);
			try {
				const { data } = await getParticipantsService();
				setAllParticipants(data.participants);
				setParticipants(data.participants);
				setCount(data.totalParticipants);
				setIsLoading(false);
			} catch (err) {
				_notification("warning", "Error", err.message);
			}
		})();
	}, [refresh]);

	const handleEventChange = async id => {
		setIsLoading(true);
		try {
			if (id === "All") {
				setParticipants(allParticipants);
				setCount(data.totalParticipants);
				setBranch(null);
				setYear(null);
				setEID(null);
			} else {
				setEID(id);
				let params = { eid: id };
				if (branch) params = { ...params, branch };
				if (year) params = { ...params, year };
				const { data } = await getParticipantsService(params);
				setParticipants(data.participants);
				setCount(data.totalParticipants);
			}
			setIsLoading(false);
		} catch (err) {
			_notification("warning", "Error", err.message);
		}
	};

	const handleQuery = async val => {
		setQuery(val);
		setIsLoading(true);
		try {
			let params = { eid: eId, query: val, branch, year };
			const { data } = await getParticipantsService(params);
			setParticipants(data.participants);
			setCount(data.totalParticipants);
			setIsLoading(false);
		} catch (err) {
			_notification("warning", "Error", err.message);
		}
	};

	const handleBranchChange = async val => {
		setIsLoading(true);
		setBranch(val);
		try {
			let params = { branch: val };
			if (year) params = { ...params, year };
			if (query) params = { ...params, query };
			if (eId) params = { ...params, eid: eId };
			const { data } = await getParticipantsService(params);
			setParticipants(data.participants);
			setCount(data.totalParticipants);
			setIsLoading(false);
		} catch (error) {
			_notification("warning", "Error", error.message);
		}
	};

	const handleYearChange = async val => {
		setIsLoading(true);
		setYear(val);
		try {
			let params = { year: val };
			if (branch) params = { ...params, branch };
			if (query) params = { ...params, query };
			if (eId) params = { ...params, eid: eId };
			const { data } = await getParticipantsService(params);
			setParticipants(data.participants);
			setCount(data.totalParticipants);
			setIsLoading(false);
		} catch (error) {
			_notification("warning", "Error", error.message);
		}
	};

	const handleParticipantRevoke = async id => {
		try {
			const res = await revokeParticipantServices(id);
			if (res.message === "success") {
				toggleRefresh(!refresh);
				_notification(
					"success",
					"Success",
					"Toggle Participant Revoke"
				);
			} else {
				_notification("warning", "Error", res.message);
			}
		} catch (err) {
			_notification("error", "Error", err.message);
		}
	};

	const handleParticipantDelete = async id => {
		try {
			const res = await deleteParticipantServices(id);
			if (res.message === "success") {
				toggleRefresh(!refresh);
				_notification("success", "Success", "Participant deleted");
			} else {
				_notification("warning", "Error", res.message);
			}
		} catch (error) {
			_notification("error", "Error", error.message);
		}
	};

	const columns = [
		{
			title: "#",
			dataIndex: "key",
			key: "key",
			render: (value, item, index) => (page - 1) * 10 + index + 1
		},
		{
			title: "Name",
			dataIndex: "name",
			key: "name",
			sorter: (a, b) => a.name[0].localeCompare(b.name[0]),
			render: text => (
				<Link
					to="#"
					onClick={() => {
						setViewDrawer(true);
						setParticipantId(text[1]);
					}}
				>
					{text[0]}
				</Link>
			)
		},
		{
			title: "Email",
			dataIndex: "email",
			key: "email"
		},
		{
			title: "Branch",
			dataIndex: "branch",
			key: "branch",
			sorter: (a, b) => a.branch.localeCompare(b.branch)
		},
		{
			title: "Year",
			dataIndex: "year",
			key: "year",
			sorter: (a, b) => a.year - b.year
		},
		{
			title: "Phone",
			dataIndex: "phone",
			key: "phone"
		},
		{
			title: "Action",
			dataIndex: "action",
			key: "action",
			role: "lead",
			render: action => (
				<span>
					<Popconfirm
						title="Do you want to toggle user revoke?"
						onConfirm={() => handleParticipantRevoke(action[1])}
						okText="Yes"
						cancelText="No"
					>
						{action[0] ? (
							<CloseOutlined style={{ color: "#F4B400" }} />
						) : (
							<CheckOutlined style={{ color: "green" }} />
						)}
					</Popconfirm>
					{userData && userData.role === "lead" ? (
						<>
							<Divider type="vertical" />
							<Popconfirm
								title="Are you sure delete this user?"
								onConfirm={() =>
									handleParticipantDelete(action[1])
								}
								okText="Yes"
								cancelText="No"
							>
								<DeleteOutlined style={{ color: "#DB4437" }} />
							</Popconfirm>
						</>
					) : null}
				</span>
			)
		}
	].filter(
		item =>
			(userData.role !== "lead" && item.role !== "lead") ||
			userData.role === "lead"
	);

	const data = participants
		? participants.map((event, id) => {
				const { _id, name, email, branch, phone, year, isRevoked } =
					event;
				return {
					index: ++id,
					key: _id,
					name: [name, _id],
					email,
					branch,
					year,
					phone,
					action: [isRevoked, _id]
				};
		  })
		: null;

	return (
		<>
			<PageTitle title="Participants" bgColor="#4285F4" />

			<div className="table-wrapper-card">
				<ParticipantsOptions
					onEventChange={handleEventChange}
					onQuery={handleQuery}
					onBranchChange={handleBranchChange}
					onYearChange={handleYearChange}
					refresh={refresh}
					toggleRefresh={toggleRefresh}
				/>

				<Card
					title={`Total Count: ${count}`}
					style={{ padding: 0, width: "100%", overflowX: "auto" }}
				>
					<Table
						loading={isLoading}
						columns={columns}
						dataSource={data}
						onChange={(d, e) => console.log(d, e)}
						pagination={{
							onChange(current) {
								setPage(current);
							},
							defaultPageSize: 500
						}}
					/>
				</Card>
			</div>

			<Drawer
				title="Participant Information"
				placement="right"
				closable={true}
				width="40%"
				destroyOnClose={true}
				onClose={() => setViewDrawer(false)}
				visible={viewDrawer}
			>
				<ParticipantDetail participantId={participantId} />
			</Drawer>
		</>
	);
}
Example #25
Source File: index.js    From certificate-generator with MIT License 4 votes vote down vote up
function ListEvents(props) {

const { Meta } = Card;
	/*Recebe o organizador e o JSON de organizadores*/
	const { organizador, users } = props

	/*Trabalham para trocar a tela da lista de eventos com o formulário de edição/criação*/
	const [ toEditFormEvent, setToEditFormEvent] = useState(false);
	const [ toCreateFormEvent, setToCreateFormEvent] = useState(false);
	const [ toProfile, setProfile] = useState(false);
	const [ toList, setList] = useState(false);
	const [ toSeeEvents, setSeeEvents] = useState(false);

	/*Esta variavel guarda o evento referente quando o botão check participantes for acionado*/
	const [ eventChecked, setEventChecked] = useState('');

	/*JSON dos eventos*/
	const [ eventos, setEventos ] = useState(eventosData)

	/*Vaiável para saber qual evento foi editado*/
	const [ eventEdited, setEventEdited ] = useState('')
	  
	//Dados do evento:
	//Serão usados para editar no formulário
	const [ company, setCompany] = useState('');
	const [ course, setCourse ] = useState('');
	const [ startDate, setStartDate ] = useState('');
	const [ finishDate, setFinishDate ] = useState('');
	const [ workload, setWorkload ] = useState('');

	/*---------- Assinatura Digital ----------*/
	const [ imageURL, setImageURL ] = useState(null)

	const sigCanvas = useRef({})

	const clear = () => sigCanvas.current.clear();

	const save = () => {
		setImageURL(sigCanvas.current.getTrimmedCanvas().toDataURL("image/png"))
	}

	/*--------- Formulário para criar evento ---------*/
	const { RangePicker } = DatePicker;

	/*Constroi o layout do input de datas*/
	const formItemLayout = {
	  labelCol: {
	    xs: {
	      span: 24,
	    },
	    sm: {
	      span: 8,
	    },
	  },
	  wrapperCol: {
	    xs: {
	      span: 24,
	    },
	    sm: {
	      span: 16,
	    },
	  },
	};

	/*Constroi o layout do input de name/curso*/
	const formInputLayout = {
	  labelCol: {
	    span: 4,
	  },
	  wrapperCol: {
	    span: 8,
	  },
	};

	/*Define as regras para que a data seja aceita */
	const rangeConfig = {
	  rules: [
	    {
	      type: 'array',
	      required: true,
	      message: 'Este campo é obrigatório!',
	    },
	  ],
	};

	/*Define as regras para que os inputs de texto sejam aceitos */
	const rangeInputs = {
		rules: [
	    	{
	        	required: true,
	            message: 'Por favor, preencha esse campo',
	        },
		],
	};

	/*Função acionada quando um evento for ser criado*/
	/*Ela não é chamada caso os campos não forem preeenchidos*/
	const onFinish = fieldsValue => {

	    /*Dados do calendário*/
	    const rangeValue = fieldsValue['range-picker'];

	    if(imageURL === null) {
	    	message.error('Por favor, escreva sua assinatura digital')
	    } else {
	    	setEventos([
				...eventos, {
				user: organizador,
				company: fieldsValue.company, 
				course: fieldsValue.course,
				startDate: rangeValue[0].format('DD-MM-YYYY'), 
				finishDate: rangeValue[1].format('DD-MM-YYYY'), 
				workload: fieldsValue.workload, 
				logo: "https://miro.medium.com/max/478/1*jriufqYKgJTW4DKrBizU5w.png", 
				digitalSignature: imageURL
			}
		])

		message.success('Evento criado com sucesso')

		/*Retira o componente do formulário de eventos e volta para a lista*/
	    setToCreateFormEvent(false)
	    }  
	};

	/*Buscando os eventos do organizador*/

	let eventsOfOrganizer = []

	eventos.map(evento => {
		if(evento.user === organizador) {
			eventsOfOrganizer.push(evento)
		}
	})

	/*Verifica se existem eventos cadastrados para mostrar elemento do Antd 'No Data'*/
	let noEvents = true

	/* ------------- Deletando Eventos ---------------*/
	const deleteEvent = (eventToBeDeleted) => {

		message.success('O evento foi excluido')

		setEventos( eventsOfOrganizer.filter(evento => {
			if(evento.course !== eventToBeDeleted) {
				return evento
			}
		}))
	}

	/* -------------- Editando eventos ----------------*/
	const beforeEdit = () => {

		if( !company || !course || !startDate || !finishDate || ! workload || !imageURL){
			message.error('Por favor, não deixe seus dados vazios.')
			//quando o formulário aparece na tela, essa mensagem aparece, caso o campo não tenha sido preenchido.
		} else {
			setToEditFormEvent(!toEditFormEvent)
		}
	}

	//Ao salvar as informações editadas:
	const saveEditFormEvent = (e) => {
		e.preventDefault();
		//Os campos que devem ser preenchidos:
		if( !company || !course || !startDate || !finishDate || ! workload || !imageURL){
			message.error('Por favor, preencha todos os campos do formulário.')
			//quando o formulário aparece na tela, essa mensagem aparece, caso o campo não tenha sido preenchido.

		} else {
			/*Atualizando o evento do organizador*/
			setEventos(eventsOfOrganizer.map(evento => {
				
				/*Mudando somente o evento requerido*/
				if(eventEdited === evento.course) {
					evento['company'] = company
					evento['course'] = course
					evento['startDate'] = startDate
					evento['finishDate'] = finishDate
					evento['workload'] = workload
					evento['digitalSignature'] = imageURL

					return evento;
				} else {
					return evento;
				}
				
			}) )

			message.success('Os dados do evento foram atualizados com sucesso!')

			/*Voltando para a lista de eventos*/
			//setToEditFormEvent(!toEditFormEvent)
		}
		
	}

	const clickEditFormEvent = (eventToBeEdit) => {

		/*Trocando a lista de eventos pelo formulário de edição*/
		setToEditFormEvent(!toEditFormEvent)

		/*Guardando qual evento será editado*/
		setEventEdited(eventToBeEdit.course)

		setCompany(eventToBeEdit.company)
		setCourse(eventToBeEdit.course)
		setStartDate(eventToBeEdit.startDate)
		setFinishDate(eventToBeEdit.finishDate)
		setWorkload(eventToBeEdit.workload)
	}

	/*Esta função é acionada quando o botão para o check list é acionado*/
	const saveEventToList = (eventToList) => {
		setList(true)
		setEventChecked(eventToList)
	}

	/*Esta função é acionada quando o botão para mais infomações do evento*/
	const seeEvents = (eventToList) => {
		setSeeEvents(true)
		setEventChecked(eventToList)
	}

	return(
		<>
		
		<div style={{ display: ( toEditFormEvent || toCreateFormEvent || toProfile || toList || toSeeEvents )?  'none' : null }}>

			<h1 className="title-2-list-events"><UserOutlined onClick={() => setProfile(true)}/> {organizador}</h1>

			<Button className="button-add" onClick={() => setToCreateFormEvent(true)}><UsergroupAddOutlined/> Cadastrar mais um evento</Button>
			
			<br/>
			<h1 className="title">Eventos Cadastrados</h1>
			<div className="listEvents">
			{
				eventos.map(eventoJson => {

					if(eventoJson.user === organizador ){
						noEvents = false
						return(
							<Card 
								style={{ width: 300 }}
								    cover={
								     	<img
								   			alt="Poster do evento"
								    		src="https://jaquelinecramos.files.wordpress.com/2018/03/dyfqkqaw0aad5xm.jpg?w=776"
								      />
								    }
								    actions={[
								    	<>
								    	<Popover content={<h5>Ver mais info. do evento</h5>}>
								     		<Button style={{ borderColor: 'transparent'}} onClick={() => seeEvents(eventoJson) }><HeartOutlined key="edit" /></Button>
								     	</Popover>

								     	<Popover content={<h5>Editar evento</h5>}>
								     		<Button style={{ borderColor: 'transparent'}} onClick={() =>  clickEditFormEvent(eventoJson) } ><FormOutlined key="edit" /></Button>
								     	</Popover>

								     	<Popover content={<h5>Participantes</h5>}>
								     		<Button style={{ borderColor: 'transparent'}} onClick={() =>  saveEventToList(eventoJson)}><TeamOutlined key="ellipsis" /></Button>
								    	</Popover>

								     	<Popconfirm 
								     		title="Você tem certeza de que quer excluir este evento?"
								     		onConfirm={() => deleteEvent(eventoJson.course) }
								     		okText="Sim"
								     		cancelText="Não"
								     	>
								    		<Button style={{ borderColor: 'transparent'}} ><CloseOutlined key="edit" /></Button>
								    	</Popconfirm>
								    	</>
								    ]}
								  >
								    <Meta
								      avatar={<Avatar src="https://cdn-images-1.medium.com/max/1200/1*B8rGvo7fJ7qL4uFJ_II_-w.png" />}
								      title={<h4 style={{ color: '#C6255A'}}>{eventoJson.course}</h4>}
								      description={
								      		<>
								      			<h5 style={{ fontSize: '12px'}}>Inicio: &nbsp;{eventoJson.startDate}</h5>
								      			
								      			<h5 style={{ fontSize: '12px'}}>Encerramento: &nbsp;{eventoJson.finishDate}</h5>
								      		</>
								      	}
								    />
							</Card>
						)
					}
				})
			}
			{ noEvents && <Empty style={{marginTop: '5%'}}/> }
			</div>

		</div>
		{toEditFormEvent && 
		// Mostra na tela o formulário com os campos para serem editados
		//o value está trazendo as informações do último cadastrado "Lucas...."
		//quando eu troco o nome do course (Evento), altera o nome dos 3 eventos que estão sendo mostrados na tela
			<div className="edit-event"
				style={{ display: toEditFormEvent ?  'block' : 'none' }} >

				<h2 className="edit-event-title">Edite os dados do seu evento:</h2>
				<h4>Comunidade:</h4>
				<Input 
					className="edit-event-input" 
					placeholder="Comunidade" 
					value={company} 
					onChange={ newValue => setCompany(newValue.target.value) } />
				<br/>
				<h4>Evento:</h4>
				<Input 
					className="edit-event-input" 
					placeholder="Evento" 
					value={course} 
					onChange={ newValue => setCourse(newValue.target.value) }/>
				<br/>
				<h4>Data de Inicio:</h4>
				<Input 
					className="edit-event-input" 
					placeholder="Data de Início" 
					value={startDate} 
					onChange={ newValue => setStartDate(newValue.target.value) }/>
				<br/>
				<h4>Data de Encerramento:</h4>
				<Input 
					className="edit-event-input" 
					placeholder="Data de Fim" 
					value={finishDate} 
					onChange={ newValue => setFinishDate(newValue.target.value) }/>
				<br/>
				<h4>Carga Horaria:</h4>
				<Input 
					className="edit-event-input" 
					placeholder="Carga Horária" 
					value={workload} 
					onChange={ newValue => setWorkload(newValue.target.value) }/>
				<br/>
				<h4>Assinatura Digital:</h4>
				<div>
					<Popup modal trigger={<Button className="button-open-pad">Abrir Pad para assinar</Button>}>
						{ close => (
							<>
								<SignaturePad ref={sigCanvas}
											  canvasProps={{
											  	className: 'signatureCanvas'
											  }}
								/>
								<Button onClick={save} className="button-save">Salvar</Button>
								<Button onClick={clear} >Apagar Tudo</Button>
								<Button onClick={close} className="button-close" >Fechar</Button>
							</>
						)}
					</Popup>
					<br/>
					<br/>
					{ imageURL ? (
						<img
							src={imageURL}
							alt="Minha assinatura Digital"
							className="buttons-pad"

						/>
					) : null }
				</div>

				<Button 
					className="button-edit-event" type="primary" primary 
					onClick={saveEditFormEvent}>Atualizar dados</Button>
				<br/>

				<Button className="back-edit-event" onClick={beforeEdit}>Voltar para a lista de eventos</Button>
			</div>
		}

		{ toCreateFormEvent && 
			<>
				
				<Form name="time_related_controls" {...formItemLayout} onFinish={onFinish}>  
			      <div className="inputs-event">
			        <h1 className="h1-form-event">Criando um novo evento</h1>
			        <Form.Item
				        {...formInputLayout}
				        {...rangeInputs}
			          className="input-1-event"
				        name="company"
				        label="Comunidade" >

			          <Input placeholder="Digite a comunidade responsável pelo evento" />
			        </Form.Item>

			        <Form.Item
			          {...formInputLayout}
			          {...rangeInputs}
			          className="input-2-event"
			          name="course"
			          label="Curso/Evento">
			          <Input placeholder="Digite o nome do evento"  />
			        </Form.Item>

			        <Form.Item 
			          {...rangeInputs}
			          className="input-3-event"
			          label="Carga Horária" 
			          name="workload" >
			          <InputNumber /> 
			        </Form.Item>

			        <Form.Item 
			          name="range-picker" 
			          className="input-4-event"
			          label="Data de inicio/fim do evento" 
			          {...rangeConfig}>
			          <RangePicker />
			        </Form.Item>

			        <div className="upload-assinature">
			        	<h3 className="h3-form-event">Assinatura Digital:</h3>
			        	<div>
							<Popup modal trigger={<Button className="button-open-pad">Abrir Pad para assinar</Button>}>
								{ close => (
									<>
										<SignaturePad ref={sigCanvas}
													  canvasProps={{
													  	className: 'signatureCanvas'
													  }}
										/>
										<Button onClick={save} className="button-save">Salvar</Button>
										<Button onClick={clear} >Apagar Tudo</Button>
										<Button onClick={close} className="button-close" >Fechar</Button>
									</>
								)}
							</Popup>
							<br/>
							<br/>
							{ imageURL ? (
								<img
									src={imageURL}
									alt="Minha assinatura Digital"
									className="buttons-pad"
								/>
							) : <h4 style={{ color: 'red'}}>Sem assinatura</h4> }
						</div>
			        </div>


			        <Form.Item>
			        	<Button type="primary" htmlType="submit" className="button-events">
			        		Cadastrar Novo Evento
			        	</Button>
			            <br/>
			        </Form.Item>

			         
			      </div>
			    </Form>
				<Button 
					onClick={() => setToCreateFormEvent(false)} 
					className="button-back-from-create"
					>
	                Voltar para a lista de Eventos
	            </Button>
			</>
		}

		{ toProfile && 
			<>
				<ProfileCard organizador={organizador} users={users} assinatura={imageURL}/>
				<Button 
					onClick={() => setProfile(false)}
					className="button-back-of-profile" 
					>
	                Voltar para a lista de Eventos
	            </Button>
			</>
		}

		{ toList &&
			<>
				<ListOfPresents evento={eventChecked}/>
				<Button onClick={() => setList(false)} className="button-back-from-list" style={{ marginButtom: '-20%'}}>
	                Voltar para a lista de Eventos
	            </Button>
	        </>
		}

		{
			toSeeEvents && 
				<>
					<InfoEvent evento={eventChecked}/>
					<Button 
						onClick={() => setSeeEvents(false)}
						className="button-back-of-profile" 
						>
	                	Voltar para a lista de Eventos
	            	</Button>
	            </>
		}
		</>		
			
	);
}
Example #26
Source File: adminUsers.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>Change User Permissions <ClusterOutlined /></span>}
                    visible={this.state.permissionModal}
                    onOk={this.changePermissions}
                    onCancel={() => { this.setState({ permissionModal: false }) }}
                    confirmLoading={this.state.modalLoading}
                >
                    <Select size="large" value={this.state.permissionChangeTo} style={{ width: "30ch" }} onSelect={(value) => { this.setState({ permissionChangeTo: value }) }}>
                        <Option value="0">0 - Normal User</Option>
                        <Option value="1">1 - Challenge Creator User</Option>
                        <Option value="2">2 - Admin User</Option>
                    </Select>
                    <br />
                    <br />

                    <ul>
                        <li><b>0 - Normal User</b>: Has access to the basic functions and nothing else</li>
                        <li><b>1 - Challenge Creator User</b>: Has the additional power of submitting new challenges, but not modifying existing ones</li>
                        <li><b>2 - Admin User</b>: Has full access to the platform via the admin panel.</li>
                    </ul>
                </Modal>

                <Modal
                    title="Create New Account"
                    visible={this.state.createUserModal}
                    footer={null}
                    onCancel={() => { this.setState({ createUserModal: false }) }}
                >

                    <RegisterForm createAccount={this.createAccount.bind(this)} setState={this.setState.bind(this)} />
                </Modal>

                <Modal
                    title={"Changing Account Password For: " + this.state.username}
                    visible={this.state.passwordResetModal}
                    footer={null}
                    onCancel={() => { this.setState({ passwordResetModal: false }) }}
                >

                    <ChangePasswordForm username={this.state.username} setState={this.setState.bind(this)} />
                </Modal>

                <Modal
                    title={"Changing Category For: " + this.state.username}
                    visible={this.state.categoryChangeModal}
                    footer={null}
                    onCancel={() => { this.setState({ categoryChangeModal: false }) }}
                >

                    <SelectParticipantCategoryForm fillTableData={this.fillTableData.bind(this)} categoryList={this.state.categoryList} username={this.state.username} participantCategory={this.state.participantCategory} />
                </Modal>

                <Modal
                    title={"Changing Email For: " + this.state.username}
                    visible={this.state.emailChangeModal}
                    footer={null}
                    onCancel={() => { this.setState({ emailChangeModal: false }) }}
                >

                    <ChangeEmailForm fillTableData={this.fillTableData.bind(this)} username={this.state.username} setState={this.setState.bind(this)} />
                </Modal>


                <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={<UserOutlined />} onClick={() => { this.setState({ createUserModal: true }) }}>Create New User</Button>
                        {this.state.loading && (
                            <div style={{ display: "flex", justifyContent: "center", alignItems: "center" }}>
                                <Ellipsis color="#177ddc" size={60} ></Ellipsis>
                                <h1>Loading Users</h1>
                            </div>
                        )}
                    </div>
                    <Button loading={this.state.loading} type="primary" shape="circle" size="large" style={{ marginBottom: "2vh", maxWidth: "25ch" }} icon={<RedoOutlined />} onClick={async () => { await Promise.all([this.fillTableData(), this.getDisableStates()]); message.success("Users list refreshed.") }} />
                </div>
                <div style={{ display: "flex", alignItems: "center" }}>
                    <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 user(s) (' + this.state.selectedTableKeys.join(", ") + ')? This action is irreversible.',
                            icon: <ExclamationCircleOutlined />,
                            onOk: (close) => { this.deleteAccounts(close.bind(this), this.state.selectedTableKeys) },
                            onCancel: () => { },
                        });
                    }}>Delete Users</Button>
                    <Button type="default" disabled={this.state.disableEditButtons} style={{ marginBottom: "2vh", marginRight: "1ch", backgroundColor: "#6e6e6e" }} icon={<CheckOutlined style={{ color: "#49aa19" }} />} onClick={() => {
                        confirm({
                            confirmLoading: this.state.disableEditButtons,
                            title: 'Are you sure you want to verify the user(s) (' + this.state.selectedTableKeys.join(", ") + ')?',
                            icon: <ExclamationCircleOutlined />,
                            onOk: (close) => { this.verifyAccounts(close.bind(this), this.state.selectedTableKeys) },
                            onCancel: () => { },
                        });
                    }}>Verify Users</Button>
                    <Button type="default" disabled={this.state.disableEditButtons} style={{ marginBottom: "2vh", marginRight: "1ch", backgroundColor: "#6e6e6e" }} icon={<CloseOutlined style={{ color: "#a61d24" }} />} onClick={() => {
                        confirm({
                            confirmLoading: this.state.disableEditButtons,
                            title: 'Are you sure you want to un-verify the user(s) (' + this.state.selectedTableKeys.join(", ") + ')?',
                            content: 'Please note that this action will send a new email per user asking them to re-verify.',
                            icon: <ExclamationCircleOutlined />,
                            onOk: (close) => { this.unverifyAccounts(close.bind(this), this.state.selectedTableKeys) },
                            onCancel: () => { },
                        });
                    }}>Un-Verify Users</Button>
                </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 users found/created</h1>
                        </div>
                    )
                }}>
                    <Column title="Username" dataIndex="username" key="username"
                        render={(text, row, index) => {
                            return <Link to={"/Profile/" + text}><a style={{ fontWeight: 700 }}>{text}</a></Link>;
                        }}
                        filterDropdown={({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => (
                            <div style={{ padding: 8 }}>
                                <Input
                                    placeholder="Search Username"
                                    value={selectedKeys[0]}
                                    onChange={e => setSelectedKeys(e.target.value ? [e.target.value] : [])}
                                    onPressEnter={() => confirm()}
                                    style={{ marginBottom: 8, display: 'block' }}
                                    autoFocus
                                />
                                <Space>
                                    <Button
                                        type="primary"
                                        onClick={() => { confirm() }}
                                        icon={<SearchOutlined />}
                                    >
                                        Search
                                    </Button>
                                    <Button onClick={() => clearFilters()}>
                                        Reset
                                    </Button>
                                </Space>
                            </div>
                        )}
                        onFilter={(value, record) => record.username.toLowerCase().trim().includes(value.toLowerCase())}
                        filterIcon={filtered => <SearchOutlined style={{ color: filtered ? '#1890ff' : undefined }} />}
                        sorter={(a, b) => {
                            if (a.username < b.username) return -1
                            else return 1
                        }}
                    />
                    <Column title="Email" dataIndex="email" key="email"
                        filterDropdown={({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => (
                            <div style={{ padding: 8 }}>
                                <Input
                                    placeholder="Search Email"
                                    value={selectedKeys[0]}
                                    onChange={e => setSelectedKeys(e.target.value ? [e.target.value] : [])}
                                    onPressEnter={() => confirm()}
                                    style={{ marginBottom: 8, display: 'block' }}
                                    autoFocus
                                />
                                <Space>
                                    <Button
                                        type="primary"
                                        onClick={() => { confirm() }}
                                        icon={<SearchOutlined />}
                                    >
                                        Search
                                    </Button>
                                    <Button onClick={() => clearFilters()}>
                                        Reset
                                    </Button>
                                </Space>
                            </div>
                        )}
                        onFilter={(value, record) => record.email.toLowerCase().trim().includes(value.toLowerCase())}
                        filterIcon={filtered => <SearchOutlined style={{ color: filtered ? '#1890ff' : undefined }} />}
                    />
                    <Column title="Permissions" dataIndex="type" key="type" filters={[{ text: "Normal User (0)", value: 0 }, { text: "Challenge Creator (1)", value: 1 }, { text: "Admin (2)", value: 2 }]} onFilter={(value, record) => { return value === record.type }} />
                    <Column title="Team" dataIndex="team" key="team"
                        render={(text, row, index) => {
                            if (text != "N/A") return <Link to={"/Team/" + text}><a style={{ fontWeight: 700 }}>{text}</a></Link>;
                            else return text;
                        }}
                        filterDropdown={({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => (
                            <div style={{ padding: 8 }}>
                                <Input
                                    placeholder="Search Team"
                                    value={selectedKeys[0]}
                                    onChange={e => setSelectedKeys(e.target.value ? [e.target.value] : [])}
                                    onPressEnter={() => confirm()}
                                    style={{ marginBottom: 8, display: 'block' }}
                                    autoFocus
                                />
                                <Space>
                                    <Button
                                        type="primary"
                                        onClick={() => { confirm() }}
                                        icon={<SearchOutlined />}
                                    >
                                        Search
                                    </Button>
                                    <Button onClick={() => clearFilters()}>
                                        Reset
                                    </Button>
                                </Space>
                            </div>
                        )}
                        onFilter={(value, record) => record.team.toLowerCase().trim().includes(value.toLowerCase())}
                        filterIcon={filtered => <SearchOutlined style={{ color: filtered ? '#1890ff' : undefined }} />}
                    />
                    <Column title="Category" dataIndex="category" key="category" filters={
                        this.state.categoryList.map((category) => {
                            return { text: category, value: category }
                        })} onFilter={(value, record) => { return value === record.category }} />
                    <Column title="Verified" dataIndex="verified" key="verified" filters={[{ text: "Verified", value: "True" }, { text: "Unverified", value: "False" }]} onFilter={(value, record) => { return value === record.verified }} />
                    <Column
                        title=""
                        key="action"
                        render={(text, record) => (
                            <Dropdown trigger={['click']} overlay={
                                <Menu>
                                    <Menu.Item onClick={() => {
                                        this.setState({ permissionModal: true, username: record.username, permissionChangeTo: record.type.toString() })
                                    }}>
                                        <span>
                                            Change Permissions <ClusterOutlined />
                                        </span>
                                    </Menu.Item>
                                    <Menu.Item onClick={() => {
                                        this.setState({ passwordResetModal: true, username: record.username })
                                    }}>
                                        <span>
                                            Change Password <KeyOutlined />
                                        </span>
                                    </Menu.Item>
                                    <Menu.Item onClick={() => {
                                        this.setState({ emailChangeModal: true, username: record.username })
                                    }}>
                                        <span>
                                            Change Email <MailOutlined />
                                        </span>
                                    </Menu.Item>
                                    <Menu.Item onClick={() => {
                                        this.setState({ categoryChangeModal: true, username: record.username, participantCategory: record.category })
                                    }}>
                                        <span>
                                            Change Category <ApartmentOutlined />
                                        </span>
                                    </Menu.Item>
                                </Menu>
                            } placement="bottomCenter">
                                <Button>Actions</Button>
                            </Dropdown>
                        )}
                    />
                </Table>

                <Divider />

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

                    <Card className="settings-card">
                        <h3>Disable User Registration:  <Switch disabled={this.state.disableLoading} onClick={(value) => this.disableSetting("registerDisable", value)} checked={this.state.registerDisable} /></h3>
                        <p>Disables user registration for unregistered users. Admins can still create users from this page.</p>
                    </Card>

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

                    <Card className="settings-card">
                        <h3>Disable User Logins:  <Switch disabled={this.state.disableLoading2} onClick={(value) => this.disableSetting("loginDisable", value)} checked={this.state.loginDisable} /></h3>
                        <p>Disables user login except for admin users. <br /><b>Note:</b> Users already logged into the platform will remain authenticated as tokens cannot be revoked. If you want to restrict a user from accessing the platform anymore, simply delete their account.</p>
                    </Card>

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

                    <Card className="settings-card">
                        <h3>Disable Admin Scores:  <Switch disabled={this.state.disableLoading2} onClick={(value) => this.disableSetting("adminShowDisable", value)} checked={this.state.adminShowDisable} /></h3>
                        <p>Prevents admin scores from showing up on scoreboards and profile pages. Admin solves will still appear under the solve list in challenges. <br /> Please note that disabling/enabling this will require users to reopen ctfx to resync the scoreboard.</p>
                    </Card>
                </div>

                <Divider />

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

                    <Card className="settings-card">
                        <h3>Profile Picture Max Upload Size: <InputNumber
                            formatter={value => `${value}B`}
                            parser={value => value.replace('B', '')}
                            value={this.state.uploadSize}
                            disabled={this.state.uploadLoading}
                            onChange={(value) => this.setState({ uploadSize: value })}
                            onPressEnter={(e) => { this.changeSetting("uploadSize", this.state.uploadSize) }} /></h3>

                        <p>Sets the maximum file upload size for profile pictures (in Bytes). Press <b>Enter</b> to save</p>
                    </Card>

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

                    <Card className="settings-card">
                        <h3>Disable Category Switches:  <Switch disabled={this.state.disableLoading2} onClick={(value) => this.disableSetting("categorySwitchDisable", value)} checked={this.state.categorySwitchDisable} /></h3>
                        <p>Prevents users from switching their scoreboard category. Useful during competitions where you want to lock the user into a category</p>
                    </Card>

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

                    <Card className="settings-card">
                        <h3>User Category Management <UserOutlined /></h3>
                        <Space direction="vertical">
                            {this.state.categoryList.map((category) => {
                                return (
                                    <div style={{ display: 'flex', alignItems: "center" }}>
                                        <Input disabled value={category} />
                                         <MinusCircleOutlined onClick={() => { this.removeCategory(category) }} style={{ cursor: "pointer", marginLeft: "1ch", color: "#f5222d" }} />
                                    </div>
                                )
                            })}
                            <div style={{ display: "flex" }}>
                                <Input value={this.state.newCategoryValue} onChange={(e) => { this.setState({ newCategoryValue: e.target.value }) }} />
                                <Button
                                    loading={this.state.addCategoryLoading}
                                    style={{ marginLeft: "1ch" }}
                                    type="dashed"
                                    onClick={() => {
                                        this.addCategory()
                                    }}
                                >
                                    <PlusOutlined /> Add Category
                                </Button>
                            </div>
                        </Space>
                    </Card>
                </div>

                <Divider />

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

                    <Card className="settings-card">
                        <h3>Max Team Size: <InputNumber
                            value={this.state.teamMaxSize}
                            onChange={(value) => this.setState({ teamMaxSize: value })}
                            onPressEnter={(e) => { this.changeSetting("teamMaxSize", this.state.teamMaxSize) }} />
                        </h3>
                        <p>Sets the maximum number of members in a team. Press <b>Enter</b> to save</p>
                    </Card>

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

                    <Card className="settings-card">
                        <h3>Enable Teams:  <Switch disabled={this.state.disableLoading3} onClick={(value) => this.disableSetting("teamMode", value)} checked={this.state.teamMode} /></h3>
                        <p>Enable teams for the platform. Users in a team will have their scores combined on the scoreboard <br /> Please note that disabling/enabling this will require users to reopen ctfx to resync the scoreboard.</p>
                    </Card>

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

                    <Card className="settings-card">
                        <h3>Disable Team Switching:  <Switch disabled={this.state.disableLoading3} onClick={(value) => this.disableSetting("teamChangeDisable", value)} checked={this.state.teamChangeDisable} /></h3>
                        <p>Prevents users from leaving, joining & creating a team. Enable this option if you want to prevent any team changes during a competition</p>
                    </Card>
                </div>

                <Divider />

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

                    <Card className="settings-card">
                        <h3>Enable Password Reset  <Switch disabled={this.state.disableLoading2} onClick={(value) => this.disableSetting("forgotPass", value)} checked={this.state.forgotPass} /></h3>
                        <p>Allow users to use the "Forgot Password" option to reset their password. <br />Please ensure that you have connected to an SMTP server correctly in the "Email" tab</p>
                    </Card>

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

                    <Card className="settings-card">
                        <h3>Enable Email Verification  <Switch disabled={this.state.disableLoading2} onClick={(value) => this.disableSetting("emailVerify", value)} checked={this.state.emailVerify} /></h3>
                        <p>Forces newly registered users to <b>verify their email</b> before being able to access the site.</p>
                    </Card>

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

                    <Card className="settings-card">
                        <h3>Profile Picture Upload Path
                            <Input
                                value={this.state.uploadPath}
                                onChange={(e) => this.setState({ uploadPath: e.target.value })}
                                onPressEnter={(e) => { this.changeSetting("uploadPath", this.state.uploadPath) }} /></h3>
                        <p>Sets the file upload path for profile pictures. Please ensure that the folder has the appropriate permissions <br />set for the Node process to save the file there. Press <b>Enter</b> to save</p>
                    </Card>
                </div>

            </Layout>
        );
    }