@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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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: {eventoJson.startDate}</h5>
<h5 style={{ fontSize: '12px'}}>Encerramento: {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 |
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>
);
}