@mui/material#TableRow TypeScript Examples
The following examples show how to use
@mui/material#TableRow.
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: SkeletonComponent.tsx From firecms with MIT License | 6 votes |
function renderArrayOfMaps<M>(properties: Properties<M>, size: PreviewSize, previewProperties?: string[]) {
let tableProperties = previewProperties;
if (!tableProperties || !tableProperties.length) {
tableProperties = Object.keys(properties) as string[];
if (size)
tableProperties = tableProperties.slice(0, 3);
}
return (
<Table size={"small"}>
<TableBody>
{
[0, 1, 2].map((value, index) => {
return (
<TableRow key={`table_${value}_${index}`}>
{tableProperties && tableProperties.map(
(key) => (
<TableCell
key={`table-cell-${key}`}
component="th"
>
<SkeletonComponent
property={(properties as any)[key]}
size={"small"}/>
</TableCell>
)
)}
</TableRow>
);
})}
</TableBody>
</Table>
);
}
Example #2
Source File: header.component.tsx From master-frontend-lemoncode with MIT License | 6 votes |
HeaderComponent: React.FunctionComponent = (props) => {
return (
<TableHead>
<TableRow>
<TableCell className={classes.cell}>ID</TableCell>
<TableCell className={classes.cell}>Name</TableCell>
<TableCell className={classes.cell}>Avatar</TableCell>
</TableRow>
</TableHead>
);
}
Example #3
Source File: row.component.tsx From master-frontend-lemoncode with MIT License | 6 votes |
RowComponent: React.FunctionComponent<Props> = (props) => {
const { member } = props;
return (
<TableRow>
<TableCell>{member.id}</TableCell>
<TableCell>{member.name}</TableCell>
<TableCell>
<img className={classes.image} src={member.imageUrl} />
</TableCell>
</TableRow>
);
}
Example #4
Source File: index.tsx From Search-Next with GNU General Public License v3.0 | 6 votes |
Table: React.FC<TableProps> = (props) => {
const { dataSource, columns, size } = props;
return (
<TableContainer component={Paper}>
<MTable sx={{ minWidth: 650 }} size={size}>
<TableHead>
<TableRow>
{columns.map(({ name, field, align = 'left', ...i }) => (
<StyledTableCell key={field} align={align}>
{name}
</StyledTableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{dataSource.map((row, index) => (
<StyledTableRow
key={row.name}
sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
>
{columns.map(({ name, field, align = 'left', render, ...i }) => (
<StyledTableCell key={field} align={align}>
{render ? render(row[field], row, index) : row[field]}
</StyledTableCell>
))}
</StyledTableRow>
))}
</TableBody>
</MTable>
{dataSource.length === 0 && (
<div className="w-full">
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</div>
)}
</TableContainer>
);
}
Example #5
Source File: index.tsx From Search-Next with GNU General Public License v3.0 | 6 votes |
StyledTableRow = styled(TableRow)(({ theme }) => ({
'&:nth-of-type(odd)': {
backgroundColor: theme.palette.action.hover,
},
// hide last border
'&:last-child td, &:last-child th': {
border: 0,
},
}))
Example #6
Source File: ArrayOfMapsPreview.tsx From firecms with MIT License | 5 votes |
/**
* @category Preview components
*/
export function ArrayOfMapsPreview({
name,
value,
property,
size
}: PreviewComponentProps<object[]>) {
if (property.dataType !== "array" || !property.of || property.of.dataType !== "map")
throw Error("Picked wrong preview component ArrayOfMapsPreview");
const properties = ((property as ArrayProperty).of as MapProperty).properties;
if (!properties) {
throw Error(`You need to specify a 'properties' prop (or specify a custom field) in your map property ${name}`);
}
const values = value;
const previewProperties = ((property as ArrayProperty).of as MapProperty).previewProperties;
if (!values) return null;
let mapProperties = previewProperties;
if (!mapProperties || !mapProperties.length) {
mapProperties = Object.keys(properties);
if (size)
mapProperties = mapProperties.slice(0, 3);
}
return (
<Table size="small">
<TableBody>
{values &&
values.map((v, index) => {
return (
<TableRow key={`table_${v}_${index}`}
sx={{
"&:last-child th, &:last-child td": {
borderBottom: 0
}
}}>
{mapProperties && mapProperties.map(
(key) => (
<TableCell
key={`table-cell-${key as string}`}
component="th"
>
<ErrorBoundary>
<PreviewComponent
name={key as string}
value={(v as any)[key]}
property={properties[key as string]}
size={"small"}/>
</ErrorBoundary>
</TableCell>
)
)}
</TableRow>
);
})}
</TableBody>
</Table>
);
}
Example #7
Source File: SkeletonComponent.tsx From firecms with MIT License | 5 votes |
function renderMap<T extends object>(property: MapProperty<T>, size: PreviewSize) {
if (!property.properties)
return <></>;
let mapProperties: string[];
if (!size) {
mapProperties = Object.keys(property.properties);
} else {
if (property.previewProperties)
mapProperties = property.previewProperties as string[];
else
mapProperties = Object.keys(property.properties).slice(0, 3);
}
if (size)
return (
<List>
{mapProperties && mapProperties.map((key: string) => (
<ListItem key={property.title + key}>
<SkeletonComponent
property={(property.properties as any)[key]}
size={"small"}/>
</ListItem>
))}
</List>
);
return (
<Table size={"small"}>
<TableBody>
{mapProperties &&
mapProperties.map((key, index) => {
return (
<TableRow key={`table_${property.title}_${index}`}
sx={{
"&:last-child th, &:last-child td": {
borderBottom: 0
}
}}>
<TableCell key={`table-cell-title-${key}`}
component="th">
<Skeleton variant="text"/>
</TableCell>
<TableCell key={`table-cell-${key}`} component="th">
<SkeletonComponent
property={(property.properties as any)[key]}
size={"small"}/>
</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
);
}
Example #8
Source File: index.tsx From ExpressLRS-Configurator with GNU General Public License v3.0 | 5 votes |
WifiDeviceSelect: FunctionComponent<WifiDeviceSelectProps> = (props) => {
const { wifiDevices, onChange } = props;
const wifiDevicesSorted = useMemo(() => {
return wifiDevices.sort((a, b) => {
if (a.target === b.target) {
return a.name > b.name ? 1 : -1;
}
return a.target > b.target ? 1 : -1;
});
}, [wifiDevices]);
return (
<Box sx={styles.root}>
<Table>
<TableHead>
<TableRow>
<TableCell>Name</TableCell>
<TableCell>Target</TableCell>
<TableCell>Version</TableCell>
<TableCell>Type</TableCell>
<TableCell>DNS</TableCell>
<TableCell>IP</TableCell>
<TableCell />
</TableRow>
</TableHead>
<TableBody>
{wifiDevicesSorted.map((row) => (
<TableRow key={row.name}>
<TableCell>{row.name}</TableCell>
<TableCell>
{row.deviceName ? row.deviceName : row.target}
</TableCell>
<TableCell>{row.version}</TableCell>
<TableCell>{row.type?.toUpperCase()}</TableCell>
<TableCell>
<a target="_blank" href={`http://${row.dns}`} rel="noreferrer">
{row.dns}
</a>
</TableCell>
<TableCell>
<a target="_blank" href={`http://${row.ip}`} rel="noreferrer">
{row.ip}
</a>
</TableCell>
<TableCell>
<Button
onClick={() => {
onChange(row);
}}
>
Select
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Box>
);
}
Example #9
Source File: ClearingAccountDetail.tsx From abrechnung with GNU Affero General Public License v3.0 | 5 votes |
export default function ClearingAccountDetail({ group, account }) {
const classes = useStyles();
const accounts = useRecoilValue(accountsSeenByUser(group.id));
const balances = useRecoilValue(accountBalances(group.id));
const [showAdvanced, setShowAdvanced] = useState(false);
useEffect(() => {
for (const share of Object.values(account.clearing_shares)) {
if (share !== 1) {
setShowAdvanced(true);
break;
}
}
}, [account]);
const clearingShareValue = (accountID) => {
return account.clearing_shares?.hasOwnProperty(accountID) ? account.clearing_shares[accountID] : 0;
};
return (
<TableContainer>
<Table>
<TableHead>
<TableRow>
<TableCell>Account</TableCell>
{showAdvanced && <TableCell>Shares</TableCell>}
<TableCell width="100px" align="right">
Shared
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{accounts
.filter((a) => balances[account.id].clearingResolution.hasOwnProperty(a.id))
.map((a) => (
<TableRow hover key={a.id}>
<TableCell className={classes.tableLinkCell}>
{/*TODO: proper link*/}
<Link className={classes.tableLink} to={`/groups/${group.id}/accounts/${a.id}`}>
<Grid container direction="row" alignItems="center">
<Grid item>
{a.type === "personal" ? (
<PersonalAccountIcon />
) : (
<ClearingAccountIcon />
)}
</Grid>
<Grid item sx={{ ml: 1 }}>
<Typography variant="body2" component="span">
{a.name}
</Typography>
</Grid>
</Grid>
</Link>
</TableCell>
{showAdvanced && <TableCell width="50px">{clearingShareValue(a.id)}</TableCell>}
<TableCell width="100px" align="right">
{balances[account.id].clearingResolution[a.id].toFixed(2)} {group.currency_symbol}
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
}
Example #10
Source File: PurchaseDebitorShares.tsx From abrechnung with GNU Affero General Public License v3.0 | 5 votes |
function AccountTableRow({
transaction,
account,
showAdvanced,
debitorShareValueForAccount,
showPositions,
positionValueForAccount,
debitorValueForAccount,
updateDebShare,
}) {
const transactionHasPositions =
transaction.positions != null && transaction.positions.find((item) => !item.deleted) !== undefined;
return (
<TableRow hover>
<TableCell>
<Grid container direction="row" alignItems="center">
<Grid item>{account.type === "personal" ? <PersonalAccountIcon /> : <ClearingAccountIcon />}</Grid>
<Grid item sx={{ ml: 1 }}>
<Typography variant="body2" component="span">
{account.name}
</Typography>
</Grid>
</Grid>
</TableCell>
<TableCell width="100px">
{showAdvanced ? (
<ShareInput
onChange={(value) => updateDebShare(account.id, value)}
value={debitorShareValueForAccount(account.id)}
/>
) : (
<Checkbox
name={`${account.name}-checked`}
checked={transaction.debitor_shares.hasOwnProperty(account.id)}
onChange={(event) => updateDebShare(account.id, event.target.checked ? 1.0 : 0)}
/>
)}
</TableCell>
{showPositions || transactionHasPositions ? (
<>
<TableCell align="right">
{positionValueForAccount(account.id).toFixed(2)} {transaction.currency_symbol}
</TableCell>
<TableCell></TableCell>
<TableCell align="right">
{debitorValueForAccount(account.id).toFixed(2)} {transaction.currency_symbol}
</TableCell>
<TableCell></TableCell>
<TableCell width="100px" align="right">
{(debitorValueForAccount(account.id) + positionValueForAccount(account.id)).toFixed(2)}{" "}
{transaction.currency_symbol}
</TableCell>
</>
) : (
<TableCell width="100px" align="right">
{(debitorValueForAccount(account.id) + positionValueForAccount(account.id)).toFixed(2)}{" "}
{transaction.currency_symbol}
</TableCell>
)}
</TableRow>
);
}
Example #11
Source File: Compiler.tsx From sapio-studio with Mozilla Public License 2.0 | 5 votes |
function ShowTaproot(props: taproot_t) {
const paths = props.scripts.flatMap(([[script, depth], paths]) => {
const parsed = Bitcoin.script.decompile(Buffer.from(script, 'hex'));
let asm: string;
if (parsed) asm = Bitcoin.script.toASM(parsed);
else asm = `Unparsable: ${script}`;
return paths.map((path) => {
return (
<TableRow key={`${path}`} className="PathRow">
<TableCell>{depth}</TableCell>
<TableCell>
<code>{asm}</code>
</TableCell>
<TableCell>{path}</TableCell>
</TableRow>
);
});
});
return (
<div>
<Table>
<TableHead>
<TableRow>
<TableCell variant="head">type</TableCell>
<TableCell variant="head">address</TableCell>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell>main</TableCell>
<TableCell>{props.address.main}</TableCell>
</TableRow>
<TableRow>
<TableCell>signet</TableCell>
<TableCell>{props.address.main}</TableCell>
</TableRow>
<TableRow>
<TableCell>regtest</TableCell>
<TableCell>{props.address.regtest}</TableCell>
</TableRow>
<TableRow>
<TableCell>testnet</TableCell>
<TableCell>{props.address.test}</TableCell>
</TableRow>
</TableBody>
</Table>
<Table className="TapPaths">
<TableHead>
<TableRow>
<TableCell variant="head"> Script </TableCell>
<TableCell variant="head"> Depth </TableCell>
<TableCell variant="head"> Path</TableCell>
</TableRow>
</TableHead>
<TableBody>{paths}</TableBody>
</Table>
</div>
);
}
Example #12
Source File: EnhancedTableHead.tsx From yearn-watch-legacy with GNU Affero General Public License v3.0 | 5 votes |
EnhancedTableHead = <T extends GenericListItem>( props: EnhancedTableProps<T> ) => { const { classes, order, orderBy, onRequestSort, shouldCollapse = false, } = props; const createSortHandler = (property: keyof GenericListItem) => (event: React.MouseEvent<unknown>) => { onRequestSort(event, property); }; const collapseCell = shouldCollapse ? ( <TableCell key="collapse" align="center" padding="normal"> Details </TableCell> ) : ( '' ); return ( <TableHead> <TableRow> {collapseCell} {props.headCells.map((headCell, index) => ( <TableCell key={`header-${index}`} align={headCell.align} padding={headCell.disablePadding ? 'none' : 'normal'} sortDirection={orderBy === headCell.id ? order : false} > <> <TableSortLabel active={orderBy === headCell.id} direction={ orderBy === headCell.id ? order : 'asc' } onClick={ headCell.id ? createSortHandler(headCell.id) : undefined } > {headCell.label} {orderBy === headCell.id ? ( <span className={classes.visuallyHidden}> {order === 'desc' ? 'sorted descending' : 'sorted ascending'} </span> ) : null} </TableSortLabel> {headCell.tooltip ? ( <Tooltip title={headCell.tooltip}> <HelpOutlineRounded fontSize="small" /> </Tooltip> ) : ( '' )} </> </TableCell> ))} </TableRow> </TableHead> ); }
Example #13
Source File: DonationTable.tsx From frontend with MIT License | 4 votes |
function DonationTable({ donations }: DonationTableProps) {
const { t, i18n } = useTranslation()
const [fromDate, setFromDate] = React.useState<Date | null>(null)
const [toDate, setToDate] = React.useState<Date | null>(null)
const [monthly, setMonthly] = React.useState(true)
const [oneTime, setOneTime] = React.useState(true)
const filteredByTypeDonations = useMemo(() => {
if (monthly && oneTime) {
return donations
}
if (!monthly && !oneTime) {
return []
}
if (monthly) {
return donations?.filter((d) => d.type !== 'donation')
}
if (oneTime) {
return donations?.filter((d) => d.type === 'donation')
}
return donations
}, [donations, monthly, oneTime])
const filteredDonations = useMemo(() => {
if (!fromDate && !toDate) {
return filteredByTypeDonations
}
if (fromDate && toDate) {
return filteredByTypeDonations?.filter((d) => {
const createdAtDate = parseISO(d.createdAt)
return isAfter(createdAtDate, fromDate) && isBefore(createdAtDate, toDate)
})
}
if (fromDate) {
return filteredByTypeDonations?.filter((d) => {
const createdAtDate = parseISO(d.createdAt)
return isAfter(createdAtDate, fromDate)
})
}
if (toDate) {
return filteredByTypeDonations?.filter((d) => {
const createdAtDate = parseISO(d.createdAt)
return isBefore(createdAtDate, toDate)
})
}
}, [filteredByTypeDonations, fromDate, toDate])
return (
<Card sx={{ padding: theme.spacing(2) }}>
<Grid container alignItems={'flex-start'} spacing={theme.spacing(2)}>
<Grid item xs={6} sm={3}>
<CheckboxLabel>{t('profile:donations.oneTime')}</CheckboxLabel>
<Checkbox
onChange={(e, checked) => setOneTime(checked)}
checked={oneTime}
name="oneTime"
/>
</Grid>
<Grid item xs={6} sm={3}>
<CheckboxLabel>{t('profile:donations.monthly')}</CheckboxLabel>
<Checkbox
onChange={(e, checked) => setMonthly(checked)}
checked={monthly}
name="monthly"
/>
</Grid>
<LocalizationProvider
locale={i18n.language === 'bg' ? bg : enUS}
dateAdapter={AdapterDateFns}>
<Grid item xs={12} sm={3}>
<DatePicker
label={t('profile:donations.fromDate')}
value={fromDate}
onChange={setFromDate}
renderInput={(params) => <TextField size="small" {...params} />}
/>
</Grid>
<Grid item xs={12} sm={3}>
<DatePicker
label={t('profile:donations.toDate')}
value={toDate}
onChange={setToDate}
renderInput={(params) => <TextField size="small" {...params} />}
/>
</Grid>
</LocalizationProvider>
</Grid>
{filteredDonations?.length ? (
<TableContainer>
<Table sx={{ minWidth: 650, backgroundColor: 'white' }} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>№</TableCell>
<TableCell>{t('profile:donations.date')}</TableCell>
<TableCell>{t('profile:donations.type')}</TableCell>
<TableCell>{t('profile:donations.cause')}</TableCell>
<TableCell>{t('profile:donations.amount')}</TableCell>
<TableCell>{t('profile:donations.certificate')}</TableCell>
</TableRow>
</TableHead>
<TableBody>
{filteredDonations.map((donation, index) => (
<TableRow key={index} sx={{ '&:last-child td, &:last-child th': { border: 0 } }}>
<TableCell component="th" scope="row">
{index + 1}
</TableCell>
<TableCell>
{format(parseISO(donation.createdAt), 'd.LL.yyyy', {
locale: i18n.language === 'bg' ? bg : enUS,
})}
</TableCell>
<TableCell>
<Avatar sx={{ background: darken(theme.palette.secondary.main, 0.175) }}>
<StarIcon />
</Avatar>
</TableCell>
<TableCell>{donation.targetVault.campaign.title}</TableCell>
<TableCell>{money(donation.amount)}</TableCell>
<TableCell>
<Button variant="outlined" disabled={donation.status != 'succeeded'}>
<Link target="_blank" href={routes.donation.viewCertificate(donation.id)}>
{t('profile:donations.download')} <ArrowForwardIcon />
</Link>
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
) : (
<Box sx={{ fontSize: 20, mt: 4 }}>Към момента няма направени дарения</Box>
)}
</Card>
)
}
Example #14
Source File: index.tsx From yearn-watch-legacy with GNU Affero General Public License v3.0 | 4 votes |
ScoreRowCollapse = (props: ScoreRowCollapseProps) => {
const { item, index } = props;
const classes = useStyles();
const TVLImpact = (
<>
{parseInt(item.tvlImpact.toString())}
<TVLImpactTooltip value={parseInt(item.tvlImpact.toString())} />
</>
);
const audit = (
<>
{parseInt(item.auditScore.toString())}
<AuditScoreTooltip value={parseInt(item.auditScore.toString())} />
</>
);
const codeReview = (
<>
{parseInt(item.codeReviewScore.toString())}
<CodeReviewTooltip
value={parseInt(item.codeReviewScore.toString())}
/>
</>
);
const complexity = (
<>
{parseInt(item.complexityScore.toString())}
<ComplexityTooltip
value={parseInt(item.complexityScore.toString())}
/>
</>
);
const protocolSafety = (
<>
{parseInt(item.protocolSafetyScore.toString())}
<ProtocolSafetyTooltip
value={parseInt(item.protocolSafetyScore.toString())}
/>
</>
);
const teamknowledge = (
<>
{parseInt(item.teamKnowledgeScore.toString())}
<TeamKnowledgeTooltip
value={parseInt(item.teamKnowledgeScore.toString())}
/>
</>
);
const testValue = (
<>
{parseInt(item.testingScore.toString())}
<TestTooltip value={parseInt(item.testingScore.toString())} />
</>
);
const longevityValue = (
<>
{parseInt(item.longevityScore.toString())}
<LongevityTooltip
value={parseInt(item.longevityScore.toString())}
/>
</>
);
const data = [
{
key: 'TVL Impact:',
value: item.tvlImpact.toString(),
renderValue: (
<TableRow key={index}>
<TableCell>
{'TVL Impact:'}
<MediaQuery query="(max-device-width: 1224px)">
{TVLImpact}
</MediaQuery>
</TableCell>
<MediaQuery query="(min-device-width: 1224px)">
<TableCell>{TVLImpact}</TableCell>
</MediaQuery>
</TableRow>
),
},
{
key: 'Audit Score:',
value: item.auditScore.toString(),
renderValue: (
<TableRow key={index}>
<TableCell>
{'Audit Score:'}
<MediaQuery query="(max-device-width: 1224px)">
{audit}
</MediaQuery>
</TableCell>
<MediaQuery query="(min-device-width: 1224px)">
<TableCell>{audit}</TableCell>
</MediaQuery>
</TableRow>
),
},
{
key: 'Code Review Score:',
value: item.codeReviewScore.toString(),
renderValue: (
<TableRow key={index}>
<TableCell>
{'Code Review Score:'}
<MediaQuery query="(max-device-width: 1224px)">
{codeReview}
</MediaQuery>
</TableCell>
<MediaQuery query="(min-device-width: 1224px)">
<TableCell>{codeReview}</TableCell>
</MediaQuery>
</TableRow>
),
},
{
key: 'Complexity Score:',
value: item.complexityScore.toString(),
renderValue: (
<TableRow key={index}>
<TableCell>
{'Complexity Score:'}
<MediaQuery query="(max-device-width: 1224px)">
{complexity}
</MediaQuery>
</TableCell>
<MediaQuery query="(min-device-width: 1224px)">
<TableCell>{complexity}</TableCell>
</MediaQuery>
</TableRow>
),
},
{
key: 'Longevity Score:',
value: item.longevityScore.toString(),
renderValue: (
<TableRow key={index}>
<TableCell>
{'Longevity Score:'}
<MediaQuery query="(max-device-width: 1224px)">
{longevityValue}
</MediaQuery>
</TableCell>
<MediaQuery query="(min-device-width: 1224px)">
<TableCell>{longevityValue}</TableCell>
</MediaQuery>
</TableRow>
),
},
{
key: 'Protocol Safety Score:',
value: item.protocolSafetyScore.toString(),
renderValue: (
<TableRow key={index}>
<TableCell>
{'Protocol Safety Score:'}
<MediaQuery query="(max-device-width: 1224px)">
{protocolSafety}
</MediaQuery>
</TableCell>
<MediaQuery query="(min-device-width: 1224px)">
<TableCell>{protocolSafety}</TableCell>
</MediaQuery>
</TableRow>
),
},
{
key: 'Team Knowledge Score:',
value: item.teamKnowledgeScore.toString(),
renderValue: (
<TableRow key={index}>
<TableCell>
{'Team Knowledge Score:'}
<MediaQuery query="(max-device-width: 1224px)">
{teamknowledge}
</MediaQuery>
</TableCell>
<MediaQuery query="(min-device-width: 1224px)">
<TableCell>{teamknowledge}</TableCell>
</MediaQuery>
</TableRow>
),
},
{
key: 'Testing Score:',
value: item.testingScore.toString(),
renderValue: (
<TableRow key={index}>
<TableCell>
{'Testing Score:'}
<MediaQuery query="(max-device-width: 1224px)">
{testValue}
</MediaQuery>
</TableCell>
<MediaQuery query="(min-device-width: 1224px)">
<TableCell>{testValue}</TableCell>
</MediaQuery>
</TableRow>
),
},
];
const label = item.label.toString().toUpperCase();
return (
<Grid container className={classes.root} spacing={1}>
<Grid item xs={12}>
<Grid container justifyContent="center" spacing={1}>
<Grid key={`${index}-1`} item xs={8}>
<Paper className={classes.paper}>
<CardContent data={data} />
</Paper>
</Grid>
<Grid key={`${index}-2`} item xs={4}>
<Paper className={classes.paper}>
<SpiderWeb
title={`${label} Group Scores`}
seriesTitle={`${label}`}
values={data.map((keyValue) => ({
label: keyValue.key,
value: parseFloat(keyValue.value),
}))}
/>
</Paper>
</Grid>
</Grid>
</Grid>
</Grid>
);
}
Example #15
Source File: Compiler.tsx From sapio-studio with Mozilla Public License 2.0 | 4 votes |
function CompInput(props: { miniscript: Compiler }) {
type ResultT = ['err', string, string] | ['ok', string, string];
const [compiled, set_compiled] = React.useState<ResultT[]>([]);
const [keytab_string, set_keytab_string] = React.useState<string>('');
const updated = (
event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>
) => {
// some unicode thing
const ret: ResultT[] = event.target.value
.split(UNICODE_LINE)
.flatMap((v: string): ResultT[] => {
if (v.match(UNICODE_LINE)) return [];
try {
/// TODO: Cache based on V
const s = props.miniscript.compile(v);
return [['ok', v, s]];
} catch (e) {
if (typeof e === 'string') return [['err', v, e]];
else throw e;
}
});
set_compiled(ret);
};
const keytab_updated = (
event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>
) => {
set_keytab_string(event.target.value);
};
const [taproot, set_taproot] = React.useState<taproot_t | null>(null);
React.useEffect(() => {
// some unicode thing
const k = props.miniscript.KeyTab.new();
const ret = keytab_string.split(UNICODE_LINE).forEach((v: string) => {
if (v.match(UNICODE_LINE)) return [];
if (v === '') return [];
const nick_key = v.split(':', 2);
if (nick_key.length !== 2) return []; //throw new Error(`Malformed Keytab Entry: ${v}`);
k.add(nick_key[0]!.trim(), nick_key[1]!.trim());
});
const frags = props.miniscript.Fragments.new();
for (const frag of compiled) {
// eslint-disable-next-line no-constant-condition
if (frag[0] === 'err') {
set_taproot(null);
console.log(frag);
return;
}
frags.add(frag[2]);
}
try {
const compiled = props.miniscript.taproot(frags, k);
set_taproot(JSON.parse(compiled));
} catch (e) {
set_taproot(null);
console.log(e);
}
}, [keytab_string, compiled]);
return (
<Box className="MiniscriptCompiler">
<h1>Input</h1>
<TextareaAutosize
onChange={updated}
minRows={3}
style={{ width: '50%' }}
/>
<Table>
<TableHead>
<TableRow>
<TableCell variant="head">Input</TableCell>
<TableCell variant="head">{'=>'}</TableCell>
<TableCell variant="head">Output</TableCell>
</TableRow>
</TableHead>
<TableBody>
{compiled.map((row, i) => (
<TableRow key={`${row[1]}#${i}`}>
<TableCell
style={{
whiteSpace: 'pre-wrap',
wordBreak: 'break-word',
}}
>
<Typography
className="CompilerOutput"
component="code"
>
{row[1]}
</Typography>
</TableCell>
<TableCell> {'=>'} </TableCell>
<TableCell>
<Typography
style={{
whiteSpace: 'pre-wrap',
wordBreak: 'break-word',
}}
className="CompilerOutput"
component="code"
>
{row[2]}
</Typography>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
<h1>Translate Keys</h1>
<TextareaAutosize
onChange={keytab_updated}
minRows={3}
style={{ width: '50%' }}
/>
<div>{taproot && <ShowTaproot {...taproot}></ShowTaproot>}</div>
</Box>
);
}
Example #16
Source File: index.tsx From wallet-adapter with Apache License 2.0 | 4 votes |
Index: NextPage = () => {
const { autoConnect, setAutoConnect } = useAutoConnect();
return (
<Table>
<TableHead>
<TableRow>
<TableCell width={240}>Component</TableCell>
<TableCell width={240}>Material UI</TableCell>
<TableCell width={240}>Ant Design</TableCell>
<TableCell width={240}>React UI</TableCell>
<TableCell>Example v{pkg.version}</TableCell>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell>Connect Button</TableCell>
<TableCell>
<MaterialUIWalletConnectButton />
</TableCell>
<TableCell>
<AntDesignWalletConnectButton />
</TableCell>
<TableCell>
<ReactUIWalletConnectButton />
</TableCell>
<TableCell></TableCell>
</TableRow>
<TableRow>
<TableCell>Disconnect Button</TableCell>
<TableCell>
<MaterialUIWalletDisconnectButton />
</TableCell>
<TableCell>
<AntDesignWalletDisconnectButton />
</TableCell>
<TableCell>
<ReactUIWalletDisconnectButton />
</TableCell>
<TableCell></TableCell>
</TableRow>
<TableRow>
<TableCell>Dialog/Modal Button</TableCell>
<TableCell>
<MaterialUIWalletDialogButton />
</TableCell>
<TableCell>
<AntDesignWalletModalButton />
</TableCell>
<TableCell>
<ReactUIWalletModalButton />
</TableCell>
<TableCell></TableCell>
</TableRow>
<TableRow>
<TableCell>Multi Button</TableCell>
<TableCell>
<MaterialUIWalletMultiButton />
</TableCell>
<TableCell>
<AntDesignWalletMultiButton />
</TableCell>
<TableCell>
<ReactUIWalletMultiButton />
</TableCell>
<TableCell></TableCell>
</TableRow>
<TableRow>
<TableCell></TableCell>
<TableCell>
<Tooltip title="Only runs if the wallet is ready to connect" placement="left">
<FormControlLabel
control={
<Switch
name="autoConnect"
color="secondary"
checked={autoConnect}
onChange={(event, checked) => setAutoConnect(checked)}
/>
}
label="AutoConnect"
/>
</Tooltip>
</TableCell>
<TableCell>
<RequestAirdrop />
</TableCell>
<TableCell>
<SendTransaction />
</TableCell>
<TableCell>
<SignMessage />
</TableCell>
</TableRow>
</TableBody>
</Table>
);
}
Example #17
Source File: ItemRow.tsx From yearn-watch-legacy with GNU Affero General Public License v3.0 | 4 votes |
ItemRow = <T extends GenericListItem>(props: ItemRowProps<T>) => { const [open, setOpen] = useState(false); const { item, index, headCells } = props; const labelId = `enhanced-table-checkbox-${index}`; const shouldCollapse = props.collapse !== undefined; const itemRow = headCells.map((headCell, headIndex) => { const itemRowKey = `${labelId}-${headIndex}`; const itemIdValue = headCell.id ? item[headCell.id] : ''; const position = { rowNumber: index + 1, columnNumber: headIndex + 1, }; const cellStyle = headCell.getStyle ? headCell.getStyle(item, position) : undefined; return ( <TableCell component="th" id={labelId} scope="row" padding="normal" key={itemRowKey} align={headCell.align} style={cellStyle} > {headCell.format ? headCell.format(item, itemIdValue, position) : itemIdValue} </TableCell> ); }); const collapseButton = shouldCollapse ? ( <TableCell component="th" id={`collapse-${index}`} scope="row" padding="normal" key={`collapse-${index}`} align="center" > <IconButton aria-label="expand row" size="small" onClick={() => setOpen(!open)} > {open ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />} </IconButton> </TableCell> ) : ( '' ); const collapseRow = shouldCollapse ? ( <TableRow> <TableCell style={{ paddingBottom: 0, paddingTop: 0 }} colSpan={headCells.length} > <Collapse in={open} timeout="auto" unmountOnExit> <Box margin={1}> {props.collapse ? props.collapse(index, item) : ''} </Box> </Collapse> </TableCell> </TableRow> ) : ( '' ); return ( <> <TableRow hover role="checkbox" tabIndex={-1} key={item.key} style={ props.getRowStyle ? props.getRowStyle(index, item) : undefined } > {collapseButton} {itemRow} </TableRow> {collapseRow} </> ); }
Example #18
Source File: index.tsx From yearn-watch-legacy with GNU Affero General Public License v3.0 | 4 votes |
GenericList = <T extends GenericListItem>( props: GenericListProps<T> ) => { const { defaultRowsPerPage = 10, defaultOrder = 'asc', defaultOrderBy = 'id', } = props; const classes = useStyles(); const [order, setOrder] = React.useState<Order>(defaultOrder); const [orderBy, setOrderBy] = React.useState<keyof GenericListItem>(defaultOrderBy); const [page, setPage] = React.useState(0); const [rowsPerPage, setRowsPerPage] = React.useState(defaultRowsPerPage); const { items, title, headCells, displayPagination = true } = props; const shouldCollapse = props.collapse !== undefined; const handleRequestSort = ( event: React.MouseEvent<unknown>, property: keyof GenericListItem ) => { const isAsc = orderBy === property && order === 'asc'; setOrder(isAsc ? 'desc' : 'asc'); setOrderBy(property); }; const handleChangePage = (event: unknown, newPage: number) => { setPage(newPage); }; const handleChangeRowsPerPage = ( event: React.ChangeEvent<HTMLInputElement> ) => { setRowsPerPage(parseInt(event.target.value, 10)); setPage(0); }; const emptyRows = rowsPerPage - Math.min(rowsPerPage, items.length - page * rowsPerPage); return ( <div className={classes.root}> <Paper className={classes.paper}> <EnhancedTableToolbar title={title} /> <TableContainer> <Table className={classes.table} aria-labelledby="tableTitle" size="small" aria-label="enhanced table" > <EnhancedTableHead classes={classes} order={order} orderBy={orderBy.toString()} headCells={props.headCells} onRequestSort={handleRequestSort} shouldCollapse={shouldCollapse} /> <TableBody> {stableSort(items, getComparator(order, orderBy)) .slice( page * rowsPerPage, page * rowsPerPage + rowsPerPage ) .map((row, index) => { const labelId = `enhanced-table-checkbox-${index}`; return ( <ItemRow headCells={headCells} item={row} index={index} key={labelId} collapse={props.collapse} getRowStyle={props.getRowStyle} /> ); })} {emptyRows > 0 && ( <TableRow style={{ height: 33 * emptyRows, }} > <TableCell colSpan={6} /> </TableRow> )} </TableBody> </Table> </TableContainer> {displayPagination ? ( <TablePagination rowsPerPageOptions={[5, 10, 20, 40, 60, 75, 100]} component="div" count={items.length} rowsPerPage={rowsPerPage} page={page} onPageChange={handleChangePage} onRowsPerPageChange={handleChangeRowsPerPage} /> ) : ( '' )} </Paper> </div> ); }
Example #19
Source File: EntityPreview.tsx From firecms with MIT License | 4 votes |
/**
* Use this component to render a preview of a property values
* @param entity
* @param schema
* @param path
* @constructor
* @category Components
*/
export function EntityPreview<M>(
{
entity,
schema: inputSchema,
path
}: EntityPreviewProps<M>) {
const classes = useStyles();
const appConfig: FireCMSContext | undefined = useFireCMSContext();
const schema: ResolvedEntitySchema<M> = useMemo(() => computeSchema({
schemaOrResolver: inputSchema,
path,
entityId: entity.id,
values: entity?.values,
previousValues: entity?.values
}), [inputSchema, path, entity]);
const properties: Properties = schema.properties;
return (
<TableContainer>
<Table aria-label="entity table">
<TableBody>
<TableRow>
<TableCell align="right"
component="td"
scope="row"
className={classes.titleCell}>
<Typography variant={"caption"}
color={"textSecondary"}>
Id
</Typography>
</TableCell>
<TableCell padding="none"
className={classes.iconCell}>
{getIdIcon("disabled", "small")}
</TableCell>
<TableCell className={classes.valuePreview}>
<Box display="flex" alignItems="center">
{entity.id}
{appConfig?.entityLinkBuilder &&
<a href={appConfig.entityLinkBuilder({ entity })}
rel="noopener noreferrer"
target="_blank">
<IconButton
aria-label="go-to-entity-datasource"
size="large">
<OpenInNewIcon
fontSize={"small"}/>
</IconButton>
</a>}
</Box>
</TableCell>
</TableRow>
{schema && Object.entries(properties)
.map(([key, property]) => {
const value = (entity.values as any)[key];
return (
<TableRow
key={"entity_prev" + property.title + key}>
<TableCell align="right"
component="td"
scope="row"
className={classes.titleCell}>
<Typography
style={{ paddingLeft: "16px" }}
variant={"caption"}
color={"textSecondary"}>
{property.title}
</Typography>
</TableCell>
<TableCell padding="none"
className={classes.iconCell}>
{getIconForProperty(property, "disabled", "small")}
</TableCell>
<TableCell
className={classes.valuePreview}>
<ErrorBoundary>
<PreviewComponent
name={key}
value={value}
property={property as AnyProperty}
size={"regular"}/>
</ErrorBoundary>
</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</TableContainer>
);
}
Example #20
Source File: CertificatesTab.tsx From frontend with MIT License | 4 votes |
export default function CertificatesTab() {
const { data = { donations: [], total: 0 } } = useUserDonations()
const [fromDate, setFromDate] = React.useState(new Date())
const [toDate, setToDate] = React.useState(new Date())
return (
<Root>
<Box className={classes.boxTitle}>
<Typography className={classes.h3}>История на сертификати</Typography>
</Box>
<ProfileTab name={ProfileTabs.certificates}>
<Box>
<Box sx={{ mt: 4 }}>
<h3 className={classes.thinFont}>Онлайн дарения</h3>
</Box>
<Box
sx={{
display: 'flex',
alignItems: 'baseline',
justifyContent: 'space-between',
mt: 2,
}}>
<span className={classes.smallText}>Покажи:</span>
<Box>
<Checkbox defaultChecked />
<span className={classes.smallText}>еднократни</span>
</Box>
<Box>
<Checkbox defaultChecked />
<span className={classes.smallText}>месечни</span>
</Box>
<LocalizationProvider dateAdapter={AdapterDateFns}>
<span className={classes.smallText}>от дата</span>
<DesktopDatePicker
label="от дата"
inputFormat="MM/dd/yyyy"
value={fromDate}
onChange={(date) => setFromDate(date as Date)}
renderInput={(params) => <TextField {...params} />}
/>
<span className={classes.smallText}>до дата</span>
<DesktopDatePicker
label="до дата"
inputFormat="MM/dd/yyyy"
value={toDate}
onChange={(date) => setToDate(date as Date)}
renderInput={(params) => <TextField {...params} />}
/>
</LocalizationProvider>
</Box>
{data.donations.length ? (
<TableContainer>
<Table sx={{ minWidth: 650, backgroundColor: 'white' }} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>№</TableCell>
<TableCell>Дата</TableCell>
<TableCell>Вид</TableCell>
<TableCell>Кауза</TableCell>
<TableCell>стойност</TableCell>
<TableCell>сертификат</TableCell>
</TableRow>
</TableHead>
<TableBody>
{data.donations.map((donation, index) => (
<TableRow
key={index}
sx={{ '&:last-child td, &:last-child th': { border: 0 } }}>
<TableCell component="th" scope="row">
{index + 1}
</TableCell>
<TableCell>{formatDateString(donation.createdAt)}</TableCell>
<TableCell>
<Avatar sx={{ background: '#F6992B' }}>
<StarIcon />
</Avatar>
</TableCell>
<TableCell>{donation.targetVault.campaign.title}</TableCell>
<TableCell>
{donation.amount} {donation.currency}
</TableCell>
<TableCell>
<Button variant="outlined">
Свали <ArrowForwardIcon />
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
) : (
<Box sx={{ fontSize: 20, mt: 4 }}>Към момента няма направени дарения</Box>
)}
</Box>
</ProfileTab>
</Root>
)
}
Example #21
Source File: Worlds.tsx From NekoMaid with MIT License | 4 votes |
Worlds: React.FC = () => {
const plugin = usePlugin()
const globalData = useGlobalData()
const [worlds, setWorlds] = useState<World[]>([])
const [selected, setSelected] = useState('')
const [open, setOpen] = useState(false)
const update = () => plugin.emit('worlds:fetch', (data: World[]) => {
setWorlds(data)
if (data.length) setSelected(old => data.some(it => it.id === old) ? old : '')
})
useEffect(() => {
const offUpdate = plugin.on('worlds:update', update)
update()
return () => { offUpdate() }
}, [])
const sw = worlds.find(it => it.id === selected)
const getSwitch = (name: string, configId = name) => sw
? <ListItem
secondaryAction={<Switch disabled={!globalData.hasMultiverse} checked={(sw as any)[name]}
onChange={e => {
plugin.emit('worlds:set', sw.id, configId, e.target.checked.toString())
success()
}}
/>}><ListItemText primary={(lang.worlds as any)[name]} /></ListItem>
: null
return <Box sx={{ minHeight: '100%', py: 3 }}>
<Toolbar />
<Container maxWidth={false}>
<Grid container spacing={3}>
<Grid item lg={8} md={12} xl={9} xs={12}>
<Card>
<CardHeader title={lang.worlds.title} />
<Divider />
<Box sx={{ position: 'relative' }}>
<TableContainer>
<Table>
<TableHead>
<TableRow>
<TableCell padding='checkbox' />
<TableCell>{lang.worlds.name}</TableCell>
{globalData.hasMultiverse && <TableCell>{lang.worlds.alias}</TableCell>}
<TableCell>{lang.worlds.players}</TableCell>
<TableCell>{lang.worlds.chunks}</TableCell>
<TableCell>{lang.worlds.entities}</TableCell>
<TableCell>{lang.worlds.tiles}</TableCell>
<TableCell>{lang.worlds.time}</TableCell>
<TableCell>{lang.worlds.weather}</TableCell>
</TableRow>
</TableHead>
<TableBody>
{worlds.map(it => <TableRow key={it.id}>
<TableCell padding='checkbox'><Checkbox checked={selected === it.id} onClick={() => setSelected(it.id)} /></TableCell>
<TableCell><Tooltip title={it.id}><span>{it.name}</span></Tooltip></TableCell>
{globalData.hasMultiverse && <TableCell>{it.alias}
<IconButton size='small' onClick={() => dialog(lang.inputValue, lang.worlds.alias).then(res => {
if (res == null) return
plugin.emit('worlds:set', it.id, 'alias', res)
success()
})}><Edit fontSize='small' /></IconButton>
</TableCell>}
<TableCell>{it.players}</TableCell>
<TableCell>{it.chunks}</TableCell>
<TableCell>{it.entities}</TableCell>
<TableCell>{it.tiles}</TableCell>
<TableCell><Countdown time={it.time} max={24000} interval={50} /></TableCell>
<TableCell><IconButton size='small' onClick={() => {
plugin.emit('worlds:weather', it.id)
success()
}}>
{React.createElement((it.weather === 1 ? WeatherRainy : it.weather === 2 ? WeatherLightningRainy : WbSunny) as any)}
</IconButton></TableCell>
</TableRow>)}
</TableBody>
</Table>
</TableContainer>
</Box>
</Card>
</Grid>
<Grid item lg={4} md={6} xl={3} xs={12}>
<Card>
<CardHeader
title={lang.operations}
sx={{ position: 'relative' }}
action={<Tooltip title={lang.worlds.save} placement='left'>
<IconButton
size='small'
onClick={() => {
if (!sw) return
plugin.emit('worlds:save', sw.id)
success()
}}
sx={cardActionStyles}
><Save /></IconButton>
</Tooltip>}
/>
<Divider />
<Box sx={{ position: 'relative' }}>
{sw
? <List sx={{ width: '100%' }} component='nav'>
<ListItem secondaryAction={<ToggleButtonGroup
exclusive
color='primary'
size='small'
value={sw.difficulty}
onChange={(_, value) => {
plugin.emit('worlds:difficulty', sw.id, value)
success()
}}
>
{difficulties.map(it => <ToggleButton value={it.toUpperCase()} key={it}>{minecraft['options.difficulty.' + it]}</ToggleButton>)}
</ToggleButtonGroup>}><ListItemText primary={minecraft['options.difficulty']} /></ListItem>
<ListItem secondaryAction={<Switch checked={sw.pvp} onChange={e => {
plugin.emit('worlds:pvp', sw.id, e.target.checked)
success()
}} />}><ListItemText primary='PVP' /></ListItem>
{getSwitch('allowAnimals', 'spawning.animals.spawn')}
{getSwitch('allowMonsters', 'spawning.monsters.spawn')}
{globalData.hasMultiverse && <>
{getSwitch('allowFlight')}
{getSwitch('autoHeal')}
{getSwitch('hunger')}
</>}
<ListItem secondaryAction={globalData.canSetViewDistance
? <IconButton
onClick={() => dialog({
content: lang.inputValue,
input: {
error: true,
type: 'number',
helperText: lang.invalidValue,
validator: (it: string) => /^\d+$/.test(it) && +it > 1 && +it < 33
}
}).then(res => {
if (!res) return
plugin.emit('worlds:viewDistance', sw.id, parseInt(res as any))
success()
})}
><Edit /></IconButton>
: undefined}>
<ListItemText primary={lang.worlds.viewDistance + ': ' + sw.viewDistance} />
</ListItem>
<ListItem><ListItemText primary={minecraft['selectWorld.enterSeed']} secondary={sw.seed} /></ListItem>
<ListItemButton onClick={() => setOpen(!open)}>
<ListItemText primary={minecraft['selectWorld.gameRules']} />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse in={open} timeout="auto" unmountOnExit>
<List component='div' dense disablePadding>
{sw.rules.map(([key, value]) => {
const isTrue = value === 'true'
const isBoolean = isTrue || value === 'false'
const isNumber = /^\d+$/.test(value)
return <ListItem
key={key}
sx={{ pl: 4 }}
secondaryAction={isBoolean
? <Switch
checked={isTrue}
onChange={e => {
plugin.emit('worlds:rule', sw.id, key, e.target.checked.toString())
success()
}}
/>
: <IconButton
onClick={() => dialog({
content: lang.inputValue,
input: isNumber
? {
error: true,
type: 'number',
helperText: lang.invalidValue,
validator: (it: string) => /^\d+$/.test(it)
}
: { }
}).then(res => {
if (res == null) return
plugin.emit('worlds:rule', sw.id, key, res)
success()
})}
><Edit /></IconButton>}
>
<ListItemText primary={(minecraft['gamerule.' + key] || key) + (isBoolean ? '' : ': ' + value)} />
</ListItem>
})}
</List>
</Collapse>
</List>
: <CardContent><Empty /></CardContent>
}
</Box>
</Card>
</Grid>
</Grid>
</Container>
</Box>
}
Example #22
Source File: Plugins.tsx From NekoMaid with MIT License | 4 votes |
Plugins: React.FC = () => {
const plugin = usePlugin()
const theme = useTheme()
const { canLoadPlugin } = useGlobalData()
const [plugins, setPlugins] = useState<Plugin[]>([])
useEffect(() => {
const offList = plugin.on('plugins:list', (plugins: Plugin[]) => {
const arr: Plugin[] = []
setPlugins(plugins.filter(it => {
const res = canPluginBeDisabled(it.name)
if (res) arr.push(it)
return !res
}).concat(arr))
})
plugin.emit('plugins:fetch')
return () => {
offList()
}
}, [])
const map: Record<string, number> = { }
let id = 0
const data = plugins.map(it => {
map[it.name] = id
return { id: id++, name: it.name, category: 1 - (it.enabled as any) }
})
const links: Array<{ source: number, target: number }> = []
plugins.forEach(it => {
const source = map[it.name]
it.depends.forEach(dep => {
if (!(dep in map)) {
map[dep] = id
data.push({ id: id++, name: dep, category: 3 })
}
links.push({ source, target: map[dep] })
})
it.softDepends.forEach(dep => {
if (!(dep in map)) {
map[dep] = id
data.push({ id: id++, name: dep, category: 2 })
}
links.push({ source, target: map[dep] })
})
})
return <Box sx={{ minHeight: '100%', py: 3 }}>
<Toolbar />
<Container maxWidth={false}>
<Grid container spacing={3}>
<Grid item xs={12}>
<Card>
<CardHeader title={lang.plugins.title} />
<Divider />
<TableContainer>
<Table>
<TableHead>
<TableRow>
<TableCell sx={{ paddingRight: 0 }}>{lang.plugins.enable}</TableCell>
<TableCell>{lang.plugins.name}</TableCell>
<TableCell>{lang.plugins.version}</TableCell>
<TableCell>{lang.plugins.author}</TableCell>
<TableCell>{lang.plugins.description}</TableCell>
<TableCell align='right'>{lang.operations}</TableCell>
</TableRow>
</TableHead>
<TableBody>
{plugins.map(it => {
const canBeDisabled = canPluginBeDisabled(it.name)
const disabledForever = it.file.endsWith('.disabled')
return <TableRow key={it.name}>
<TableCell padding='checkbox'>
<Checkbox
color='primary'
checked={it.enabled}
disabled={disabledForever || canBeDisabled}
onChange={() => plugin.emit('plugins:enable', it.file, it.name, action)
} />
</TableCell>
<TableCell><Tooltip title={it.file}><span>{it.name}</span></Tooltip></TableCell>
<TableCell>{it.website
? <Link underline='hover' rel='noopener' target='_blank' href={it.website}>{it.version}</Link>
: it.version
}</TableCell>
<TableCell>{it.author}</TableCell>
<TableCell>{it.description}</TableCell>
<TableCell align='right' sx={{ whiteSpace: 'nowrap' }}>
<Tooltip title={lang.plugins[disabledForever ? 'enablePlugin' : 'disableForever']}><span>
<IconButton
disabled={it.enabled || (it.loaded && !canLoadPlugin)}
onClick={() => plugin.emit('plugins:disableForever', it.file, action)}
>{disabledForever ? <LockOpen /> : <Lock />}</IconButton>
</span></Tooltip>
{disabledForever && <Tooltip title={lang.plugins.delete}><span>
<IconButton
color='error'
disabled={canBeDisabled}
onClick={() => dialog({
okButton: { color: 'error' },
content: <>{lang.plugins.confirmDelete(<span className='bold'>{it.file.replace(/\.disabled$/, '')}</span>)}
<span className='bold' style={{ color: theme.palette.error.main }}>({lang.unrecoverable})</span></>
}).then(res => res && plugin.emit('plugins:delete', it.file, action))}
><DeleteForever /></IconButton>
</span></Tooltip>}
</TableCell>
</TableRow>
})}
</TableBody>
</Table>
</TableContainer>
</Card>
</Grid>
<Grid item xs={12}>
<Card>
<CardHeader title={lang.plugins.dependency} />
<Divider />
<ReactECharts style={{ marginTop: theme.spacing(1), height: 450 }} theme={theme.palette.mode === 'dark' ? 'dark' : undefined} option={{
backgroundColor: 'rgba(0, 0, 0, 0)',
legend: { data: lang.plugins.categories },
series: [
{
edgeSymbol: ['none', 'arrow'],
symbolSize: 13,
type: 'graph',
layout: 'force',
data,
links,
categories: lang.plugins.categories.map(name => ({ name, base: name })),
roam: true,
label: {
show: true,
position: 'right',
formatter: '{b}'
},
labelLayout: {
hideOverlap: true
}
}
]
}} />
</Card>
</Grid>
</Grid>
</Container>
</Box>
}
Example #23
Source File: PlayerList.tsx From NekoMaid with MIT License | 4 votes |
Players: React.FC = () => {
const his = useHistory()
const plugin = usePlugin()
const [page, setPage] = useState(0)
const [loading, setLoading] = useState(true)
const [state, setState] = useState<number | null>(null)
const [activedPlayer, setActivedPlayer] = useState<PlayerData | null>(null)
const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(null)
const [data, setData] = useState<{ count: number, players: PlayerData[] }>(() => ({ count: 0, players: [] }))
const globalData = useGlobalData()
const { hasWhitelist } = globalData
const refresh = () => {
setLoading(true)
plugin.emit('playerList:fetchPage', (it: any) => {
if (it.players == null) it.players = []
setData(it)
setLoading(false)
}, page, state === 1 || state === 2 ? state : 0, null)
}
useMemo(refresh, [page, state])
const close = () => {
setAnchorEl(null)
setActivedPlayer(null)
}
return <Card>
<CardHeader
title={lang.playerList.title}
action={
<ToggleButtonGroup
size='small'
color={(state === 1 ? 'warning' : state === 2 ? 'error' : undefined) as any}
value={state}
exclusive
onChange={(_, it) => {
if (it === 3) return
setState(it)
if (state === 3) refresh()
}}
>
<ToggleButton disabled={loading} value={1}><Star /></ToggleButton>
<ToggleButton disabled={loading} value={2}><Block /></ToggleButton>
<ToggleButton disabled={loading} value={3} onClick={() => state !== 3 && dialog(lang.playerList.nameToSearch, lang.username)
.then(filter => {
if (filter == null) return
his.push('/NekoMaid/playerList/' + filter)
setState(3)
setLoading(true)
plugin.emit('playerList:fetchPage', (it: any) => {
if (it.players == null) it.players = []
setPage(0)
setData(it)
setLoading(false)
}, page, 0, filter.toLowerCase())
})}><Search /></ToggleButton>
</ToggleButtonGroup>
}
/>
<Divider />
<Box sx={{ position: 'relative' }}>
<CircularLoading loading={loading} />
<TableContainer>
<Table>
<TableHead>
<TableRow>
<TableCell padding='checkbox' />
<TableCell>{lang.username}</TableCell>
<TableCell align='right'>{minecraft['stat.minecraft.play_time']}</TableCell>
<TableCell align='right'>{lang.playerList.lastPlay}</TableCell>
<TableCell align='right'>{lang.operations}</TableCell>
</TableRow>
</TableHead>
<TableBody>
{data.players.map(it => <TableRow key={it.name}>
<TableCell sx={{ cursor: 'pointer', padding: theme => theme.spacing(1, 1, 1, 2) }} onClick={() => his.push('/NekoMaid/playerList/' + it.name)}>
<Avatar src={getSkin(globalData, it.name, true)} imgProps={{ crossOrigin: 'anonymous', style: { width: 40, height: 40 } }} variant='rounded' />
</TableCell>
<TableCell>{it.name}</TableCell>
<TableCell align='right'>{dayjs.duration(it.playTime / 20, 'seconds').humanize()}</TableCell>
<TableCell align='right'>{dayjs(it.lastOnline).fromNow()}</TableCell>
<TableCell align='right'>
{(state === 1 || hasWhitelist) && <Tooltip title={lang.playerList[it.whitelisted ? 'clickToRemoveWhitelist' : 'clickToAddWhitelist']}>
<IconButton onClick={() => whitelist(it.name, plugin, refresh, !it.whitelisted)}>
{it.whitelisted ? <Star color='warning' /> : <StarBorder />}
</IconButton>
</Tooltip>}
<Tooltip title={it.ban == null ? lang.playerList.clickToBan : lang.playerList.banned + ': ' + it.ban}>
<IconButton onClick={() => banPlayer(it.name, plugin, refresh, it.ban == null)}>
<Block color={it.ban == null ? undefined : 'error'} />
</IconButton>
</Tooltip>
{actions.length
? <IconButton onClick={e => {
setActivedPlayer(anchorEl ? null : it)
setAnchorEl(anchorEl ? null : e.currentTarget)
}}><MoreHoriz /></IconButton>
: null}
</TableCell>
</TableRow>)}
</TableBody>
</Table>
</TableContainer>
<TablePagination
rowsPerPageOptions={[]}
component='div'
count={data.count}
rowsPerPage={10}
page={page}
onPageChange={(_, it) => !loading && setPage(it)}
/>
</Box>
<Menu
anchorEl={anchorEl}
open={Boolean(anchorEl)}
onClose={() => setAnchorEl(null)}
>{actions.map((It, i) => <It key={i} onClose={close} player={activedPlayer} />)}</Menu>
</Card>
}
Example #24
Source File: ObjectMetaData.tsx From console with GNU Affero General Public License v3.0 | 4 votes |
ObjectMetaData = ({
bucketName,
internalPaths,
classes,
actualInfo,
linear = false,
}: IObjectMetadata) => {
const [metaData, setMetaData] = useState<any>({});
const onMetaDataSuccess = (res: MetadataResponse) => {
let metadata = get(res, "objectMetadata", {});
setMetaData(metadata);
};
const onMetaDataError = (err: ErrorResponseHandler) => false;
const [, invokeMetaDataApi] = useApi(onMetaDataSuccess, onMetaDataError);
const metaKeys = Object.keys(metaData);
const loadMetaData = useCallback(() => {
invokeMetaDataApi(
"GET",
`/api/v1/buckets/${bucketName}/objects/metadata?prefix=${internalPaths}`
);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [bucketName, internalPaths, actualInfo]);
useEffect(() => {
if (actualInfo) {
loadMetaData();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [actualInfo, loadMetaData]);
if (linear) {
return (
<Fragment>
{metaKeys.map((element: string, index: number) => {
const renderItem = Array.isArray(metaData[element])
? metaData[element].map(decodeURIComponent).join(", ")
: decodeURIComponent(metaData[element]);
return (
<Box
className={classes.metadataLinear}
key={`box-meta-${element}-${index.toString()}`}
>
<strong>{element}</strong>
<br />
{renderItem}
</Box>
);
})}
</Fragment>
);
}
return (
<Grid container>
<Grid
item
xs={12}
sx={{
marginTop: "25px",
marginBottom: "5px",
}}
>
<h3
style={{
marginTop: "0",
marginBottom: "0",
}}
>
Object Metadata
</h3>
</Grid>
<Grid item xs={12}>
<Table className={classes.table} aria-label="simple table">
<TableBody>
{metaKeys.map((element: string, index: number) => {
const renderItem = Array.isArray(metaData[element])
? metaData[element].map(decodeURIComponent).join(", ")
: decodeURIComponent(metaData[element]);
return (
<TableRow key={`tRow-${index.toString()}`}>
<TableCell
component="th"
scope="row"
className={classes.titleItem}
>
{element}
</TableCell>
<TableCell align="right">{renderItem}</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</Grid>
</Grid>
);
}
Example #25
Source File: TransactionPositions.tsx From abrechnung with GNU Affero General Public License v3.0 | 4 votes |
export default function TransactionPositions({ group, transaction }: PropTypes) {
const classes = useStyles();
const accounts = useRecoilValue(accountsSeenByUser(group.id));
const [localPositionChanges, setLocalPositionChanges] = useRecoilState(
pendingTransactionPositionChanges(transaction.id)
);
const [showAdvanced, setShowAdvanced] = useState(false);
const [positions, setPositions] = useState([]);
useEffect(() => {
setPositions(
transaction.positions
.map((p) => ({ ...p, is_empty: false }))
.concat([
{
...localPositionChanges.empty,
is_empty: true,
},
])
);
}, [transaction, setPositions, localPositionChanges]);
// find all accounts that take part in the transaction, either via debitor shares or purchase items
// TODO: should we add creditor accounts as well?
const positionAccounts: Array<number> = Array.from(
new Set<number>(
positions
.map((item) => Object.keys(item.usages))
.flat()
.map((id) => parseInt(id))
)
);
const [additionalPurchaseItemAccounts, setAdditionalPurchaseItemAccounts] = useState([]);
const transactionAccounts: Array<number> = Array.from(
new Set<number>(
Object.keys(transaction.debitor_shares)
.map((id) => parseInt(id))
.concat(positionAccounts)
.concat(additionalPurchaseItemAccounts)
)
);
const showAddAccount = transactionAccounts.length < accounts.length;
const [showAccountSelect, setShowAccountSelect] = useState(false);
const totalPositionValue = positions.reduce((acc, curr) => acc + curr.price, 0);
const sharedTransactionValue = transaction.value - totalPositionValue;
const purchaseItemSumForAccount = (accountID) => {
return transaction.account_balances.hasOwnProperty(accountID)
? transaction.account_balances[accountID].positions
: 0;
};
const updatePosition = (position, name, price, communistShares) => {
if (position.is_empty) {
return updateEmptyPosition(position, name, price, communistShares);
}
if (position.only_local) {
setLocalPositionChanges((currPositions) => {
let mappedAdded = { ...currPositions.added };
mappedAdded[position.id] = {
...position,
name: name,
price: price,
communist_shares: communistShares,
};
return {
modified: currPositions.modified,
added: mappedAdded,
empty: currPositions.empty,
};
});
} else {
setLocalPositionChanges((currPositions) => {
let mappedModified = { ...currPositions.modified };
mappedModified[position.id] = {
...position,
name: name,
price: price,
communist_shares: communistShares,
};
return {
modified: mappedModified,
empty: currPositions.empty,
added: currPositions.added,
};
});
}
};
const updatePositionUsage = (position, accountID, shares) => {
if (position.is_empty) {
return updateEmptyPositionUsage(position, accountID, shares);
}
if (position.only_local) {
setLocalPositionChanges((currPositions) => {
let mappedAdded = { ...currPositions.added };
let usages = { ...currPositions.added[position.id].usages };
if (shares === 0) {
delete usages[accountID];
} else {
usages[accountID] = shares;
}
mappedAdded[position.id] = {
...currPositions.added[position.id],
usages: usages,
};
return {
modified: currPositions.modified,
added: mappedAdded,
empty: currPositions.empty,
};
});
} else {
setLocalPositionChanges((currPositions) => {
let mappedModified = { ...currPositions.modified };
let usages;
if (mappedModified.hasOwnProperty(position.id)) {
// we already did change something locally
usages = { ...currPositions.modified[position.id].usages };
} else {
// we first need to copy
usages = { ...position.usages };
}
if (shares === 0) {
delete usages[accountID];
} else {
usages[accountID] = shares;
}
mappedModified[position.id] = {
...position,
...currPositions.modified[position.id],
usages: usages,
};
return {
modified: mappedModified,
added: currPositions.added,
empty: currPositions.empty,
};
});
}
};
const deletePosition = (position) => {
if (position.is_empty) {
return resetEmptyPosition();
}
if (position.only_local) {
setLocalPositionChanges((currPositions) => {
let mappedAdded = { ...currPositions.added };
delete mappedAdded[position.id];
return {
modified: currPositions.modified,
added: mappedAdded,
empty: currPositions.empty,
};
});
} else {
setLocalPositionChanges((currPositions) => {
let mappedModified = { ...currPositions.modified };
mappedModified[position.id] = {
...position,
deleted: true,
};
return {
modified: mappedModified,
added: currPositions.added,
empty: currPositions.empty,
};
});
}
};
const nextEmptyPositionID = (localPositions: LocalPositionChanges) => {
return Math.min(...Object.values(localPositions.added).map((p) => p.id), -1, localPositions.empty.id) - 1;
};
const resetEmptyPosition = () => {
setLocalPositionChanges((currValue) => ({
modified: currValue.modified,
added: currValue.added,
empty: {
id: nextEmptyPositionID(currValue),
name: "",
price: 0,
communist_shares: 0,
usages: {},
deleted: false,
},
}));
};
const updateEmptyPosition = (position, name, price, communistShares) => {
if (name !== "" && name != null) {
const copyOfEmpty = { ...position, name: name, price: price, communist_shares: communistShares };
setLocalPositionChanges((currPositions) => {
let mappedAdded = { ...currPositions.added };
mappedAdded[position.id] = copyOfEmpty;
return {
modified: currPositions.modified,
added: mappedAdded,
empty: {
id: nextEmptyPositionID(currPositions),
name: "",
price: 0,
communist_shares: 0,
usages: {},
deleted: false,
},
};
});
} else {
setLocalPositionChanges((currPositions) => {
return {
modified: currPositions.modified,
added: currPositions.added,
empty: {
...position,
name: name,
price: price,
communist_shares: communistShares,
},
};
});
}
};
const updateEmptyPositionUsage = (position, accountID, value) => {
setLocalPositionChanges((currPositions) => {
let newUsages = { ...position.usages };
if (value === 0) {
delete newUsages[accountID];
} else {
newUsages[accountID] = value;
}
return {
modified: currPositions.modified,
added: currPositions.added,
empty: {
...position,
usages: newUsages,
},
};
});
};
const copyPosition = (position) => {
setLocalPositionChanges((currPositions) => {
const newPosition = {
...position,
id: nextEmptyPositionID(currPositions),
};
let mappedAdded = { ...currPositions.added };
mappedAdded[newPosition.id] = newPosition;
return {
modified: currPositions.modified,
added: mappedAdded,
empty: currPositions.empty,
};
});
};
const addPurchaseItemAccount = (account) => {
setShowAccountSelect(false);
setAdditionalPurchaseItemAccounts((currAdditionalAccounts) =>
Array.from(new Set<number>([...currAdditionalAccounts, parseInt(account.id)]))
);
};
return (
<MobilePaper sx={{ marginTop: 2 }}>
<Grid container direction="row" justifyContent="space-between">
<Typography>Positions</Typography>
{transaction.is_wip && (
<FormControlLabel
control={<Checkbox name={`show-advanced`} />}
checked={showAdvanced}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => setShowAdvanced(event.target.checked)}
label="Advanced"
/>
)}
</Grid>
<TableContainer>
<Table className={classes.table} stickyHeader aria-label="purchase items" size="small">
<TableHead>
<TableRow>
<TableCell>Name</TableCell>
<TableCell align="right">Price</TableCell>
{(transaction.is_wip ? transactionAccounts : positionAccounts).map((accountID) => (
<TableCell align="right" sx={{ minWidth: 80 }} key={accountID}>
{accounts.find((account) => account.id === accountID).name}
</TableCell>
))}
{transaction.is_wip && (
<>
{showAccountSelect && (
<TableCell align="right">
<AccountSelect
group={group}
exclude={transactionAccounts}
onChange={addPurchaseItemAccount}
/>
</TableCell>
)}
{showAddAccount && (
<TableCell align="right">
<IconButton onClick={() => setShowAccountSelect(true)}>
<Add />
</IconButton>
</TableCell>
)}
</>
)}
<TableCell align="right">Shared</TableCell>
{transaction.is_wip && <TableCell></TableCell>}
</TableRow>
</TableHead>
<TableBody>
{transaction.is_wip
? positions.map((position, idx) => (
<TableRow hover key={position.id}>
<PositionTableRow
position={position}
deletePosition={deletePosition}
transactionAccounts={transactionAccounts}
copyPosition={copyPosition}
updatePosition={updatePosition}
updatePositionUsage={updatePositionUsage}
showAdvanced={showAdvanced}
showAccountSelect={showAccountSelect}
showAddAccount={showAddAccount}
/>
</TableRow>
))
: positions.map(
(position) =>
!position.is_empty && (
<TableRow hover key={position.id}>
<TableCell>{position.name}</TableCell>
<TableCell align="right" style={{ minWidth: 80 }}>
{position.price.toFixed(2)} {transaction.currency_symbol}
</TableCell>
{positionAccounts.map((accountID) => (
<TableCell align="right" key={accountID}>
{position.usages.hasOwnProperty(String(accountID))
? position.usages[String(accountID)]
: 0}
</TableCell>
))}
<TableCell align="right">{position.communist_shares}</TableCell>
</TableRow>
)
)}
<TableRow hover>
<TableCell>
<Typography sx={{ fontWeight: "bold" }}>Total:</Typography>
</TableCell>
<TableCell align="right">
{totalPositionValue.toFixed(2)} {transaction.currency_symbol}
</TableCell>
{(transaction.is_wip ? transactionAccounts : positionAccounts).map((accountID) => (
<TableCell align="right" key={accountID}>
{purchaseItemSumForAccount(accountID).toFixed(2)} {transaction.currency_symbol}
</TableCell>
))}
<TableCell align="right" colSpan={showAddAccount ? 2 : 1}>
{(
positions.reduce((acc, curr) => acc + curr.price, 0) -
Object.values(transaction.account_balances).reduce(
(acc, curr) => acc + curr.positions,
0
)
).toFixed(2)}{" "}
{transaction.currency_symbol}
</TableCell>
{transaction.is_wip && <TableCell></TableCell>}
</TableRow>
<TableRow hover>
<TableCell>
<Typography sx={{ fontWeight: "bold" }}>Remaining:</Typography>
</TableCell>
<TableCell align="right">
{sharedTransactionValue.toFixed(2)} {transaction.currency_symbol}
</TableCell>
{(transaction.is_wip ? transactionAccounts : positionAccounts).map((accountID) => (
<TableCell align="right" key={accountID}></TableCell>
))}
<TableCell align="right" colSpan={showAddAccount ? 2 : 1}></TableCell>
{transaction.is_wip && <TableCell></TableCell>}
</TableRow>
</TableBody>
</Table>
</TableContainer>
</MobilePaper>
);
}
Example #26
Source File: PurchaseDebitorSharesReadOnly.tsx From abrechnung with GNU Affero General Public License v3.0 | 4 votes |
export default function PurchaseDebitorSharesReadOnly({ group, transaction }) {
const classes = useStyles();
const accounts = useRecoilValue(accountsSeenByUser(group.id));
const [debitorShareValues, setDebitorShareValues] = useState({});
const [showAdvanced, setShowAdvanced] = useState(false);
const transactionHasPositions =
transaction.positions != null && transaction.positions.find((item) => !item.deleted) !== undefined;
useEffect(() => {
setDebitorShareValues(transaction.debitor_shares);
for (const share of Object.values(transaction.debitor_shares)) {
if (share !== 1) {
setShowAdvanced(true);
break;
}
}
}, [transaction]);
const debitorShareValueForAccount = (accountID) => {
return debitorShareValues.hasOwnProperty(accountID) ? debitorShareValues[accountID] : 0;
};
return (
<List>
<ListItem className={classes.listItem}>
<Grid container direction="row" justifyContent="space-between">
<Typography variant="subtitle1" className={classes.checkboxLabel}>
<Box sx={{ display: "flex", alignItems: "flex-end" }}>For whom</Box>
</Typography>
</Grid>
</ListItem>
<Divider variant="middle" className={classes.divider} />
<TableContainer>
<Table>
<TableHead>
<TableRow>
<TableCell>Account</TableCell>
{showAdvanced && <TableCell>Shares</TableCell>}
{transactionHasPositions ? (
<>
<TableCell width="100px" align="right">
Positions
</TableCell>
<TableCell width="3px" align="center">
+
</TableCell>
<TableCell width="100px" align="right">
Shared Rest
</TableCell>
<TableCell width="3px" align="center">
=
</TableCell>
<TableCell width="100px" align="right">
Total
</TableCell>
</>
) : (
<TableCell width="100px" align="right">
Shared
</TableCell>
)}
</TableRow>
</TableHead>
<TableBody>
{accounts
.filter(
(account) =>
transaction.account_balances.hasOwnProperty(account.id) &&
(transaction.account_balances[account.id].common_debitors !== 0 ||
transaction.account_balances[account.id].positions)
)
.map((account) => (
<TableRow hover key={account.id}>
<TableCell className={classes.tableLinkCell}>
{/*TODO: proper link*/}
<Link
className={classes.tableLink}
to={`/groups/${group.id}/accounts/${account.id}`}
>
<Grid container direction="row" alignItems="center">
<Grid item>
{account.type === "personal" ? (
<PersonalAccountIcon />
) : (
<ClearingAccountIcon />
)}
</Grid>
<Grid item sx={{ ml: 1 }}>
<Typography variant="body2" component="span">
{account.name}
</Typography>
</Grid>
</Grid>
</Link>
</TableCell>
{showAdvanced && (
<TableCell width="50px">{debitorShareValueForAccount(account.id)}</TableCell>
)}
{transactionHasPositions ? (
<>
<TableCell align="right">
{transaction.account_balances[account.id].positions.toFixed(2)}{" "}
{transaction.currency_symbol}
</TableCell>
<TableCell></TableCell>
<TableCell align="right">
{transaction.account_balances[account.id].common_debitors.toFixed(2)}{" "}
{transaction.currency_symbol}
</TableCell>
<TableCell></TableCell>
<TableCell width="100px" align="right">
{(
transaction.account_balances[account.id].common_debitors +
transaction.account_balances[account.id].positions
).toFixed(2)}{" "}
{transaction.currency_symbol}
</TableCell>
</>
) : (
<TableCell width="100px" align="right">
{transaction.account_balances[account.id].common_debitors.toFixed(2)}{" "}
{transaction.currency_symbol}
</TableCell>
)}
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</List>
);
}
Example #27
Source File: PurchaseDebitorShares.tsx From abrechnung with GNU Affero General Public License v3.0 | 4 votes |
export default function PurchaseDebitorShares({ group, transaction, showPositions = false }) {
const classes = useStyles();
const isSmallScreen = useMediaQuery((theme: Theme) => theme.breakpoints.down("sm"));
const accounts = useRecoilValue(accountsSeenByUser(group.id));
const [searchValue, setSearchValue] = useState("");
const [filteredAccounts, setFilteredAccounts] = useState([]);
const [showAdvanced, setShowAdvanced] = useState(false);
const transactionHasPositions =
transaction.positions != null && transaction.positions.find((item) => !item.deleted) !== undefined;
const setLocalTransactionDetails = useSetRecoilState(pendingTransactionDetailChanges(transaction.id));
useEffect(() => {
for (const share of Object.values(transaction.debitor_shares)) {
if (share !== 1) {
setShowAdvanced(true);
break;
}
}
}, [transaction]);
useEffect(() => {
if (searchValue != null && searchValue !== "") {
setFilteredAccounts(
accounts.filter((acc) => {
return acc.name.toLowerCase().includes(searchValue.toLowerCase());
})
);
} else {
setFilteredAccounts(accounts);
}
}, [searchValue, accounts]);
const debitorShareValueForAccount = (accountID) => {
return transaction.debitor_shares && transaction.debitor_shares.hasOwnProperty(accountID)
? transaction.debitor_shares[accountID]
: 0;
};
const debitorValueForAccount = (accountID) => {
if (!transaction.account_balances.hasOwnProperty(accountID)) {
return 0.0;
}
return transaction.account_balances[accountID].common_debitors;
};
const positionValueForAccount = (accountID) => {
if (!transaction.account_balances.hasOwnProperty(accountID)) {
return 0.0;
}
return transaction.account_balances[accountID].positions;
};
const updateDebShare = (accountID, value) => {
if (value === 0) {
setLocalTransactionDetails((currState) => {
let newDebitorShares;
if (currState.debitor_shares === undefined) {
newDebitorShares = {
...transaction.debitor_shares,
};
} else {
newDebitorShares = {
...currState.debitor_shares,
};
}
delete newDebitorShares[accountID];
return {
...currState,
debitor_shares: newDebitorShares,
};
});
} else {
setLocalTransactionDetails((currState) => {
let newDebitorShares;
if (currState.debitor_shares === undefined) {
newDebitorShares = {
...transaction.debitor_shares,
[accountID]: value,
};
} else {
newDebitorShares = {
...currState.debitor_shares,
[accountID]: value,
};
}
return {
...currState,
debitor_shares: newDebitorShares,
};
});
}
};
return (
<div>
<Box className={classes.listItem}>
<Grid container direction="row" justifyContent="space-between">
<Typography variant="subtitle1" className={classes.checkboxLabel}>
<Box sx={{ display: "flex", alignItems: "flex-end" }}>For whom</Box>
</Typography>
{transaction.is_wip && (
<FormControlLabel
control={<Checkbox name={`show-advanced`} />}
checked={showAdvanced}
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
setShowAdvanced(event.target.checked)
}
label="Advanced"
/>
)}
</Grid>
</Box>
<Divider variant="middle" className={classes.divider} />
<TableContainer sx={{ maxHeight: { md: 400 } }}>
<Table size="small" stickyHeader>
<TableHead>
<TableRow>
<TableCell>
{isSmallScreen ? (
"Account"
) : (
<TextField
placeholder="Search ..."
margin="none"
size="small"
value={searchValue}
onChange={(e) => setSearchValue(e.target.value)}
variant="standard"
InputProps={{
startAdornment: (
<InputAdornment position="start">
<SearchIcon />
</InputAdornment>
),
endAdornment: (
<InputAdornment position="end">
<IconButton
aria-label="clear search input"
onClick={(e) => setSearchValue("")}
edge="end"
>
<Clear />
</IconButton>
</InputAdornment>
),
}}
/>
)}
</TableCell>
<TableCell width="100px">Shares</TableCell>
{showPositions || transactionHasPositions ? (
<>
<TableCell width="100px" align="right">
Positions
</TableCell>
<TableCell width="3px" align="center">
+
</TableCell>
<TableCell width="100px" align="right">
Shared + Rest
</TableCell>
<TableCell width="3px" align="center">
=
</TableCell>
<TableCell width="100px" align="right">
Total
</TableCell>
</>
) : (
<TableCell width="100px" align="right">
Shared
</TableCell>
)}
</TableRow>
</TableHead>
<TableBody>
{filteredAccounts.map((account) => (
<AccountTableRow
key={account.id}
transaction={transaction}
account={account}
debitorValueForAccount={debitorValueForAccount}
debitorShareValueForAccount={debitorShareValueForAccount}
positionValueForAccount={positionValueForAccount}
showAdvanced={showAdvanced}
showPositions={showPositions}
updateDebShare={updateDebShare}
/>
))}
</TableBody>
</Table>
</TableContainer>
</div>
);
}
Example #28
Source File: ClearingSharesFormElement.tsx From abrechnung with GNU Affero General Public License v3.0 | 4 votes |
export default function ClearingSharesFormElement({ group, clearingShares, setClearingShares, accountID = undefined }) {
const accounts = useRecoilValue(accountsSeenByUser(group.id));
const [showAdvanced, setShowAdvanced] = useState(false);
const [searchValue, setSearchValue] = useState("");
const [filteredAccounts, setFilteredAccounts] = useState([]);
useEffect(() => {
if (searchValue != null && searchValue !== "") {
setFilteredAccounts(
accounts.filter((acc) => {
return acc.name.toLowerCase().includes(searchValue.toLowerCase());
})
);
} else {
setFilteredAccounts(accounts);
}
}, [searchValue, accounts]);
return (
<>
<Grid container direction="row" justifyContent="space-between">
<Typography variant="subtitle1">Allocation to</Typography>
<FormControlLabel
control={<Checkbox name={`show-advanced`} />}
checked={showAdvanced}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => setShowAdvanced(event.target.checked)}
label="Advanced"
/>
</Grid>
<TableContainer sx={{ maxHeight: 400 }}>
<Table size="small" stickyHeader>
<TableHead>
<TableRow>
<TableCell>
<TextField
placeholder="Search ..."
margin="none"
size="small"
value={searchValue}
onChange={(e) => setSearchValue(e.target.value)}
variant="standard"
InputProps={{
startAdornment: (
<InputAdornment position="start">
<SearchIcon />
</InputAdornment>
),
}}
/>
</TableCell>
<TableCell width="100px">Shares</TableCell>
</TableRow>
</TableHead>
<TableBody>
{filteredAccounts.map(
(account) =>
(accountID === undefined || account.id !== accountID) && (
<TableRow hover key={account.id}>
<TableCell>
<Grid container direction="row" alignItems="center">
<Grid item>
{account.type === "personal" ? <Person /> : <CompareArrows />}
</Grid>
<Grid item sx={{ ml: 1 }}>
<Typography variant="body2" component="span">
{account.name}
</Typography>
</Grid>
</Grid>
</TableCell>
<TableCell width="100px">
{showAdvanced ? (
<ShareInput
onChange={(value) =>
setClearingShares({
...(clearingShares !== undefined ? clearingShares : {}),
[account.id]: value,
})
}
value={
clearingShares && clearingShares.hasOwnProperty(account.id)
? clearingShares[account.id]
: 0.0
}
/>
) : (
<Checkbox
name={`${account.name}-checked`}
checked={
clearingShares &&
clearingShares.hasOwnProperty(account.id) &&
clearingShares[account.id] !== 0
}
onChange={(event) =>
setClearingShares({
...(clearingShares !== undefined ? clearingShares : {}),
[account.id]: event.target.checked ? 1.0 : 0.0,
})
}
/>
)}
</TableCell>
</TableRow>
)
)}
</TableBody>
</Table>
</TableContainer>
</>
);
}
Example #29
Source File: MapPreview.tsx From firecms with MIT License | 4 votes |
/**
* @category Preview components
*/
export function MapPreview<T extends {}>({
name,
value,
property,
size
}: PreviewComponentProps<T>) {
const classes = useStyles();
if (property.dataType !== "map") {
throw Error("Picked wrong preview component MapPreview");
}
const mapProperty = property as MapProperty;
if (!mapProperty.properties) {
throw Error(`You need to specify a 'properties' prop (or specify a custom field) in your map property ${name}`);
}
if (!value) return null;
let mapPropertyKeys: string[];
if (size === "regular") {
mapPropertyKeys = Object.keys(mapProperty.properties);
} else {
mapPropertyKeys = (mapProperty.previewProperties || Object.keys(mapProperty.properties)) as string[];
if (size === "small")
mapPropertyKeys = mapPropertyKeys.slice(0, 3);
else if (size === "tiny")
mapPropertyKeys = mapPropertyKeys.slice(0, 1);
}
if (size !== "regular")
return (
<>
{mapPropertyKeys.map((key, index) => (
<div
key={"map_preview_" + mapProperty.title + key + index}>
<ErrorBoundary>
<PreviewComponent name={key}
value={(value as any)[key]}
property={mapProperty.properties![key]}
size={size}/>
</ErrorBoundary>
</div>
))}
</>
);
return (
<Table size="small" key={`map_preview_${name}`}>
<TableBody>
{mapPropertyKeys &&
mapPropertyKeys.map((key, index) => {
return (
<TableRow
key={`map_preview_table_${name}_${index}`}
className={classes.tableNoBottomBorder}>
<TableCell key={`table-cell-title-${name}-${key}`}
className={classes.verticalAlignTop}
width="30%"
component="th">
<Typography variant={"caption"}
color={"textSecondary"}>
{mapProperty.properties![key].title}
</Typography>
</TableCell>
<TableCell key={`table-cell-${name}-${key}`}
width="70%"
className={classes.verticalAlignTop}
component="th">
<ErrorBoundary>
<PreviewComponent
name={key}
value={(value as any)[key]}
property={mapProperty.properties![key]}
size={"small"}/>
</ErrorBoundary>
</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
);
}