@mui/material#TableCell TypeScript Examples

The following examples show how to use @mui/material#TableCell. 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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
StyledTableCell = styled(TableCell)(({ theme }) => ({
  [`&.${tableCellClasses.head}`]: {
    backgroundColor: theme.palette.common.white,
    color: theme.palette.common.black,
  },
  [`&.${tableCellClasses.body}`]: {
    fontSize: 14,
  },
}))
Example #5
Source File: ArrayOfMapsPreview.tsx    From firecms with MIT License 5 votes vote down vote up
/**
 * @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 #6
Source File: SkeletonComponent.tsx    From firecms with MIT License 5 votes vote down vote up
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 #7
Source File: index.tsx    From ExpressLRS-Configurator with GNU General Public License v3.0 5 votes vote down vote up
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 #8
Source File: ClearingAccountDetail.tsx    From abrechnung with GNU Affero General Public License v3.0 5 votes vote down vote up
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 #9
Source File: PurchaseDebitorShares.tsx    From abrechnung with GNU Affero General Public License v3.0 5 votes vote down vote up
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 #10
Source File: EnhancedTableHead.tsx    From yearn-watch-legacy with GNU Affero General Public License v3.0 5 votes vote down vote up
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 #11
Source File: Compiler.tsx    From sapio-studio with Mozilla Public License 2.0 5 votes vote down vote up
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: CertificatesTab.tsx    From frontend with MIT License 4 votes vote down vote up
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 #13
Source File: index.tsx    From yearn-watch-legacy with GNU Affero General Public License v3.0 4 votes vote down vote up
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 #14
Source File: DonationTable.tsx    From frontend with MIT License 4 votes vote down vote up
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 #15
Source File: Compiler.tsx    From sapio-studio with Mozilla Public License 2.0 4 votes vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
/**
 * 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: Worlds.tsx    From NekoMaid with MIT License 4 votes vote down vote up
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 #21
Source File: Plugins.tsx    From NekoMaid with MIT License 4 votes vote down vote up
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>)}&nbsp;
                                  <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 #22
Source File: PlayerList.tsx    From NekoMaid with MIT License 4 votes vote down vote up
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 #23
Source File: ObjectMetaData.tsx    From console with GNU Affero General Public License v3.0 4 votes vote down vote up
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 #24
Source File: TransactionPositions.tsx    From abrechnung with GNU Affero General Public License v3.0 4 votes vote down vote up
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 #25
Source File: TransactionPositions.tsx    From abrechnung with GNU Affero General Public License v3.0 4 votes vote down vote up
function PositionTableRow({
    position,
    updatePosition,
    transactionAccounts,
    showAdvanced,
    copyPosition,
    updatePositionUsage,
    showAccountSelect,
    showAddAccount,
    deletePosition,
}) {
    const validateFloat = (value) => {
        return !(value === null || value === undefined || value === "" || isNaN(parseFloat(value)));
    };
    return (
        <>
            <TableCell key={`position-${position.id}-name`}>
                <WrappedTextField
                    key={`position-${position.id}-name`}
                    value={position.name}
                    id={`position-${position.id}-name`}
                    onChange={(value) => updatePosition(position, value, position.price, position.communist_shares)}
                    validate={(value) => value !== "" && value != null}
                />
            </TableCell>
            <TableCell key={`position-${position.id}-communist`} align="right">
                <WrappedTextField
                    key={`position-${position.id}-communist`}
                    id={`position-${position.id}-communist`}
                    value={position.price}
                    style={{ width: 70 }}
                    onChange={(value) =>
                        updatePosition(position, position.name, parseFloat(value), position.communist_shares)
                    }
                    validate={validateFloat}
                    errorMsg={"float required"}
                />
            </TableCell>
            {transactionAccounts.map((accountID) => (
                <TableCell align="right" key={accountID}>
                    {showAdvanced ? (
                        <ShareInput
                            value={
                                position.usages.hasOwnProperty(String(accountID))
                                    ? position.usages[String(accountID)]
                                    : 0
                            }
                            onChange={(value) => updatePositionUsage(position, accountID, value)}
                            inputProps={{ tabIndex: -1 }}
                        />
                    ) : (
                        <Checkbox
                            name={`${accountID}-checked`}
                            checked={position.usages.hasOwnProperty(String(accountID))}
                            onChange={(event) => updatePositionUsage(position, accountID, event.target.checked ? 1 : 0)}
                            inputProps={{ tabIndex: -1 }}
                        />
                    )}
                </TableCell>
            ))}
            {showAccountSelect && <TableCell></TableCell>}
            {showAddAccount && <TableCell></TableCell>}
            <TableCell align="right">
                {showAdvanced ? (
                    <ShareInput
                        value={position.communist_shares}
                        onChange={(value) => updatePosition(position, position.name, position.price, parseFloat(value))}
                        inputProps={{ tabIndex: -1 }}
                    />
                ) : (
                    <Checkbox
                        name="communist-checked"
                        checked={position.communist_shares !== 0}
                        onChange={(event) =>
                            updatePosition(position, position.name, position.price, event.target.checked ? 1 : 0)
                        }
                        inputProps={{ tabIndex: -1 }}
                    />
                )}
            </TableCell>
            <TableCell>
                <IconButton onClick={() => copyPosition(position)} tabIndex={-1}>
                    <ContentCopy />
                </IconButton>
                <IconButton onClick={() => deletePosition(position)} tabIndex={-1}>
                    <Delete />
                </IconButton>
            </TableCell>
        </>
    );
}
Example #26
Source File: PurchaseDebitorSharesReadOnly.tsx    From abrechnung with GNU Affero General Public License v3.0 4 votes vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
/**
 * @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>
    );

}