@material-ui/core#Chip JavaScript Examples
The following examples show how to use
@material-ui/core#Chip.
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: BetaBanner.js From akashlytics-deploy with GNU General Public License v3.0 | 6 votes |
BetaBanner = () => {
const [isBetaBarVisible, setIsBetaBarVisible] = useState(true);
const classes = useStyles();
const onCloseClick = () => {
localStorage.setItem("isBetaBannerSeen", true);
setIsBetaBarVisible(false);
};
return (
<>
{isBetaBarVisible && (
<Dialog open={true} maxWidth="xs" fullWidth>
<DialogContent className={classes.dialogContent}>
<Typography variant="h3">
<strong>Welcome!</strong>
</Typography>
<Box padding="1rem 0">
<Chip label="BETA" color="secondary" className={classes.betaChip} size="small" />
</Box>
<div className={classes.betaText}>
<Typography variant="body1">
<strong>Akashlytics Deploy</strong> is currently in <strong>BETA</strong>. We strongly suggest you start with a new wallet and a small amount of
AKT until we further stabilize the product. Enjoy!
</Typography>
</div>
</DialogContent>
<DialogActions>
<Button variant="contained" onClick={onCloseClick} type="button" color="primary">
Got it!
</Button>
</DialogActions>
</Dialog>
)}
</>
);
}
Example #2
Source File: DataPreview.js From Otto with MIT License | 6 votes |
export default function DataPreview() {
const { state } = useState();
const classes = useStyles();
if (state.sample_dataset == null) {
return null;
}
const metadata = datasetMetadata[state.sample_dataset];
function getFormatted(label, index) {
if (metadata.units) {
return label + " (" + metadata.units[index] + ")";
}
return label;
}
return (
<Grid direction="column" container className={classes.noPadding}>
{/* Data Attributes */}
<Grid item>
<div className={classes.root}>
{chipData(state).map((data, index) => {
return (
<li key={index}>
<Chip label={data} color="primary" className={classes.chip} />
</li>
);
})}
</div>
</Grid>
{/* Table */}
<Grid item className={classes.fullWidth}>
<TableContainer component={Paper} className={classes.table}>
<Table size="small" aria-label="a dense table">
<TableHead>
<TableRow>
{metadata.columns.map((column, index) => (
<TableCell key={index}>
{getFormatted(
metadata.columnsMap
? metadata.columnsMap[column]
: column,
index
)}
</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{metadata.data.slice(0, 5).map((row, index) => (
<TableRow key={index}>
{metadata.columns.map((column, index) => (
<TableCell key={index} component="th" scope="row">
{row[column]}
</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</Grid>
</Grid>
);
}
Example #3
Source File: card.js From dscbppimt-official-website with MIT License | 6 votes |
AboutCard = ({ image, title, body, hashtag }) => {
const classes = useStyles()
return(
<Card elevation={2} className={classes.aboutCard}>
<CardContent className={classes.aboutCardContent}>
{image}
<Typography variant="subtitle1" component="h5" className={classes.aboutCardTitle}>{title}</Typography>
<Typography variant="body2" component="p" className={classes.aboutCardBody}>{body}</Typography>
<Chip label={hashtag}/>
</CardContent>
</Card>
)
}
Example #4
Source File: TagsManager.js From Edlib with GNU General Public License v3.0 | 6 votes |
renderTags() {
return this.props.tags.map((tag) => {
return (
<Chip
onDelete={() => this.handleRemove(tag)}
key={'tag-' + tag}
className={this.props.classes.chip}
label={tag}
/>
);
});
}
Example #5
Source File: Table.js From react-code-splitting-2021-04-26 with MIT License | 6 votes |
export default function TableComponent({ data }) {
const classes = useStyles();
var keys = Object.keys(data[0]).map(i => i.toUpperCase());
keys.shift(); // delete "id" key
return (
<Table className="mb-0">
<TableHead>
<TableRow>
{keys.map(key => (
<TableCell key={key}>{key}</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{data.map(({ id, name, email, product, price, date, city, status }) => (
<TableRow key={id}>
<TableCell className="pl-3 fw-normal">{name}</TableCell>
<TableCell>{email}</TableCell>
<TableCell>{product}</TableCell>
<TableCell>{price}</TableCell>
<TableCell>{date}</TableCell>
<TableCell>{city}</TableCell>
<TableCell>
<Chip label={status} classes={{root: classes[states[status.toLowerCase()]]}}/>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
);
}
Example #6
Source File: index.js From yi-note with GNU General Public License v3.0 | 6 votes |
Tags = () => {
const { tags } = useStoreState(state => state.page.data);
const handleTagClick = tag => {
browser.runtime.sendMessage({
action: 'open-options',
data: { action: 'filter-by-tags', data: [tag] }
});
};
return (
<Grid container spacing={1}>
{tags.map(tag => (
<Grid item key={tag}>
<Chip
label={tag}
color="default"
clickable
onClick={handleTagClick.bind(null, tag)}
/>
</Grid>
))}
</Grid>
);
}
Example #7
Source File: Footer.js From akashlytics-deploy with GNU General Public License v3.0 | 5 votes |
Footer = () => {
const classes = useStyles();
const { appVersion } = useAppVersion();
return (
<AppBar position="fixed" color="default" elevation={0} component="footer" className={classes.root} id="footer">
<Toolbar variant="dense" className={classes.toolbar}>
<Box display="flex" alignItems="center">
{appVersion && (
<>
<Typography variant="caption" className={classes.caption}>
<strong>v{appVersion}</strong>
</Typography>
<Chip label="beta" color="secondary" size="small" className={classes.betaChip} />
</>
)}
<LinkTo onClick={() => window.electron.openUrl("https://akash.network")} className={classes.akashLink}>
<img src="./images/powered-by-akash.svg" alt="Akashlytics Logo" className={classes.akashImage} />
</LinkTo>
</Box>
<Box display="flex" alignItems="center">
<Box marginRight="1rem">
<Button
onClick={() => window.electron.openUrl("https://www.mintscan.io/akash/validators/akashvaloper14mt78hz73d9tdwpdvkd59ne9509kxw8yj7qy8f")}
size="small"
>
<Typography variant="caption" className={classes.caption}>
Validator
</Typography>
</Button>
</Box>
<ul className={classes.socialLinks}>
<li>
<LinkTo onClick={() => window.electron.openUrl("https://discord.gg/rXDFNYnFwv")} className={classes.socialLink}>
<DiscordIcon className={classes.socialIcon} />
</LinkTo>
</li>
<li>
<LinkTo
onClick={() => window.electron.openUrl("https://www.youtube.com/channel/UC1rgl1y8mtcQoa9R_RWO0UA?sub_confirmation=1")}
className={classes.socialLink}
>
<YouTubeIcon className={classes.socialIcon} />
</LinkTo>
</li>
<li>
<LinkTo onClick={() => window.electron.openUrl("https://twitter.com/akashlytics")} className={classes.socialLink}>
<TwitterIcon className={classes.socialIcon} />
</LinkTo>
</li>
<li>
<LinkTo onClick={() => window.electron.openUrl("https://github.com/Akashlytics/akashlytics-deploy")} className={classes.socialLink}>
<GitHubIcon className={classes.socialIcon} />
</LinkTo>
</li>
</ul>
</Box>
</Toolbar>
</AppBar>
);
}
Example #8
Source File: QuesCard.js From stack-underflow with MIT License | 5 votes |
QuesCard = ({ question }) => {
const classes = useQuesCardStyles();
const {
id,
title,
author,
body,
tags,
points,
views,
answerCount,
createdAt,
} = question;
return (
<Paper elevation={0} className={classes.root}>
<div className={classes.infoWrapper}>
<div className={classes.innerInfo}>
<Typography variant="body2" className={classes.mainText}>
{points}
</Typography>
<Typography variant="caption">votes</Typography>
</div>
<div className={classes.innerInfo}>
<Typography variant="body2" className={classes.mainText}>
{answerCount}
</Typography>
<Typography variant="caption">answers</Typography>
</div>
<Typography variant="caption" noWrap>
{views} views
</Typography>
</div>
<div className={classes.quesDetails}>
<Typography
variant="body2"
color="secondary"
className={classes.title}
component={RouterLink}
to={`/questions/${id}`}
>
{title}
</Typography>
<Typography variant="body2" style={{ wordWrap: 'anywhere' }}>
{body.length > 150 ? body.slice(0, 150) + '...' : body}
</Typography>
<div className={classes.bottomWrapper}>
<div className={classes.tagsWrapper}>
{tags.map((t) => (
<Chip
key={t}
label={t}
variant="outlined"
color="primary"
size="small"
component={RouterLink}
to={`/tags/${t}`}
className={classes.tag}
clickable
/>
))}
</div>
<PostedByUser
username={author.username}
userId={author.id}
createdAt={createdAt}
/>
</div>
</div>
</Paper>
);
}
Example #9
Source File: ProductOptions.js From beluga with GNU General Public License v3.0 | 5 votes |
function ProductOptions(props) {
const { variant, handleNameChange, onSave, inEditMode } = props;
const [variantOptionText, setVariantOptionText] = useState("");
return (
<div>
<div style={{ display: "flex", alignItems: "center" }}>
{(onSave && !inEditMode) ? (
<div style={{ fontWeight: "bold", margin: "0 40px 10px 0" }}>
{variant.name}
</div>
) : (
<TextField
label="Option Name (i.e. Size, Color)"
style={{ width: "350px" }}
value={variant.name}
onChange={(e) => handleNameChange(e.target.value)}
margin="normal"
/>
)}
{ onSave && inEditMode && (
<Button
onClick={onSave}
variant="outlined" color="secondary" size="small"
style={{ verticalAlign: "bottom", margin: "0 40px" }}
>
Save
</Button>
)}
<div style={{ margin: "0 0 10px 40px", verticalAlign: "bottom", display: "inline-block" }}>
{ variant.options.map((v,i) => (
<Chip key={`variant${i}`}
label={v.label}
onDelete={() => props.deleteVariantOption(i)}
color="secondary"
variant="outlined"
style={{ marginRight: "10px" }}
/>
))}
</div>
</div>
<Step disabled={onSave && inEditMode}>
<TextField
label="Option Value (i.e. Medium, Blue)"
value={variantOptionText}
onChange={(e) => setVariantOptionText(e.target.value)}
margin="normal"
size="small"
style={{ width: "350px" }}
/>
<Button
onClick={() => {
props.addVariantOption(variantOptionText);
setVariantOptionText("");
}}
variant="outlined" color="secondary" size="small"
style={{ verticalAlign: "bottom", margin: "0 0 10px 40px" }}
>
Add
</Button>
</Step>
</div>
);
}
Example #10
Source File: Header.js From spells-fyi with MIT License | 5 votes |
Header = () => {
const classes = useStyles();
return (
<Grid className={classes.topBar}
container
direction="row"
alignItems="center"
justify="space-between"
>
<Grid item>
<Grid
container
direction="row"
justify="flex-start"
alignItems="center"
wrap="nowrap"
>
<img src={ Blocky } className={classes.logo} alt="Blocklytics" />
<Typography className={classes.logoText}>Spells</Typography>
<Chip label=".fyi" className={classes.fyiTag} />
</Grid>
</Grid>
<Grid item>
<Grid container direction="row" alignItems="center" justify="flex-end" spacing={2}>
<Grid item>
<Button color="primary" href="https://github.com/blocklytics/spells-fyi" target="_blank">Code</Button>
</Grid>
<Grid item>
<Button color="primary" href="https://thegraph.com/explorer/subgraph/blocklytics/spells" target="_blank">Data</Button>
</Grid>
{/* <Grid item>
<Button color="primary">Bounties</Link>
</Grid> */}
<Grid item>
<Button color="primary" href="https://twitter.com/spellsfyi" target="_blank">Twitter</Button>
</Grid>
<Grid item>
<Button color="primary" href="https://discordapp.com/invite/GFxFN3K" target="_blank">Discord</Button>
</Grid>
<Grid item>
<Button color="primary" href="https://gitcoin.co/grants/601/spellsfyi-see-the-future" target="_blank">GitCoin</Button>
</Grid>
</Grid>
</Grid>
</Grid>
)
}
Example #11
Source File: MentorCard.js From mentors-website with MIT License | 5 votes |
MentorCard = (props) => {
const classes = useStyles();
const {
mentor,
choseCountry,
choseSkill,
heartedMentor,
toggleHeartedMentor,
} = props;
const handleFlagClick = () => {
choseCountry(mentor.countryAlpha2Code)
}
const handleSkillChipClick = (e) => {
choseSkill(e.target.textContent)
}
return (
<Card className={classes.root}>
<CardHeader
avatar={
<Avatar
src={`https://unavatar.now.sh/twitter/${mentor.twitter}`}
aria-label="mentor"
className={classes.avatar}
>
{mentor.name[0]}
</Avatar>
}
action={
<IconButton onClick={handleFlagClick}>
<img
src={`https://www.countryflags.io/${mentor.countryAlpha2Code}/flat/32.png`}
alt={mentor.country}
/>
</IconButton>
}
title={mentor.name}
subheader={mentor.title}
/>
<CardContent className={classes.MessageCardContent}>
<Typography variant="body2">"{mentor.message}"</Typography>
</CardContent>
<CardContent className={classes.SkillsCardContent}>
<Grid container justify="center" spacing={1}>
{mentor.skills.map((skill, index) => (
<Grid key={index} item>
<Chip label={skill} variant="outlined" onClick={handleSkillChipClick} />
</Grid>
))}
</Grid>
</CardContent>
<Divider variant="fullWidth" />
<CardActions className={classes.cardAction} disableSpacing>
<Button href="#connect-mentor" color="primary">
Connect
</Button>
<IconButton onClick={() => toggleHeartedMentor(mentor.id)}>
{heartedMentor ? (
<FavoriteOutlinedIcon color="secondary" />
) : (
<FavoriteBorderOutlinedIcon />
)}
</IconButton>
</CardActions>
</Card>
);
}
Example #12
Source File: Highlightable.js From dataqa with GNU General Public License v3.0 | 5 votes |
getRanges() {
const newText = [];
let lastRange;
// For all the characters on the text
for(let textCharIndex = 0;textCharIndex < this.props.text.length;textCharIndex++) {
const range = this.getRange((this.props.startChar || 0) + textCharIndex);
if(range){
console.log("char index ", textCharIndex, "startChar ", this.props.startChar , range);
}
const url = getUrl(textCharIndex, this.props.text);
const isEmoji = emojiRegex().test(this.props.text[textCharIndex] + this.props.text[textCharIndex + 1]);
// Get the current character node
const node = this.getNode(textCharIndex, range, this.props.text, url, isEmoji);
// If the next node is an url one, we fast forward to the end of it
if(url.length) {
textCharIndex += url.length - 1;
} else if(isEmoji) {
// Because an emoji is composed of 2 chars
textCharIndex++;
}
if(!range) {
newText.push(node);
continue;
}
// If the char is in range
lastRange = range;
// We put the first range node on the array
const letterGroup = [node];
// For all the characters in the highlighted range
let rangeCharIndex = textCharIndex + 1;
for(;rangeCharIndex < parseInt(range.end - (this.props.startChar || 0)) + 1;rangeCharIndex++) {
const isEmoji = emojiRegex().test(`${this.props.text[rangeCharIndex]}${this.props.text[rangeCharIndex + 1]}`);
if(isEmoji) {
letterGroup.push(this.getEmojiNode(rangeCharIndex, range));
// Because an emoji is composed of 2 chars
rangeCharIndex++;
} else {
letterGroup.push(this.getLetterNode(rangeCharIndex, range));
}
textCharIndex = rangeCharIndex;
}
// const RangeText = letterGroup.map((node) => node.props.children).join('');
// if range does not have entityId (ED), then assign default color
let color, variant;
if((typeof range.entityId) === "undefined"){
color = colors["grey"][100];
variant='outlined';
}else{
color = colors[this.props.entityColourMap[range.entityId]][200];
}
newText.push(<Chip
key={`chip-${textCharIndex}`}
style={{backgroundColor: color}}
label={letterGroup}
onDelete={this.props.onDeleteRange? () => this.props.onDeleteRange(range) : undefined}
variant={variant}
/>);
}
return newText;
}
Example #13
Source File: Facets.js From azure-search-react-template with MIT License | 5 votes |
export default function Facets(props) {
function mapFacetName(facetName) {
const capitalizeFirstLetter = (string) =>
string[0] ? `${string[0].toUpperCase()}${string.substring(1)}` : '';
facetName = facetName.trim();
facetName = capitalizeFirstLetter(facetName);
facetName = facetName.replace('_', ' ');
return facetName;
}
function addFilter(name, value) {
const newFilters = props.filters.concat({ field: name, value: value });
props.setFilters(newFilters);
}
function removeFilter(filter) {
const newFilters = props.filters.filter((item) => item.value !== filter.value);
props.setFilters(newFilters);
}
var facets;
try{
facets = Object.keys(props.facets).map(key => {
return <CheckboxFacet
key={key}
name={key}
values={props.facets[key]}
addFilter={addFilter}
removeFilter={removeFilter}
mapFacetName={mapFacetName}
selectedFacets={props.filters.filter( f => f.field === key)}
/>;
});
} catch (error) {
console.log(error);
}
const filters = props.filters.map((filter, index) => {
return (
<li key={index}>
<Chip
label={`${mapFacetName(filter.field)}: ${filter.value}`}
onDelete={() => removeFilter(filter)}
className="chip"
/>
</li>);
});
return (
<div id="facetPanel" className="box">
<div className="facetbox">
<div id="clearFilters">
<ul className="filterlist">
{filters}
</ul>
</div>
<FacetList component="nav" className="listitem" >
{facets}
</FacetList>
</div>
</div>
);
}
Example #14
Source File: BmcDialog.js From budgie-stream with MIT License | 5 votes |
export default function BmcDialog(props) {
const { close } = props;
const classes = useStyles();
const [supporters, setSupporters] = useState({});
const loadSupporters = async () => {
const response = await fetch(
"https://filahf.github.io/budgie-stream-supporters/supporters.json"
);
const data = await response.json();
setSupporters(data.supporters);
};
useEffect(() => {
loadSupporters();
}, []);
return (
<div>
<Dialog
onClose={close}
aria-labelledby="customized-dialog-title"
open={props.open}
scroll="paper"
maxWidth="xs"
>
<DialogTitle
id="customized-dialog-title"
style={{ textAlign: "center", marginBottom: 0, paddingBottom: 0 }}
>
Sponsors & Supporters
</DialogTitle>
<DialogContent>
<Typography>
This project is open source and free to use. If you would like to
support the development of Budgie Stream, consider buying me a
coffee.
</Typography>
<div className={classes.action}>
<Typography style={{ marginTop: "1.5rem" }} variant="subtitle2">
Supporters
</Typography>
</div>
<div className={classes.root}>
{Object.entries(supporters).length === 0 ? (
<Chip variant="outlined" label="No supporters yet" />
) : (
supporters.sort(compare).map((supporter, id) => (
<Tooltip
key={id}
title={"Bought " + supporter.value + " coffee(s)!"}
placement="top"
arrow
>
<Chip
icon={<FavoriteIcon style={{ color: "#bf616a" }} />}
variant="outlined"
label={supporter.name}
/>
</Tooltip>
))
)}
</div>
</DialogContent>
<MuiDialogActions className={classes.action}>
<Button
variant="contained"
color="secondary"
style={{ textTransform: "none" }}
onClick={handleClick}
>
Buy me a coffee
</Button>
</MuiDialogActions>
</Dialog>
</div>
);
}
Example #15
Source File: positions.jsx From GraphVega with MIT License | 5 votes |
Positions = props => {
return (
<Row>
<Col sm={{span:12}}>
<Card>
<CardContent>
<Typography variant="h6" display="block" gutterBottom>
Positions
</Typography>
<Table>
<TableHead>
<TableRow>
<TableCell>TYPE</TableCell>
<TableCell>QTY</TableCell>
<TableCell>MARK</TableCell>
<TableCell>STRIKE</TableCell>
<TableCell>EXPIRY</TableCell>
<TableCell>IMP VOL</TableCell>
<TableCell>VEGA</TableCell>
<TableCell>THETA</TableCell>
<TableCell>DELTA</TableCell>
<TableCell>GAMMA</TableCell>
</TableRow>
</TableHead>
<TableBody>
{props.positions.map((option) => (
<TableRow>
<TableCell>
<Chip label={option.option_type} color={chipStyle(option.option_type)}/>
</TableCell>
<TableCell>{option.quantity}</TableCell>
<TableCell>{(option.bid + option.ask)/2}</TableCell>
<TableCell>{option.strike}</TableCell>
<TableCell>{expiry(option.expiration_date)}</TableCell>
<TableCell>{roundOne(option.greeks.smv_vol*100)}%</TableCell>
<TableCell>{option.greeks.vega}</TableCell>
<TableCell>{option.greeks.theta}</TableCell>
<TableCell>{option.greeks.delta}</TableCell>
<TableCell>{option.greeks.gamma}</TableCell>
</TableRow>
))}
{(props.quantity && props.quantity !== 0) ?
<TableRow>
<TableCell>
<Chip label={"shares"} />
</TableCell>
<TableCell>{props.quantity}</TableCell>
<TableCell>{(props.quote.ask + props.quote.bid)/2}</TableCell>
<TableCell>--</TableCell>
<TableCell>--</TableCell>
<TableCell>--</TableCell>
<TableCell>--</TableCell>
<TableCell>--</TableCell>
<TableCell>{props.quantity}</TableCell>
<TableCell>--</TableCell>
</TableRow>
: ""
}
</TableBody>
</Table>
</CardContent>
</Card>
</Col>
</Row>
)
}
Example #16
Source File: index.js From yi-note with GNU General Public License v3.0 | 5 votes |
TagDialog = ({ tags, onAddTag, onRemoveTag }) => {
const { t } = useTranslation('tagdialog');
const {
tagDialog: { open }
} = useStoreState(state => state);
const {
tagDialog: { setOpen }
} = useStoreActions(actions => actions);
const [input, setInput] = useState('');
const containerRef = useRef(null);
useEffect(() => {
containerRef.current = document.getElementById(APP_ID);
}, []);
const handleClose = () => {
setOpen(false);
};
const handleInputChange = e => {
setInput(e.target.value);
};
const handleKeyPress = e => {
if (e.key === 'Enter') {
onAddTag(input);
setInput('');
}
};
const handleDelete = tag => {
onRemoveTag(tag);
};
return (
<Dialog onClose={handleClose} open={open} container={containerRef.current}>
<DialogContent>
<Grid container direction="column" spacing={3}>
<Grid item>
<TextField
autoFocus
label={t('input.label')}
value={input}
onChange={handleInputChange}
onKeyPress={handleKeyPress}
/>
</Grid>
<Grid item container spacing={1}>
{tags.map(tag => (
<Grid item key={tag}>
<Chip
label={tag}
color="default"
onDelete={handleDelete.bind(null, tag)}
/>
</Grid>
))}
</Grid>
</Grid>
</DialogContent>
</Dialog>
);
}
Example #17
Source File: Disruption.js From warsinhk with MIT License | 5 votes |
Disruption = props => {
const { node, onCategoryClick } = props
const { i18n, t } = useTranslation()
const [expanded, setExpanded] = React.useState(false)
const handleExpandClick = () => {
setExpanded(!expanded)
}
const sourceUrl = withLanguage(i18n, node, "source_url")
const hasDescription = props.children && props.children.length > 0
const ExpandIcon = expanded ? InvertedExpandMoreIcon : ExpandMoreIcon
return (
<DisruptionCard>
<DisruptionCardHeader title={withLanguage(i18n, node, "name")} />
<DisruptionCardContent>
<Box alignItems="flex-start">
<Row>
<Chip
label={withLanguage(i18n, node, "category")}
size="small"
variant="outlined"
onClick={() =>
onCategoryClick(withLanguage(i18n, node, "category"))
}
/>
</Row>
<Row>
<DisruptionDetail variant="body1">
{withLanguage(i18n, node, "detail")}
</DisruptionDetail>
</Row>
<Row>
{t("disruption.status")}:{" "}
{withLanguage(i18n, node, "status") || "-"}
</Row>
<Row>
{t("disruption.to")}: {withLanguage(i18n, node, "to") || "-"}
</Row>
</Box>
</DisruptionCardContent>
<>
<DisruptionCardActions disableSpacing>
<DisruptionAction>
{sourceUrl && (
<Row>
<Typography variant="caption">
<Link component={Link} href={sourceUrl} target="_blank">
{t("disruption.source")}
</Link>
</Typography>
</Row>
)}
<Row>
<Typography variant="caption">
{t("disruption.last_updated", { date: node.last_update })}
</Typography>
</Row>
</DisruptionAction>
{hasDescription && (
<IconButton onClick={handleExpandClick} aria-expanded={expanded}>
<ExpandIcon />
</IconButton>
)}
</DisruptionCardActions>
{hasDescription && (
<Collapse in={expanded} timeout="auto" unmountOnExit>
<DisruptionCardContent>
{hasDescription && (
<Box alignItems="flex-start">{props.children}</Box>
)}
</DisruptionCardContent>
</Collapse>
)}
</>
</DisruptionCard>
)
}
Example #18
Source File: PageRegion.js From covid-19 with MIT License | 5 votes |
Graphs = (props) => {
const classes = useGraphStyles();
const world = useContext(WorldContext);
const name = world.get(props.path, NameComponent);
const basic = world.get(props.path, BasicDataComponent);
const population = world.get(props.path, PopulationComponent);
const [comparingWith, setComparingWith] = React.useState(() => []);
const addComparison = (path) => {
const name = world.get(path, NameComponent);
const basic = world.get(path, BasicDataComponent);
const population = world.get(path, PopulationComponent);
setComparingWith(comparingWith.concat([{
path,
name,
basic,
population
}]));
};
const removeComparison = (i) => {
const copied = [...comparingWith];
copied.splice(i, 1);
setComparingWith(copied);
};
return (
<div className={props.className}>
<div className={classes.comparisons}>
<Typography>Compare with: </Typography>
<SearchInput
className={classes.comparisonSearch}
onChoice={addComparison}
/>
{comparingWith.map(({ path, name }, i) => {
return (
<Chip
key={path.string()}
className={classes.chip}
onDelete={() => removeComparison(i)}
label={name.english()}
/>
);
})}
</div>
{[DailyChangeGraph, DailyTotalGraph, DoublingGraph].map((Graph, i) => (
<Graph
key={i}
name={name}
basic={basic}
population={population}
comparingWith={comparingWith}
className={classes.graph}
/>
))}
</div>
);
}
Example #19
Source File: SendModal.js From akashlytics-deploy with GNU General Public License v3.0 | 4 votes |
SendModal = ({ onClose, onSendTransaction }) => {
const classes = useStyles();
const formRef = useRef();
const [isBalanceClicked, setIsBalanceClicked] = useState(false);
const [error, setError] = useState("");
const { balance } = useWallet();
const {
handleSubmit,
control,
formState: { errors },
watch,
setValue,
clearErrors
} = useForm({
defaultValues: {
recipient: "",
sendAmount: 0
}
});
const { recipient } = watch();
const onBalanceClick = () => {
setIsBalanceClicked((prev) => !prev);
setError("");
clearErrors();
setValue("sendAmount", uaktToAKT(balance - txFeeBuffer, 6));
};
const onSubmit = ({ sendAmount }) => {
clearErrors();
const amount = aktToUakt(sendAmount);
if (!recipient) {
setError(`You must set a recipient.`);
return;
}
if (amount > balance) {
setError(`You can't send more than you currently have in your balance. Current balance is: ${uaktToAKT(amount, 6)}AKT.`);
return;
}
onSendTransaction(recipient.trim(), amount);
};
const onContinueClick = (event) => {
event.preventDefault();
formRef.current.dispatchEvent(new Event("submit", { cancelable: true, bubbles: true }));
};
return (
<Dialog maxWidth="xs" fullWidth aria-labelledby="send-transaction-dialog-title" open={true} onClose={onClose}>
<DialogTitle id="send-transaction-dialog-title">Send tokens</DialogTitle>
<DialogContent dividers className={classes.dialogContent}>
<form onSubmit={handleSubmit(onSubmit)} ref={formRef}>
<FormControl error={!errors.recipient} className={classes.formControl} fullWidth>
<Controller
control={control}
name="recipient"
rules={{
required: true
}}
render={({ fieldState, field }) => {
const helperText = "Recipient is required.";
return (
<TextField
{...field}
type="text"
variant="outlined"
label="Recipient"
error={!!fieldState.invalid}
helperText={fieldState.invalid && helperText}
className={classes.formValue}
/>
);
}}
/>
</FormControl>
<Box marginBottom=".5rem" marginTop=".5rem" textAlign="right">
<LinkTo onClick={() => onBalanceClick()}>Balance: {uaktToAKT(balance, 6)} AKT</LinkTo>
</Box>
<FormControl error={!errors.sendAmount} className={classes.formControl} fullWidth>
<Controller
control={control}
name="sendAmount"
rules={{
required: true,
validate: (value) => value > 0 && value < balance
}}
render={({ fieldState, field }) => {
const helperText = fieldState.error?.type === "validate" ? "Invalid amount." : "Amount is required.";
return (
<TextField
{...field}
type="number"
variant="outlined"
label="Amount"
autoFocus
error={!!fieldState.invalid}
helperText={fieldState.invalid && helperText}
className={classes.formValue}
inputProps={{ min: 0, step: 0.000001, max: uaktToAKT(balance - txFeeBuffer, 6) }}
InputProps={{
startAdornment: <InputAdornment position="start">AKT</InputAdornment>,
endAdornment: isBalanceClicked && (
<InputAdornment position="end">
<Chip label="MAX" size="small" color="primary" />
</InputAdornment>
)
}}
disabled={isBalanceClicked}
/>
);
}}
/>
</FormControl>
{error && (
<Alert severity="warning" className={classes.alert}>
{error}
</Alert>
)}
</form>
</DialogContent>
<DialogActions className={classes.dialogActions}>
<Button onClick={onClose}>Cancel</Button>
<Button onClick={onContinueClick} disabled={!!errors.sendAmount || !!errors.recipient} variant="contained" color="primary">
Continue
</Button>
</DialogActions>
</Dialog>
);
}
Example #20
Source File: GeneralSkills.js From resumeker-fe with MIT License | 4 votes |
function GeneralSkills(props) {
const { data } = useQuery(DRAFT_ID);
const [info, setInfo] = useState({
draftID: "",
skill: "",
id: Date.now(),
});
const [activeStep, setActiveStep] = useState(6);
//Instantiate useMutation Hook / Creates tuple with 1st var being actual
//call function, and 2nd destructured variable being return data and tracking
const [addSkill, { loading, error }] = useMutation(ADD_SKILL_MUTATION, {
onCompleted(data) {
console.log(data, "\n Add General Skill Response");
},
});
const classes = useStyles();
const addingData = () => {
if (info.skill.length > 0) {
props.addGeneralSkill(info);
//Apollo useMutation API call to send data to backend
addSkill({
variables: {
input: {
draftID: localStorage.getItem("draftID"),
skillType: "Qualitative",
name: info.skill,
},
},
});
}
};
const nextPage = (event) => {
event.preventDefault();
addingData();
props.setActiveStep((prevActiveStep) => prevActiveStep + 1);
props.history.push("/form/languages");
};
const anotherSkill = (event) => {
event.preventDefault();
addingData();
setInfo({
...info,
skill: "",
id: Date.now(),
});
};
const onChange = (event) => {
event.preventDefault();
setInfo({ ...info, [event.target.name]: event.target.value });
};
const handleDelete = (skillToDelete) => (event) => {
event.preventDefault();
props.removeGeneralSkill(skillToDelete);
setInfo({ ...info });
};
return (
<div>
<Grid container componet="main" className={classes.root}>
<CssBaseline />
<TipsLayout tips={Tip()} />
<Grid item xs={12} sm={8} md={9} component={Paper} elevation={6} square>
<MobileStepper
variant="progress"
steps={8}
position="static"
activeStep={props.activeStep}
className={classes.progress}
/>
<div className={classes.paper}>
<Typography component="h1" variant="h5">
Tell us about some of your other skills that didn't quite make it
into the technical section!
</Typography>
<Typography
color="textSecondary"
component="h5"
variant="subtitle2"
>
(Time Management, Critical Thinking, Teamwork, Problem Solving,
Comunication, etc)
</Typography>
<form
className={classes.form}
onSubmit={anotherSkill}
id="generalSkillsForm"
>
<SingleFieldFormTemplate
onChange={onChange}
info={info.skill}
anotherOne={(e) => anotherSkill(e)}
name="skill"
label="General Skill"
/>
<Grid className={classes.skillContainer}>
<Paper
component="ul"
square="true"
className={classes.chipContainer}
>
<Chip
label="Your Skills:"
className={classes.chip}
color="primary"
/>
{props.resumeData.generalSkills.map((data) => {
return (
<li key={data.id} className="listOfGeneralSkills">
<Chip
label={data.skill}
onDelete={handleDelete(data)}
className={classes.chip}
/>
</li>
);
})}
</Paper>
</Grid>
<Grid className={classes.buttonContainer}>
<Button
type="button"
fullWidth
variant="outlined"
color="primary"
id="previous_techSkills"
className={`${classes.previousButton} singlePageButton`}
onClick={() => {
props.setActiveStep((prevActiveStep) => prevActiveStep - 1);
props.history.push("/form/techskills");
}}
>
Previous Form
</Button>
<Button
type="button"
fullWidth
variant="contained"
color="primary"
id="next_languages"
className={`${classes.nextButton} singlePageButton`}
onClick={(e) => nextPage(e)}
>
Next Form
</Button>
</Grid>
</form>
</div>
</Grid>
</Grid>
<button onClick={() => nextPage()}>Next Page</button>
</div>
);
}
Example #21
Source File: Discussion.js From app with MIT License | 4 votes |
function CommentList({ requestId }) {
const classes = useStyles();
const firestore = useFirestore();
const [retries, setRetries] = useState(0);
const { showError } = useNotifications();
// This is used to trigger the snapshot subscription after confirming that the user
// has permission to access the contact info.
const [query, setQuery] = useState(null);
const [commentDocs, setCommentDocs] = useState([]);
// Because of timing issues, this component will likely get run before the server has applied
// the requested document access resulting in almost a guranteed permission-denied error. So,
// we use this effect to monitor for permission-denied until the change has propagated, at which
// point, we do the actual doc subscription (next useEffect);
useEffect(() => {
async function getData() {
try {
const dataQuery = firestore
.collection(`${REQUESTS_DISCUSSIONS_COLLECTION}`)
.where('requestId', '==', requestId)
.orderBy('createdAt', 'asc');
// Call it once because this will throw the permission exception.
await dataQuery.get();
setQuery(dataQuery); // Setting this will trigger the subscription useEffect.
} catch (err) {
// We only try reloading if insufficient permissions.
if (err.code !== 'permission-denied') {
throw err;
}
if (retries >= 25) {
// setAccessFailed(true);
showError(
'Failed to get contact info access, please try again later.',
);
} else {
window.setTimeout(() => {
setRetries(retries + 1);
}, 1000);
}
}
}
getData();
}, [retries, firestore, requestId, showError]);
// Once the previous useEffect verifies that the user has access then this one does the actual
// document subscription.
useEffect(() => {
if (!query) return undefined;
const unsub = query.onSnapshot((querySnap) => {
setCommentDocs(querySnap.docs);
});
return unsub;
}, [query]);
// const querySnapshot = useFirestoreCollection(
// firestore
// .collection(`${REQUESTS_DISCUSSIONS_COLLECTION}`)
// .where('requestId', '==', requestId)
// .orderBy('createdAt', 'asc'),
// );
if (!commentDocs.length) {
return (
<Box color="text.disabled">
<Typography
variant="body2"
className={classes.noComments}
data-test="no-comments">
No comments yet.
</Typography>
<Divider className={classes.divider} />
</Box>
);
}
return (
<List>
{commentDocs.map(
(docSnap) =>
// When new comment is added locally, the createdAt can be the serverTimestamp() value.
// So, we wait on rendering until any new snapshot has finished writing.
!docSnap.metadata.hasPendingWrites && (
<ListItem
key={docSnap.id}
divider
alignItems="flex-start"
data-test="private-comment">
<ListItemAvatar>
<Avatar>{docSnap.get('author.firstName').slice(0, 1)}</Avatar>
</ListItemAvatar>
<ListItemText
disableTypography
primary={
<Typography variant="subtitle2">
{docSnap.get('author.firstName')} –{' '}
<Typography
variant="body2"
display="inline"
color="textSecondary">
{format(docSnap.get('createdAt').toDate(), 'p - PPPP')}
</Typography>{' '}
{docSnap.get('kind') !== 1 && (
<Chip
variant="outlined"
size="small"
icon={kindMap[docSnap.get('kind')].icon}
label={kindMap[docSnap.get('kind')].shortDescription}
/>
)}
</Typography>
}
secondary={docSnap
.get('content')
.split('\n')
.map((content, key) => (
// eslint-disable-next-line react/no-array-index-key
<Typography variant="body1" key={key} gutterBottom>
{content}
</Typography>
))}
/>
</ListItem>
),
)}
</List>
);
}
Example #22
Source File: MetaColInfo.js From Designer-Client with GNU General Public License v3.0 | 4 votes |
export function MetaColInfo(props) {
const classes = useStyles();
const [col, setCol] = useState({...props.col});
const formHeaders = props.formHeaders;
const getType = (val) => {
switch (val) {
case "varchar":
return "text";
default:
return val;
}
};
const getTypeLength = (type) => {
const parsedType = getType(type);
if (TypeLengthMap[type]) {
return TypeLengthMap[type];
}
return "";
}
const getFormat = (type) => {
switch (type) {
case "datetime":
return "yyyy-MM-dd HH:mm:ss";
case "date":
return "yyyy-MM-dd";
case "time":
return "HH:mm:ss";
default:
return "";
}
}
const isDateType = (type) => {
return ["datetime", "date", "time"].indexOf(type) < 0;
}
const handleChange = (e) => {
const updatedCol = {
...col,
[e.target.name]: e.target.type === "checkbox" ? e.target.checked : e.target.value,
};
setCol(updatedCol);
};
return (
<Accordion>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
aria-controls={`column${col.id} - ${col.columnName}`}
id={`column-${col.id}`}
>
<div className={classes.headerWrap}>
<Typography className={classes.heading}>
{col.columnName}
</Typography>
<div>
{col.type &&
<Chip size="small" label={`Type: ${col.type}`} variant="outlined" />
}
</div>
</div>
</AccordionSummary>
<AccordionDetails className={classes.formWrap}>
<FormControl className={classes.formControl}>
<InputLabel
htmlFor={`meta-${col.id}-input-originName`}
className="label"
>
{formHeaders[0].name}
</InputLabel>
<Input
id={`meta-${col.id}-input-originName`}
className="form"
name="originName"
value={col.originalColumnName}
disabled={true}
/>
</FormControl>
<FormControl className={classes.formControl}>
<InputLabel
htmlFor={`meta-${col.id}-input-columnName`}
className="label"
>
{formHeaders[1].name}
</InputLabel>
<Input
id={`meta-${col.id}-input-columnName`}
className="form"
name="columnName"
value={col.columnName}
onChange={handleChange}
/>
<FormHelperText className="helpText">
{formHeaders[1].tooltip}
</FormHelperText>
</FormControl>
<FormControl className={classes.formControl}>
<InputLabel id={`label-meta-${col.id}-input-type`} className="label">
{formHeaders[2].name}
</InputLabel>
<Select
labelId={`label-meta-${col.id}-input-type`}
id={`meta-${col.id}-input-type`}
name="type"
value={getType(col.type)}
className="form"
onChange={handleChange}
>
<MenuItem value={"int"}>숫자(정수)</MenuItem>
<MenuItem value={"double"}>숫자(부동소수)</MenuItem>
<MenuItem value={"text"}>문자</MenuItem>
<MenuItem value={"datetime"}>날짜(시간포함)</MenuItem>
<MenuItem value={"date"}>날짜(시간 미포함)</MenuItem>
<MenuItem value={"time"}>시간(시간 미포함)</MenuItem>
</Select>
</FormControl>
{isDateType(col.type) ?
<FormControl className={classes.formControl}>
<InputLabel htmlFor={`meta-${col.id}-input-length`} className="label">
{formHeaders[3].name}
</InputLabel>
<Input
id={`meta-${col.id}-input-length`}
value={col.length || getTypeLength(col.type)}
name="length"
className="form"
onChange={handleChange}
/>
</FormControl>
:
<FormControl className={classes.formControl}>
<InputLabel htmlFor={`meta-${col.id}-input-format`} className="label">
{formHeaders[4].name}
</InputLabel>
<Input
id={`meta-${col.id}-input-format`}
value={col.format || getFormat(col.type)}
name="format"
className="form"
onChange={handleChange}
/>
<FormHelperText className="helpText">
{formHeaders[4].tooltip}
</FormHelperText>
</FormControl>
}
<FormControlLabel
className={`${classes.formControl} options`}
control={
<Checkbox
id={`meta-${col.id}-input-nullable`}
checked={col.isNullable}
name="isNullable"
onChange={handleChange}
color="primary"
/>
}
label={
<Typography style={{ fontSize: "0.875rem" }}>빈값 허용</Typography>
}
/>
<FormControlLabel
className={`${classes.formControl} options`}
control={
<Checkbox
id={`meta-${col.id}-input-unique`}
checked={col.isUnique}
name="isUnique"
onChange={handleChange}
color="primary"
/>
}
label={
<Typography style={{ fontSize: "0.875rem" }}>고유값</Typography>
}
/>
<FormControlLabel
className={`${classes.formControl} options`}
control={
<Checkbox
id={`meta-${col.id}-input-hidden`}
checked={col.isHidden}
name="isHidden"
onChange={handleChange}
color="primary"
/>
}
label={
<Typography style={{ fontSize: "0.875rem" }}>숨김(미제공)</Typography>
}
/>
</AccordionDetails>
</Accordion>
)
}
Example #23
Source File: CaptureMatchingView.js From treetracker-admin-client with GNU Affero General Public License v3.0 | 4 votes |
function CaptureMatchingView() {
const initialFilter = {
startDate: '',
endDate: '',
stakeholderUUID: null,
};
const classes = useStyle();
const appContext = useContext(AppContext);
const matchingToolContext = useContext(MatchingToolContext);
const [captureImage, setCaptureImage] = useState(null);
const [currentPage, setCurrentPage] = useState(1);
const [loading, setLoading] = useState(false);
const [candidateImgData, setCandidateImgData] = useState([]);
const [noOfPages, setNoOfPages] = useState(null); //for pagination
const [imgCount, setImgCount] = useState(null); //for header icon
const [treesCount, setTreesCount] = useState(0);
const [startDate, setStartDate] = useState('');
const [endDate, setEndDate] = useState('');
const [organizationId, setOrganizationId] = useState(null);
const [stakeholderUUID, setStakeholderUUID] = useState(null);
const [filter, setFilter] = useState(initialFilter);
const [growerAccount, setGrowerAccount] = useState({});
// To get total tree count on candidate capture image icon
// const treesCount = candidateImgData.length;
const [screenWidth, setScreenWidth] = useState(window.innerWidth);
const resizeWindow = useCallback(() => {
setScreenWidth(window.innerWidth);
}, []);
useEffect(() => {
window.addEventListener('resize', resizeWindow);
return () => {
window.removeEventListener('resize', resizeWindow);
};
}, [resizeWindow]);
async function fetchCandidateTrees(captureId, abortController) {
const data = await api.fetchCandidateTrees(captureId, abortController);
if (data) {
setCandidateImgData(data.matches);
setTreesCount(data.matches.length);
setLoading(false);
}
}
async function clean() {
setCandidateImgData([]);
setTreesCount(0);
setCaptureImage(null);
setTreesCount(0);
setImgCount(null);
// setCurrentPage(1);
// setNoOfPages(null);
}
async function fetchCaptures(currentPage, abortController) {
clean();
setLoading(true);
// log.debug('fetchCaptures filter', filter);
const filterParameters = {
captured_at_start_date: filter.startDate,
captured_at_end_date: filter.endDate,
'organization_ids[]': filter.stakeholderUUID && [filter.stakeholderUUID],
};
// log.debug('fetchCaptures filterParameters', filterParameters);
const data = await api.fetchCapturesToMatch(
currentPage,
abortController,
filterParameters
);
// log.debug('fetchCptures data', currentPage, data);
if (data?.captures?.length > 0) {
setCaptureImage(data.captures[0]);
setNoOfPages(data.count);
setImgCount(data.count);
} else {
setLoading(false);
setNoOfPages(0);
setImgCount(0);
log.warn('no data:', data);
}
}
async function loadGrowerInfo() {
if (captureImage) {
// log.warn('loadGrowerInfo...');
if (captureImage.grower_account_id) {
const data = await api.getGrowerAccountById(
captureImage.grower_account_id
);
setGrowerAccount(data);
} else {
log.warn('No grower account id found');
}
}
}
useEffect(() => {
document.title = `Capture Matching - ${documentTitle}`;
}, []);
useEffect(() => {
const abortController = new AbortController();
fetchCaptures(currentPage, abortController);
return () => abortController.abort();
}, [currentPage, filter]);
useEffect(() => {
if (currentPage <= 0 || currentPage > noOfPages) {
setCurrentPage(1);
}
}, [noOfPages, currentPage]);
useEffect(() => {
const abortController = new AbortController();
if (captureImage) {
const captureId = captureImage.id;
fetchCandidateTrees(captureId, abortController);
// load grower info
loadGrowerInfo();
}
return () => abortController.abort();
}, [captureImage]);
// Capture Image Pagination function
const handleChange = (e, value) => {
setCurrentPage(value);
};
// Same Tree Capture function
const sameTreeHandler = async (treeId) => {
const captureId = captureImage.id;
// log.debug('captureId treeId', captureId, treeId);
await fetch(`${CAPTURE_API}/captures/${captureId}`, {
method: 'PATCH',
headers: {
'content-type': 'application/json',
// Authorization: session.token,
},
body: JSON.stringify({
tree_id: treeId,
}),
});
// make sure new captures are loaded by updating page or if it's the first page reloading directly
if (currentPage === 1) {
fetchCaptures(currentPage);
} else {
setCurrentPage((page) => page + 1);
}
};
// Skip button
const handleSkip = () => {
setCurrentPage((page) => page + 1);
};
function handleStartDateChange(e) {
setStartDate(e.target.value);
}
function handleEndDateChange(e) {
setEndDate(e.target.value);
}
function handleFilterSubmit() {
log.debug('filter submit -----> ', organizationId, stakeholderUUID);
setFilter({
startDate,
endDate,
stakeholderUUID,
});
matchingToolContext.handleFilterToggle();
}
function handleFilterReset() {
setFilter(initialFilter);
matchingToolContext.handleFilterToggle();
}
// components
function currentCaptureNumber(text, icon, count, tooltip) {
return (
<Box>
<Paper elevation={3} className={classes.currentNumberBox1}>
<Box className={classes.currentNumberBox2}>
<Box>
<Box className={classes.currentNumberBox3}>{icon}</Box>
</Box>
<Box>
<Box className={classes.currentNumberBox4}>
<Typography
variant="h6"
className={`${classes.currentNumberText} ${classes.currentNumberBold}`}
>
{count}
</Typography>
{tooltip && (
<Tooltip placement="right-start" title={tooltip}>
<QuestionMarkIcon />
</Tooltip>
)}
</Box>
<Typography variant="body1" className={classes.currentNumberText}>
{text}
</Typography>
</Box>
</Box>
</Paper>
</Box>
);
}
const CaptureHeader = (
<Box>
<Box>
<Grid container className={classes.currentHeaderBox1}>
{currentCaptureNumber(
`Unmatched Capture${(imgCount !== 1 && 's') || ''}`,
<PhotoCameraOutlinedIcon
className={classes.currentHeaderCaptureImgIcon}
/>,
imgCount,
''
)}
<Box className={classes.currentHeaderBox2}>
<Box>
{(filter.startDate || filter.endDate) && (
<Chip
label={`${filter.startDate || 'Start Date'} - ${
filter.endDate || 'End Date'
}`}
className={classes.currentHeaderChip}
onDelete={() =>
setFilter({
...filter,
startDate: undefined,
endDate: undefined,
})
}
/>
)}
{filter.stakeholderUUID && (
<Chip
label={appContext.orgList.reduce((a, c) => {
return c.stakeholder_uuid === filter.stakeholderUUID
? c.name
: a;
}, '')}
className={classes.currentHeaderChip}
onDelete={() =>
setFilter({
...filter,
stakeholderUUID: undefined,
})
}
/>
)}
</Box>
<IconButton
onClick={matchingToolContext.handleFilterToggle}
className={classes.currentHeaderClass1}
>
<FilterListIcon htmlColor="#6E6E6E" />
</IconButton>
<Pagination
count={noOfPages}
page={currentPage}
onChange={handleChange}
defaultPage={1}
size="small"
siblingCount={0}
/>
</Box>
</Grid>
</Box>
</Box>
);
const CaptureImage = (
<Box className={classes.captureImageBox1}>
{CaptureHeader}
<Box height={16} />
{!loading && !captureImage && (
//captureImage && treesCount === 0 && (
<Box>
<Typography variant="h5">No capture found.</Typography>
</Box>
)}
{captureImage && (
<Paper
elevation={4}
key={`capture_${captureImage.id}`}
className={classes.captureImageContainerBox}
>
<Box className={classes.captureImageHeaderBox}>
<Box className={classes.box2}>
<Tooltip title={captureImage.id} interactive>
<Typography variant="h5">
Capture {(captureImage.id + '').substring(0, 10) + '...'}
</Typography>
</Tooltip>
<Box className={classes.captureImageCaptureInfo}>
<Box className={classes.captureImageBox3}>
<AccessTimeIcon />
<Typography variant="body1">
{getDateTimeStringLocale(captureImage.created_at)}
</Typography>
</Box>
<Box className={classes.captureImageBox3}>
<LocationOnOutlinedIcon
style={{
cursor: 'pointer',
}}
onClick={() => {
window.open(
`https://www.google.com/maps/search/?api=1&query=${captureImage.latitude},${captureImage.longitude}`
);
}}
/>
<Typography variant="body1">
<Country
lat={captureImage.latitude}
lon={captureImage.longitude}
/>
</Typography>
</Box>
</Box>
</Box>
{!loading && growerAccount && (
<Box className={classes.growerBox1}>
<Avatar
className={classes.growerAvatar}
src={growerAccount.image_url}
/>
<Box className={classes.growerBox2}>
<Typography variant="h5">
{growerAccount.first_name}
</Typography>
<Typography variant="body1">
Joined at{' '}
{moment(
growerAccount.first_registration_at ||
growerAccount.created_at
).format('MM/DD/YYYY')}
</Typography>
</Box>
</Box>
)}
{loading && <Box>...</Box>}
{!loading && !growerAccount && <Box>no grower info</Box>}
<Button
variant="text"
color="primary"
onClick={handleSkip}
className={classes.captureImageButton}
>
Skip
<SkipNextIcon />
</Button>
</Box>
<Box className={classes.captureImageImgBox}>
<OptimizedImage
key={captureImage.id}
className={classes.captureImageImgContainer}
src={captureImage.image_url}
alt={`Capture ${captureImage.id}`}
objectFit="contain"
width={screenWidth * 0.5}
fixed
alertWidth="100%"
alertHeight="30%"
alertPadding="2rem"
alertTitleSize="1.6rem"
alertTextSize="1rem"
/>
</Box>
</Paper>
)}
</Box>
);
return (
<>
<Grid
container
direction="column"
style={{
flexWrap: 'nowrap',
height: '100%',
overflow: 'hidden',
}}
>
<Navbar />
<Box className={classes.container}>
<Paper elevation={8} className={classes.box1}>
{CaptureImage}
</Paper>
<Box className={classes.box2}>
<Box className={classes.candidateIconBox}>
{currentCaptureNumber(
`Candidate Match${(treesCount !== 1 && 'es') || ''}`,
<NatureOutlinedIcon className={classes.candidateImgIcon} />,
treesCount,
`Any tree within 6m of the capture`
)}
</Box>
<Box height={14} />
{loading ? null : (
<CandidateImages
capture={captureImage}
candidateImgData={candidateImgData}
sameTreeHandler={sameTreeHandler}
/>
)}
{!loading &&
captureImage &&
candidateImgData &&
candidateImgData.length === 0 && (
//captureImage && treesCount === 0 && (
<Box className={classes.noCandidateBox}>
<Typography variant="h5">
No candidate match found, this capture might be a new tree
</Typography>
</Box>
)}
</Box>
</Box>
{loading && (
<AppBar position="fixed" style={{ zIndex: 10000 }}>
<LinearProgress color="primary" />
</AppBar>
)}
</Grid>
<Drawer
anchor="right"
BackdropProps={{ invisible: false }}
open={matchingToolContext.isFilterOpen}
>
<Grid
container
direction="column"
className={classes.customTableFilterForm}
>
{/* start filter header */}
<Grid item className={classes.customTableFilterHeader}>
<Grid container direction="row" justify="space-between">
<Grid item>
<Grid container direction="row">
<Typography variant="h6">Filter</Typography>
</Grid>
</Grid>
<CloseIcon
onClick={matchingToolContext.handleFilterToggle}
className={classes.customTableFilterCloseIcon}
/>
</Grid>
</Grid>
{/* end filter header */}
{/* start filter body */}
<>
<FormControl
variant="outlined"
className={classes.customTableFilterSelectFormControl}
>
<TextField
id="start_date"
name="start_date"
value={startDate}
label="Start Date"
type="date"
onChange={handleStartDateChange}
InputLabelProps={{
shrink: true,
}}
/>
</FormControl>
<FormControl
variant="outlined"
className={classes.customTableFilterSelectFormControl}
>
<TextField
id="end_date"
name="end_date"
label="End Date"
value={endDate}
onChange={handleEndDateChange}
type="date"
InputLabelProps={{
shrink: true,
}}
/>
</FormControl>
</>
<FormControl
variant="outlined"
className={classes.customTableFilterSelectFormControl}
>
<SelectOrg
orgId={organizationId || 'ORGANIZATION_NOT_SET'}
defaultOrgs={[
{
id: 'ORGANIZATION_NOT_SET',
stakeholder_uuid: null,
name: 'Not set',
value: null,
},
]}
handleSelection={(org) => {
setOrganizationId(org.id);
setStakeholderUUID(org.stakeholder_uuid);
}}
/>
</FormControl>
<Divider
style={{
margin: '50px 0 20px 0',
}}
/>
<Grid
container
direction="column"
className={classes.customTableFilterActions}
>
<Button
variant="contained"
color="primary"
disableElevation
className={classes.customTableFilterSubmitButton}
onClick={handleFilterSubmit}
>
APPLY
</Button>
<Button
color="primary"
variant="text"
onClick={handleFilterReset}
className={classes.customTableFilterResetButton}
>
RESET
</Button>
</Grid>
</Grid>
</Drawer>
</>
);
}
Example #24
Source File: EditEvent.jsx From archeage-tools with The Unlicense | 4 votes |
render() {
const { id, open, onClose, mobile, eventTypes } = this.props;
const { formData: { name, icon, eventType, description, link, times, disabled }, avatarSelect, editTime, timeData, error, loading } = this.state;
return (
<Dialog
open={open}
onClose={onClose}
fullScreen={mobile}
>
<AppBar position="static">
<Toolbar variant="dense">
<Typography className="title-text">{id ? 'Edit' : 'New'} Event</Typography>
<IconButton color="inherit" aria-label="Close" onClick={onClose}>
<CloseIcon />
</IconButton>
</Toolbar>
</AppBar>
<DialogContent>
<form autoComplete="off" onSubmit={this.handleSubmit} ref={this.form}>
<div className="event-form">
<div className="avatar-opt">
<Avatar src={icon ? `/images/event/${icon}.png` : null} onClick={this.toggleAvatar} />
<Typography>{icon || 'Select an icon.'}</Typography>
</div>
<TextField
required
id="event-name"
label="Event Name"
value={name || ''}
onChange={(e) => this.handleChange('name', e.target.value)}
/>
<FormControl required>
<InputLabel id="event-type-select">Type</InputLabel>
<Select
labelId="event-type-select"
id="event-type"
value={eventType || ''}
onChange={(e) => this.handleChange('eventType', e.target.value)}
>
{Object.values(eventTypes).map(type => (
<MenuItem
value={type.id}
key={`etype-${type.id}`}
>
{type.name}
</MenuItem>
))}
</Select>
</FormControl>
<TextField
id="event-desc"
label="Description"
value={description || ''}
onChange={(e) => this.handleChange('description', e.target.value)}
multiline
/>
<TextField
id="event-link"
label="Link"
value={link || ''}
onChange={(e) => this.handleChange('link', e.target.value)}
/>
<div>
<FormControlLabel
control={
<Checkbox
checked={disabled || false}
onChange={(_, disabled) => this.handleChange('disabled', disabled)}
name="disabled"
/>}
label="Disabled"
/>
</div>
<div className="times">
<Typography>Times</Typography>
<div className="chips">
{(times || []).map((time, timeId) => (
<Chip
key={`time-${timeId}`}
icon={<Avatar>{time.region || 'GT'}</Avatar>}
label={`${time.time} ${time.days.length > 0 && time.days.length < 7
? time.days.map(day => DAY_ABBR[day]).join('') : ''}`}
onClick={this.editTime(timeId)}
onDelete={this.deleteTime(timeId)}
variant="outlined"
color={editTime === timeId ? 'primary' : 'secondary'}
/>
))}
{editTime === false &&
<IconButton onClick={this.editTime()}>
<AddIcon />
</IconButton>}
</div>
</div>
</div>
</form>
{editTime !== false &&
<Paper elevation={3}>
<form autoComplete="off" onSubmit={this.saveTime} className="time-form">
<Typography>{editTime === true ? 'Add Time' : 'Edit Time'}</Typography>
<FormControl
style={{ width: 75 }}
disabled={Boolean(timeData.gameTime)}
>
<InputLabel id="region-label" shrink>Region</InputLabel>
<Select
labelId="region-label"
id="region"
value={timeData.region || ''}
onChange={(e) => this.handleChangeTime('region', e.target.value)}
>
{[null, ...Object.values(REGIONS)].map(region => (
<MenuItem
value={region}
key={`region-${region}`}
>
{region || 'None'}
</MenuItem>
))}
</Select>
</FormControl>
<TextField
id="start-time"
label="Start Time"
margin="dense"
type="time"
required
value={timeData.time || ''}
onChange={(e) => this.handleChangeTime('time', this.handleTime(e))}
InputLabelProps={{
shrink: true,
}}
inputProps={{
step: 900,
}}
/>
<TextField
id="duration"
label="Duration"
margin="dense"
type="time"
value={timeData.duration || ''}
onChange={(e) => this.handleChangeTime('duration', this.handleTime(e))}
InputLabelProps={{
shrink: true,
}}
inputProps={{
step: 900,
}}
/>
<TextField
id="in-game-time"
label="Game Time?"
margin="dense"
type="time"
value={timeData.gameTime || ''}
onChange={(e) => {
const gameTime = this.handleTime(e);
this.handleChangeTime('gameTime', gameTime, () => {
if (gameTime) {
this.handleChangeTime('region', null);
}
});
}}
InputLabelProps={{
shrink: true,
}}
inputProps={{
step: 900,
}}
/>
<TextField
id="time-name"
label="Name"
margin="dense"
value={timeData.name || ''}
onChange={(e) => this.handleChangeTime('name', e.target.value)}
InputLabelProps={{
shrink: true,
}}
placeholder={`${name || 'Event Name'}: ...`}
/>
<TextField
className="start-message"
id="time-message"
label="Start Message"
margin="dense"
value={timeData.startMessage || ''}
onChange={(e) => this.handleChangeTime('startMessage', e.target.value)}
InputLabelProps={{
shrink: true,
}}
placeholder="Alternate message for when this event starts."
/>
<TextField
id="reminder-time"
label="Reminder Time"
margin="dense"
type="time"
value={timeData.reminderTime || ''}
onChange={(e) => this.handleChangeTime('reminderTime', this.handleTime(e))}
InputLabelProps={{
shrink: true,
}}
inputProps={{
step: 900,
}}
/>
<TextField
className="start-message"
id="time-reminder-message"
label="Reminder Message"
margin="dense"
value={timeData.reminderMessage || ''}
onChange={(e) => this.handleChangeTime('reminderMessage', e.target.value)}
InputLabelProps={{
shrink: true,
}}
placeholder="Alternate message for when this event is starting soon."
/>
<FormControl className="day-select">
<InputLabel id="time-days-label">Days</InputLabel>
<Select
labelId="time-days-label"
id="time-days"
multiple
value={timeData.days || []}
onChange={(e) => this.handleChangeTime('days', e.target.value)}
input={<Input id="select-multiple-chip" />}
renderValue={(selected) => (
<div className="day-chips">
{selected.map((value) => (
<Chip key={value} label={DAY[value]} className="day-chip" />
))}
</div>
)}
>
{Object.entries(DAY).map(([key, name]) => (
<MenuItem key={key} value={key} className="day-item">
{name}
</MenuItem>
))}
</Select>
</FormControl>
<IconButton type="submit"><CheckIcon /></IconButton>
<IconButton onClick={this.editTime(false)}><CloseIcon /></IconButton>
</form>
</Paper>}
<Popover
anchorOrigin={{
vertical: 'top',
horizontal: 'left',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'left',
}}
anchorEl={avatarSelect}
open={Boolean(avatarSelect)}
elevation={2}
onClose={() => this.toggleAvatar()}
>
<div className="avatar-select">
{Object.entries(EventIcon).sort(sortBy(0)).map(([key, url]) => (
<Tooltip title={getIconName(url)} key={key}>
<Avatar
src={url}
onClick={() => {
this.handleChange('icon', getIconName(url));
this.toggleAvatar();
}}
/>
</Tooltip>
))}
</div>
</Popover>
{error &&
<Box color="error.main">
<Typography>{error}</Typography>
</Box>}
<DialogActions>
<Button onClick={onClose}>
Cancel
</Button>
<Button
color="primary"
onClick={() => this.form.current.dispatchEvent(new Event('submit'))}
disabled={loading}
>
Save
</Button>
</DialogActions>
</DialogContent>
</Dialog>
);
}
Example #25
Source File: AnswerForm.js From stack-underflow with MIT License | 4 votes |
AnswerForm = ({ quesId, tags }) => {
const classes = useQuesPageStyles();
const { user } = useAuthContext();
const { clearEdit, notify } = useStateContext();
const { register, handleSubmit, reset, errors } = useForm({
mode: 'onChange',
resolver: yupResolver(validationSchema),
});
const [addAnswer, { loading }] = useMutation(POST_ANSWER, {
onError: (err) => {
notify(getErrorMsg(err), 'error');
},
});
const postAnswer = ({ answerBody }) => {
addAnswer({
variables: { quesId, body: answerBody },
update: (proxy, { data }) => {
reset();
const dataInCache = proxy.readQuery({
query: VIEW_QUESTION,
variables: { quesId },
});
const updatedData = {
...dataInCache.viewQuestion,
answers: data.postAnswer,
};
proxy.writeQuery({
query: VIEW_QUESTION,
variables: { quesId },
data: { viewQuestion: updatedData },
});
notify('Answer submitted!');
},
});
};
return (
<div className={classes.answerForm}>
{user && (
<Typography variant="h6" color="secondary">
Your Answer
</Typography>
)}
{user && (
<form onSubmit={handleSubmit(postAnswer)}>
<TextField
inputRef={register}
name="answerBody"
required
fullWidth
type="text"
placeholder="Enter atleast 30 characters"
variant="outlined"
size="small"
error={'answerBody' in errors}
helperText={'answerBody' in errors ? errors.answerBody.message : ''}
multiline
rows={5}
/>
<div>
<Button
color="primary"
variant="contained"
style={{ marginTop: '0.8em' }}
type="submit"
disabled={loading}
>
Post Your Answer
</Button>
</div>
</form>
)}
<div className={classes.footerText}>
<span>
Browse other questions tagged{' '}
{tags.map((t) => (
<Chip
key={t}
label={t}
variant="outlined"
color="primary"
size="small"
component={RouterLink}
to={`/tags/${t}`}
className={classes.footerTag}
clickable
/>
))}
or{' '}
{user ? (
<Link component={RouterLink} to="/ask" onClick={() => clearEdit()}>
ask your own question.
</Link>
) : (
<AuthFormModal buttonType="link" />
)}
</span>
</div>
</div>
);
}
Example #26
Source File: Card.js From to-view-list with MIT License | 4 votes |
Card = ({ entry }) => {
const {
id,
title,
link,
description,
tags,
type,
isViewed,
isStarred,
createdAt,
updatedAt,
} = entry;
const [{ darkMode }, dispatch] = useEntryContext();
const history = useHistory();
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('xs'));
const classes = useCardStyles(isViewed, darkMode)();
const handleStarToggle = async () => {
try {
dispatch(toggleStarEntry(id));
await entryService.star(id);
notify(
dispatch,
`${isStarred ? 'Un-Starred' : 'Starred'} "${title}"!`,
'success'
);
} catch (err) {
if (err?.response?.data?.error) {
notify(dispatch, `${err.response.data.error}`, 'error');
} else {
notify(dispatch, `${err.message}`, 'error');
}
}
};
const handleViewToggle = async () => {
try {
dispatch(toggleViewEntry(id));
await entryService.view(id);
notify(
dispatch,
`Marked "${title}" as ${isViewed ? 'Not Viewed' : 'Viewed'}!`,
'success'
);
} catch (err) {
if (err?.response?.data?.error) {
notify(dispatch, `${err.response.data.error}`, 'error');
} else {
notify(dispatch, `${err.message}`, 'error');
}
}
};
const handleTagFilter = (tag) => {
dispatch(setTagFilter(tag));
};
const handleEdit = () => {
dispatch(setEditValues(entry));
history.push('/add_update');
};
const handleDelete = async () => {
try {
dispatch(removeEntry(id));
await entryService.remove(id);
notify(dispatch, `Successfully deleted "${title}"!`, 'success');
} catch (err) {
if (err?.response?.data?.error) {
notify(dispatch, `${err.response.data.error}`, 'error');
} else {
notify(dispatch, `${err.message}`, 'error');
}
}
};
const formattedLink = link.startsWith('http') ? link : `https://${link}`;
const iconSize = isMobile ? 'small' : 'large';
const iconStyle = { marginRight: 8 };
return (
<Paper className={classes.root} variant="outlined">
<div className={classes.cardTitle}>
<Typography variant="h5" className={classes.linkTitle}>
{type === 'article' ? (
<WebIcon style={iconStyle} fontSize={iconSize} />
) : type === 'video' ? (
<YouTubeIcon style={iconStyle} fontSize={iconSize} />
) : (
<LineStyleIcon style={iconStyle} fontSize={iconSize} />
)}
{title}
</Typography>
<div className={classes.endButtons}>
{!isMobile ? (
<>
<Button
onClick={handleEdit}
startIcon={<EditIcon />}
className={classes.edit}
>
Edit
</Button>
<DeleteDialog
handleDelete={handleDelete}
title={title}
isMobile={isMobile}
/>
</>
) : (
<>
<IconButton onClick={handleEdit} className={classes.edit}>
<EditIcon />
</IconButton>
<DeleteDialog
handleDelete={handleDelete}
title={title}
isMobile={isMobile}
/>
</>
)}
<FormControlLabel
control={
<Checkbox
checked={isStarred}
icon={<StarBorderIcon className={classes.starIcon} />}
checkedIcon={<StarIcon className={classes.starIcon} />}
className={classes.star}
/>
}
label={isMobile ? '' : isStarred ? 'Starred!' : 'Star it'}
onChange={handleStarToggle}
className={classes.starButton}
/>
<FormControlLabel
control={
<Checkbox
checked={isViewed}
icon={<VisibilityOutlinedIcon className={classes.viewIcon} />}
checkedIcon={<VisibilityIcon className={classes.viewIcon} />}
className={classes.view}
/>
}
label={isMobile ? '' : isViewed ? 'Viewed!' : 'Mark as viewed'}
onChange={handleViewToggle}
className={classes.viewButton}
/>
</div>
</div>
<Divider />
<div>
<Link
href={formattedLink}
target="_blank"
rel="noreferrer"
variant="h6"
color="secondary"
className={classes.link}
>
<LinkIcon style={{ marginRight: 8 }} />
{formattedLink.length > 40
? formattedLink.slice(0, 40) + '...'
: formattedLink}
</Link>
<Typography varaint="body1" className={classes.description}>
{description}
</Typography>
{tags.length !== 0 && (
<div className={classes.tagsGroup}>
Tags:{' '}
{tags.map((tag) => (
<Chip
key={tag}
label={tag}
color="secondary"
className={classes.tag}
onClick={() => handleTagFilter(tag)}
/>
))}
</div>
)}
<Typography variant="body2" className={classes.addedTime}>
<Tooltip title={createdAt}>
<span>
Added:{' '}
<TimeAgo datetime={createdAt} className={classes.timestamp} />
</span>
</Tooltip>
{createdAt !== updatedAt ? (
<Tooltip title={updatedAt}>
<span>
{' '}
| Last modified:{' '}
<TimeAgo
datetime={updatedAt}
className={classes.timestamp}
/>{' '}
</span>
</Tooltip>
) : null}
</Typography>
</div>
</Paper>
);
}
Example #27
Source File: LatestOrders.js From EMP with MIT License | 4 votes |
LatestOrders = () => {
// const classes = useStyles();
const [orders] = useState(data);
return (
<Card>
<CardHeader title="Latest Orders" />
<Divider />
<PerfectScrollbar>
<Box minWidth={800}>
<Table>
<TableHead>
<TableRow>
<TableCell>
Order Ref
</TableCell>
<TableCell>
Customer
</TableCell>
<TableCell sortDirection="desc">
<Tooltip
enterDelay={300}
title="Sort"
>
<TableSortLabel
active
direction="desc"
>
Date
</TableSortLabel>
</Tooltip>
</TableCell>
<TableCell>
Status
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{orders.map((order) => (
<TableRow
hover
key={order.id}
>
<TableCell>
{order.ref}
</TableCell>
<TableCell>
{order.customer.name}
</TableCell>
<TableCell>
{moment(order.createdAt).format('DD/MM/YYYY')}
</TableCell>
<TableCell>
<Chip
color="primary"
label={order.status}
size="small"
/>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Box>
</PerfectScrollbar>
<Box
display="flex"
justifyContent="flex-end"
p={2}
>
<Button
color="primary"
endIcon={<ArrowRightIcon />}
size="small"
variant="text"
>
View all
</Button>
</Box>
</Card>
);
}
Example #28
Source File: SchematicCard.js From eSim-Cloud with GNU General Public License v3.0 | 4 votes |
// Card displaying overview of onCloud saved schematic.
export default function SchematicCard ({ sch }) {
const classes = useStyles()
const dispatch = useDispatch()
useEffect(() => {
dispatch(fetchSchematics())
}, [dispatch])
// To handle delete schematic snackbar
const [snacOpen, setSnacOpen] = React.useState(false)
const handleSnacClick = () => {
setSnacOpen(true)
}
const handleSnacClose = (event, reason) => {
if (reason === 'clickaway') {
return
}
setSnacOpen(false)
}
const clickViewProject = () => {
const win = window.open()
win.location.href = '/eda/#/project?save_id=' + sch.save_id + '&version=' + sch.project_version + '&branch=' + sch.project_branch + '&project_id=' + sch.project_id
win.focus()
}
const clickViewLTI = () => {
const win = window.open()
win.location.href = `/eda/#/lti?id=${sch.save_id}&version=${sch.version}&branch=${sch.branch}`
}
return (
<>
{/* User saved Schematic Overview Card */}
<Card>
<ButtonBase
target="_blank"
component={RouterLink}
to={sch.lti_id ? `/editor?id=${sch.save_id}&version=${sch.version}<i_id=${sch.lti_id}&branch=${sch.branch}` : `/editor?id=${sch.save_id}&version=${sch.version}&branch=${sch.branch}`}
// to={'/editor?id=' + sch.save_id + '&version=' + sch.version + '&branch=' + sch.branch}
style={{ width: '100%' }}
>
<CardActionArea>
<CardHeader
title={sch.name}
subheader={'Created On ' + getDate(sch.create_time)}
action={sch.project_id && sch.is_reported === true && <Tooltip title='Project is reported!' arrow><ReportProblemIcon style={{ color: 'red' }} /></Tooltip>}
/>
<CardMedia
className={classes.media}
image={sch.base64_image}
title={sch.name}
/>
<CardContent>
<Typography variant="body2" component="p">
{sch.description}
</Typography>
{/* Display updated status */}
<Typography variant="body2" color="textSecondary" component="p" style={{ margin: '5px 0px 0px 0px' }}>
</Typography>
</CardContent>
</CardActionArea>
</ButtonBase>
<CardActions>
<Chip color='primary' variant='outlined' label={`Updated ${timeSince(sch.save_time)} ago...`} />
{sch.project_id && <Chip variant='outlined' clickable={true} onClick={clickViewProject} label='Project' />}
{sch.lti_id && <Chip variant='outlined' clickable={true} onClick={clickViewLTI} label='LTI' />}
{/* Display create LTI app option */}
{!sch.lti_id && <Tooltip title='Create LTI app' placement="bottom" arrow>
<IconButton
component={RouterLink}
color='secondary'
// style={{ marginLeft: 'auto' }}
// fontSize="small"
to={`/lti?id=${sch.save_id}&version=${sch.version}&branch=${sch.branch}`} >
<ScreenShareRoundedIcon fontSize="small" />
</IconButton>
</Tooltip>}
{/* Display delete option */}
{!sch.project_id &&
<Button onClick={() => { handleSnacClick() }}>
<Tooltip title="Delete" placement="bottom" arrow>
<DeleteIcon
color="secondary"
fontSize="small"
// style={{ marginLeft: 'auto' }}
/>
</Tooltip>
</Button>}
<SimpleSnackbar open={snacOpen} close={handleSnacClose} sch={sch} confirmation={deleteSchematic} />
{/* Display share status */}
<Tooltip
title={!sch.shared ? 'SHARE OFF' : 'SHARE ON'}
placement="bottom"
arrow
>
<ShareIcon
color={!sch.shared ? 'disabled' : 'primary'}
fontSize="small"
style={{ marginRight: '10px' }}
/>
</Tooltip>
</CardActions>
</Card>
</>
)
}
Example #29
Source File: Projects.js From gitlab-lint-react with BSD 3-Clause "New" or "Revised" License | 4 votes |
Projects = () => {
const classes = useStyles();
const [page, setPage] = useState(1);
const [searchInput, setSearchInput] = useState("");
const handleChange = (event, value) => {
setPage(value);
fetchData({ query: { page: value, q: searchInput } });
};
const debouncedSearch = useCallback(
() => debounce((value) => fetchData({ query: { page, q: value } }), 500),
[page]
);
const handleChangeSearch = (value) => {
setSearchInput(value);
debouncedSearch(value);
};
const [rows, setData] = useState({});
const [meta, setMeta] = useState({});
const fetchData = ({ query }) => {
GitlabLintHttpClient("GET_ALL", { entity: "projects", query: query })
.then((data) => {
setData(data.data);
setMeta(data.meta);
})
.catch((err) => console.error(err));
};
useEffect(() => {
fetchData({ query: { page: 1 } });
}, []);
if (Object.keys(rows).length === 0 && rows.constructor === Object) {
return <Loading />;
}
return (
<React.Fragment>
<div className={classes.header}>
<Typography variant="h4" paragraph>
Projects
</Typography>
<form noValidate autoComplete="off">
<Input
placeholder="Find a project..."
value={searchInput}
onChange={(e) => handleChangeSearch(e.target.value)}
/>
</form>
</div>
<List>
{rows.map((row) => {
return (
<ListItem
button
component={Link}
to={`/projects/${row.id}`}
key={row.id}
>
<ListItemText primary={row.path_with_namespace} />
<div className={classes.levels}>
{Object.keys(row.rules).map((key, index) => {
return (
<Tooltip key={key} title={key} placement="top-start">
<Chip
className={`${classes.level} ${classes[key]}`}
label={row.rules[key]}
size="small"
/>
</Tooltip>
);
})}
</div>
</ListItem>
);
})}
</List>
<div className={classes.pagination}>
<Pagination
boundaryCount={2}
color="primary"
count={meta.totalOfPages}
onChange={handleChange}
page={page}
siblingCount={2}
/>
</div>
</React.Fragment>
);
}