react-bootstrap#Table TypeScript Examples

The following examples show how to use react-bootstrap#Table. 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: meetingTables.tsx    From remote-office-hours-queue with Apache License 2.0 6 votes vote down vote up
export function MeetingsInProgressTable (props: MeetingTableProps) {
    const startedMeetingRows = props.meetings
        .sort((a, b) => a.id - b.id)
        .map((m) => (
            <tr key={m.id}>
                <StartedMeetingEditor
                    {...props}
                    meeting={m}
                    readableMeetingType={getBackendByName(m.backend_type, props.backends).friendly_name}
                />
            </tr>
        ));

    const startedMeetingsTable = props.meetings.length
        ? (
            <Table bordered responsive>
                <thead>
                    <tr>
                        <th scope="col">Attendee</th>
                        <th scope="col">Host</th>
                        <th scope="col">Details</th>
                        <th scope="col">Meeting Actions</th>
                    </tr>
                </thead>
                <tbody>{startedMeetingRows}</tbody>
            </Table>
        )
        : (
            <>
            <hr/>
            <p>There are currently no meetings in progress. Please create a meeting below to see it here.</p>
            </>
        );
    return startedMeetingsTable;
}
Example #2
Source File: ServantCostumeDetails.tsx    From apps with MIT License 6 votes vote down vote up
ServantCostumeDetails = (props: {
    costumes?: {
        [key: string]: Profile.CostumeDetail;
    };
}) => {
    if (props.costumes !== undefined && Object.values(props.costumes).length > 0) {
        return (
            <>
                <h3>Costumes</h3>
                <Table responsive>
                    <thead>
                        <tr>
                            <th>#</th>
                            <th>Name</th>
                            <th>Detail</th>
                        </tr>
                    </thead>
                    <tbody>
                        {Object.values(props.costumes).map((costume) => (
                            <tr key={costume.id}>
                                <th scope="row">{costume.costumeCollectionNo}</th>
                                <td className="newline">{costume.name}</td>
                                <td className="newline">{costume.detail}</td>
                            </tr>
                        ))}
                    </tbody>
                </Table>
            </>
        );
    } else {
        return null;
    }
}
Example #3
Source File: TestimoniesTable.tsx    From advocacy-maps with MIT License 6 votes vote down vote up
TestimoniesTable = (
  props: UsePublishedTestimonyListing & { search?: boolean }
) => {
  const { pagination, items, setFilter } = props
  const testimonies = items.result ?? []
  return (
    <Container>
      {props.search && <TestimonySearch setFilter={setFilter} />}
      <Table responsive striped bordered hover>
        <thead>
          <tr>
            <th>Bill</th>
            <th>Position</th>
            <th>
              Submitter
              <QuestionTooltip text="Submitters without links have chosen to make their profile private." />
            </th>
            <th>Date Submitted</th>
            <th>Text</th>
            <th></th>
          </tr>
        </thead>
        <tbody>
          {testimonies.map((testimony, index) => (
            <TestimonyRow key={index} testimony={testimony} />
          ))}
        </tbody>
      </Table>
      <PaginationButtons pagination={pagination} />
    </Container>
  )
}
Example #4
Source File: SupportServant.tsx    From apps with MIT License 6 votes vote down vote up
SupportServantSubData = (props: { region: Region; supportServant: SupportServant.SupportServant }) => {
    const { region, supportServant } = props;
    const traitDescriptions = supportServant.traits.map((trait) => (
        <TraitDescription
            region={region}
            trait={trait}
            overrideTraits={[{ id: supportServant.svt.id, name: `Self` }]}
        />
    ));
    return (
        <Table bordered responsive className="quest-svt-data-table">
            <tbody>
                {traitDescriptions.length > 0
                    ? renderSpanningRow({
                          title: "Traits",
                          content: mergeElements(traitDescriptions, ", "),
                      })
                    : null}
                {supportServant.releaseConditions.length > 0
                    ? renderSpanningRow({
                          title: "Release Conditions",
                          content: mergeElements(
                              supportServant.releaseConditions.map((cond) => (
                                  <CondTargetValueDescriptor
                                      region={region}
                                      cond={cond.type}
                                      target={cond.targetId}
                                      value={cond.value}
                                  />
                              )),
                              <br />
                          ),
                      })
                    : null}
            </tbody>
        </Table>
    );
}
Example #5
Source File: common.tsx    From remote-office-hours-queue with Apache License 2.0 6 votes vote down vote up
export function QueueTable (props: QueueTableProps) {
    const linkBase = props.manageLink ? '/manage/' : '/queue/'

    const sortedQueues = sortQueues(props.queues.slice());
    const queueItems = sortedQueues.map(q => (
        <tr key={q.id}>
            <td aria-label={`Queue ID Number`}>
                <Link to={`${linkBase}${q.id}`}>
                    <Badge variant='primary' pill={true}>{q.id}</Badge>
                </Link>
            </td>
            <td aria-label={`Name for Queue ID ${q.id}`}>
                <Link to={`${linkBase}${q.id}`}>{q.name}</Link>
            </td>
            <td aria-label={`Status for Queue ID ${q.id}`}>
                <Link to={`${linkBase}${q.id}`}>
                    <Badge variant={q.status === 'open' ? 'success' : 'danger'} pill={true}>
                        {q.status}
                    </Badge>
                </Link>
            </td>
        </tr>
    ));
    return (
        <Table bordered hover aria-label='Queue Table with Links' className='queue-table'>
            <thead>
                <tr>
                    <th aria-label='Queue ID Number'>Queue ID</th>
                    <th aria-label='Queue Name'>Name</th>
                    <th aria-label='Queue Status'>Status</th>
                </tr>
            </thead>
            <tbody>{queueItems}</tbody>
        </Table>
    );
}
Example #6
Source File: DataTable.tsx    From apps with MIT License 6 votes vote down vote up
render() {
        return (
            <div>
                {this.props.header ? <div className={"data-header"}>{this.props.header}</div> : null}

                <Table bordered hover className={"data-table"} responsive={this.props.responsive}>
                    <tbody>
                        {Object.keys(this.props.data).map((key, index) => {
                            return (
                                <tr key={index}>
                                    <th>{key}</th>
                                    <td>{DataTable.dumpValue(this.props.data[key])}</td>
                                </tr>
                            );
                        })}
                    </tbody>
                </Table>
            </div>
        );
    }
Example #7
Source File: BlocklistView.tsx    From 3Speak-app with GNU General Public License v3.0 5 votes vote down vote up
export function BlocklistView(props: any) {
  const [list, setList] = useState([])

  const generate = () => {
    PromiseIpc.send('blocklist.ls', {} as any).then((value: any) => {
      setList(value)
    })
  }

  const handleRemove = async (reflink) => {
    await PromiseIpc.send('blocklist.rm', reflink)
    NotificationManager.success(`Unblocked ${reflink}`)
    generate()
  }

  useEffect(() => {
    document.title = '3Speak - Tokenised video communities'
    generate()
  }, [])

  return (
    <div>
      <Table responsive>
        <thead>
          <tr>
            <th>Reflink</th>
            <th>Reason</th>
            <th>Remove?</th>
          </tr>
        </thead>
        <tbody>
          {list.map((value) => (
            <tr key={value._id}>
              <td>{value._id}</td>
              <td>{value.reason}</td>
              <td>
                <Button variant="danger" onClick={() => handleRemove(value._id)}>
                  X
                </Button>
              </td>
            </tr>
          ))}
        </tbody>
      </Table>
    </div>
  )
}
Example #8
Source File: EventRewardTower.tsx    From apps with MIT License 5 votes vote down vote up
EventRewardTower = ({
    region,
    tower,
    itemMap,
}: {
    region: Region;
    tower: Event.EventTower;
    itemMap: Map<number, Item.Item>;
}) => {
    return (
        <Table hover responsive>
            <thead>
                <tr>
                    <th className="text-center">Floor</th>
                    <th>Message</th>
                    <th>Reward</th>
                </tr>
            </thead>
            <tbody>
                {tower.rewards.map((reward) => {
                    return (
                        <tr key={reward.floor}>
                            <th scope="row" style={{ textAlign: "center" }}>
                                {reward.floor}
                            </th>
                            <td>{colorString(interpolateString(reward.boardMessage, [reward.floor]))}</td>
                            <td>
                                {mergeElements(
                                    reward.gifts.map((gift) => (
                                        <GiftDescriptor
                                            key={`${gift.objectId}-${gift.priority}`}
                                            region={region}
                                            gift={gift}
                                            items={itemMap}
                                        />
                                    )),
                                    ", "
                                )}
                            </td>
                        </tr>
                    );
                })}
            </tbody>
        </Table>
    );
}
Example #9
Source File: statistic-data.component.tsx    From cwa-quick-test-frontend with Apache License 2.0 5 votes vote down vote up
StatisticDataRow = (props: any) => {
    const { t } = useTranslation();

    const [pcrEnabled, setPcrEnabled] = React.useState(false);
    const [statisticRows, setStatisticRows] = React.useState<DisplayStatisticData[]>([]);

    React.useEffect(() => {
        if (props && props.statisticData) {
            const statisticData: DisplayStatisticData[] = props.statisticData;

            setPcrEnabled(props.pcrEnabled);
            setStatisticRows(statisticData);
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [props.statisticData])

    return (
        <Table bordered hover responsive className="width-eight-houndred">
            <thead>
                <tr>
                    <th>&nbsp;</th>
                    <th><strong>{t('translation:totalTestCount')}</strong></th>
                    <th><strong>{t('translation:positiveTestCount')}</strong></th>
                    {!pcrEnabled
                        ? <></>
                        : <>
                            <th><strong>{t('translation:pcrTotalTestCount')}</strong></th>
                            <th><strong>{t('translation:pcrPositiveTestCount')}</strong></th>
                        </>
                    }
                    <th>&nbsp;</th>
                </tr>
            </thead>
            <tbody>
                {statisticRows.map((statiscData: DisplayStatisticData, i: number) =>
                    <tr key={statiscData.key}>
                        <td><strong>{statiscData.label}</strong></td>
                        <td>{statiscData.ratTestCount}</td>
                        <td>
                            {statiscData.ratTestCount > 0 ? statiscData.ratPositiveTestCount +
                                ' ( ' + (100 * statiscData.ratPositiveTestCount / statiscData.ratTestCount).toFixed(2) + "% )" : 0}
                        </td>
                        {!pcrEnabled
                            ? <></>
                            : <>
                                <td>{statiscData.pcrTestCount}</td>
                                <td>
                                    {statiscData.pcrTestCount > 0 ? statiscData.pcrPositiveTestCount +
                                        ' ( ' + (100 * statiscData.pcrPositiveTestCount / statiscData.pcrTestCount).toFixed(2) + "% )" : 0}
                                </td>
                            </>
                        }
                        <td className="width-one">
                            <Button className="btn-icon delete-icon mx-1"
                                onClick={() => { props.deleteRow(statiscData.key) }}
                            />
                        </td>
                    </tr>
                )}
            </tbody>
        </Table>
    )
}
Example #10
Source File: MysticCodesPage.tsx    From apps with MIT License 5 votes vote down vote up
render() {
        if (this.state.error) return <ErrorStatus error={this.state.error} />;

        if (this.state.loading) return <Loading />;

        return (
            <div id="mystic-codes" className="listing-page">
                <Table striped bordered hover responsive>
                    <thead>
                        <tr>
                            <th className="col-center">#</th>
                            <th style={{ textAlign: "center", width: "140px" }}>Thumbnail</th>
                            <th>Name</th>
                        </tr>
                    </thead>
                    <tbody>
                        {this.state.mysticCodes.map((mysticCode) => {
                            const route = `/${this.props.region}/mystic-code/${mysticCode.id}`;

                            return (
                                <tr key={mysticCode.id}>
                                    <td className="col-center">
                                        <Link to={route}>{mysticCode.id}</Link>
                                    </td>
                                    <td className="col-center">
                                        <Link to={route}>
                                            <FaceIcon location={mysticCode.item.male} height={50} />
                                            <FaceIcon location={mysticCode.item.female} height={50} />
                                        </Link>
                                    </td>
                                    <td>
                                        <Link to={route}>{mysticCode.name}</Link>
                                    </td>
                                </tr>
                            );
                        })}
                    </tbody>
                </Table>
            </div>
        );
    }
Example #11
Source File: meetingTables.tsx    From remote-office-hours-queue with Apache License 2.0 5 votes vote down vote up
export function MeetingsInQueueTable (props: MeetingsInQueueTableProps) {
    const unstartedMeetingRows = props.meetings
        .sort((a, b) => a.id - b.id)
        .map(
            (m, i) => (
                <tr key={m.id}>
                    <th scope="row" className="d-none d-sm-table-cell">{i+1}</th>
                    <UnstartedMeetingEditor
                        {...props}
                        meeting={m}
                        readableMeetingType={getBackendByName(m.backend_type, props.backends).friendly_name}
                        potentialAssignees={props.queue.hosts}
                        onChangeAssignee={(a: User | undefined) => props.onChangeAssignee(a, m)}
                    />
                </tr>
            )
        );

    const unstartedMeetingsTable = props.meetings.length
        ? (
            <Table bordered responsive>
                <thead>
                    <tr>
                        <th scope="col" className="d-none d-sm-table-cell">Queue #</th>
                        <th scope="col">Attendee</th>
                        <th scope="col">Host</th>
                        <th scope="col">Details</th>
                        <th scope="col">Meeting Actions</th>
                    </tr>
                </thead>
                <tbody>{unstartedMeetingRows}</tbody>
            </Table>
        )
        : (
            <>
            <hr/>
            <p>There are currently no meetings in queue.</p>
            <p>
                <strong>Did you know?</strong> You can get notified by SMS (text) message when someone joins your empty queue
                by adding your cell phone number and enabling host notifications in your <Link to="/preferences">User Preferences</Link>. 
            </p>
            </>
        );
    return unstartedMeetingsTable;
}
Example #12
Source File: ServantProfileComments.tsx    From apps with MIT License 5 votes vote down vote up
render() {
        return (
            <>
                <h3>Profile</h3>

                <Table responsive className="servant-comments">
                    <thead className="servant-comments-header">
                        <tr>
                            <th>
                                <Row className="m-0">
                                    <Col sm={12} md={2} className="pl-0">
                                        Condition
                                    </Col>
                                    <Col className="pr-0">Message</Col>
                                </Row>
                            </th>
                        </tr>
                    </thead>
                    <tbody>
                        {this.props.comments.map((comment) => {
                            return (
                                <tr key={`${comment.id}-${comment.priority}`}>
                                    <td>
                                        <Row className="m-0">
                                            <Col sm={12} md={2} className="pl-0">
                                                <b>
                                                    <ProfileConditionDescriptor
                                                        region={this.props.region}
                                                        comment={comment}
                                                    />
                                                    <ProfileCommentAddsDescriptor
                                                        region={this.props.region}
                                                        commentAdds={comment.additionalConds}
                                                    />
                                                </b>
                                            </Col>
                                            <Col className="newline pr-0">{replacePUACodePoints(comment.comment)}</Col>
                                        </Row>
                                    </td>
                                </tr>
                            );
                        })}
                    </tbody>
                </Table>
            </>
        );
    }
Example #13
Source File: replace-table.tsx    From polkabtc-ui with Apache License 2.0 4 votes vote down vote up
export default function ReplaceTable(props: ReplaceTableProps): ReactElement {
  const { polkaBtcLoaded, address } = useSelector((state: StoreType) => state.general);
  const dispatch = useDispatch();
  const replaceRequests = useSelector((state: StoreType) => state.vault.requests);
  const [polkaBTCAmount, setPolkaBTCamount] = useState(new Big(0));
  const { t } = useTranslation();

  useEffect(() => {
    const fetchData = async () => {
      if (!polkaBtcLoaded || !address) return;

      try {
        const vaultId = window.polkaBTC.api.createType(ACCOUNT_ID_TYPE_NAME, address);
        const issuedPolkaBTCAmount = await window.polkaBTC.vaults.getIssuedAmount(vaultId);
        setPolkaBTCamount(issuedPolkaBTCAmount);
        const requests = await window.polkaBTC.vaults.mapReplaceRequests(vaultId);
        if (!requests) return;

        dispatch(addReplaceRequestsAction(parachainToUIReplaceRequests(requests)));
      } catch (err) {
        console.log(err);
      }
    };

    fetchData();
  }, [polkaBtcLoaded, dispatch, address]);

  return (
    <div style={{ margin: '40px 0px' }}>
      <div>
        <p
          className='mb-4'
          style={{
            fontWeight: 700,
            fontSize: '26px'
          }}>
          {t('vault.replace_requests')}
        </p>
      </div>
      {replaceRequests && replaceRequests.length > 0 ? (
        <React.Fragment>
          <Table
            hover
            responsive
            size='md'>
            <thead>
              <tr>
                <th>{t('id')}</th>
                <th>{t('vault.creation_block')}</th>
                <th>{t('vault.old_vault')}</th>
                <th>{t('vault.new_vault')}</th>
                <th>{t('btc_address')}</th>
                <th>PolkaBTC</th>
                <th>{t('griefing_collateral')}</th>
                <th>{t('status')}</th>
              </tr>
            </thead>
            <tbody>
              {replaceRequests.map((redeem, index) => {
                return (
                  <tr key={index}>
                    <td>{redeem.id}</td>
                    <td>{redeem.timestamp}</td>
                    <td>{shortAddress(redeem.oldVault)}</td>
                    <td>{shortAddress(redeem.newVault)}</td>
                    <td>{shortAddress(redeem.btcAddress)}</td>
                    <td>{redeem.polkaBTC}</td>
                    <td>{redeem.lockedDOT}</td>
                    <td>{redeem.status}</td>
                  </tr>
                );
              })}
            </tbody>
          </Table>
        </React.Fragment>
      ) : (
        <React.Fragment>{t('empty_data')}</React.Fragment>
      )}
      <div className='row'>
        <div className='col-12'>
          {polkaBTCAmount.gt(new Big(0)) ? (
            <Button
              variant='outline-danger'
              className='vault-dashboard-button'
              onClick={() => props.openModal(true)}>
              {t('vault.replace_vault')}
            </Button>
          ) : (
            ''
          )}
        </div>
      </div>
    </div>
  );
}
Example #14
Source File: MasterMissionPage.tsx    From apps with MIT License 4 votes vote down vote up
MasterMissionPage = (props: { region: Region; masterMissionId: number }) => {
    const { region, masterMissionId } = props;
    const [loading, setLoading] = useState<boolean>(true);
    const [error, setError] = useState<AxiosError | undefined>(undefined);
    const [masterMission, setMasterMission] = useState<MasterMission.MasterMission | undefined>(undefined);
    const [enumList, setEnumList] = useState<EnumList | undefined>(undefined);
    const [servantCache, setServantCache] = useState<Map<number, Servant.ServantBasic> | undefined>(undefined);
    const [itemCache, setItemCache] = useState<Map<number, Item.Item> | undefined>(undefined);

    useEffect(() => {
        Manager.setRegion(region);
        Promise.all([Api.masterMission(masterMissionId), Api.enumList(), Api.servantList(), Api.itemList()])
            .then(([mmData, enums, servants, items]) => {
                setMasterMission(mmData);
                setEnumList(enums);
                setServantCache(new Map(servants.map((servant) => [servant.id, servant])));
                setItemCache(new Map(items.map((item) => [item.id, item])));
                setLoading(false);
            })
            .catch((e) => {
                setError(e);
                setLoading(false);
            });
    }, [region, masterMissionId]);

    if (loading) return <Loading />;

    if (error !== undefined) return <ErrorStatus error={error} />;

    if (masterMission === undefined) return null;

    document.title = `[${region}] Master Mission ${masterMissionId} - Atlas Academy DB`;

    const missionMap = new Map(masterMission.missions.map((mission) => [mission.id, mission]));
    const questCache = new Map(masterMission.quests.map((quest) => [quest.id, quest]));

    return (
        <>
            <h1>Master Mission {masterMissionId}</h1>
            <br />

            <div style={{ marginBottom: "3%" }}>
                <DataTable
                    data={{
                        ID: masterMissionId,
                        Status: getEventStatus(masterMission.startedAt, masterMission.endedAt),
                        Start: getTimeString(masterMission.startedAt),
                        End: getTimeString(masterMission.endedAt),
                        Close: getTimeString(masterMission.closedAt),
                        Raw: (
                            <Row>
                                <Col>
                                    <RawDataViewer text="Nice" data={masterMission} />
                                </Col>
                                <Col>
                                    <RawDataViewer text="Raw" data={`${Host}/raw/${region}/mm/${masterMissionId}`} />
                                </Col>
                            </Row>
                        ),
                    }}
                />
            </div>
            <h2>Missions</h2>
            <Table hover responsive>
                <thead>
                    <tr>
                        <th style={{ textAlign: "center" }}>#</th>
                        <th>Detail</th>
                        <th>Reward</th>
                    </tr>
                </thead>
                <tbody>
                    {masterMission.missions.map((mission) => (
                        <tr key={mission.id}>
                            <th scope="row" style={{ textAlign: "center" }}>
                                {mission.dispNo}
                            </th>
                            <td>
                                <b className="newline">{mission.name}</b>
                                <br />
                                <MasterMissionCond
                                    region={region}
                                    mission={mission}
                                    missionMap={missionMap}
                                    servants={servantCache}
                                    quests={questCache}
                                    items={itemCache}
                                    enums={enumList}
                                />
                            </td>
                            <td>
                                {mission.gifts.map((gift) => (
                                    <div key={`${gift.objectId}-${gift.priority}`}>
                                        <GiftDescriptor region={region} gift={gift} items={itemCache} />
                                        <br />
                                    </div>
                                ))}
                            </td>
                        </tr>
                    ))}
                </tbody>
            </Table>
        </>
    );
}
Example #15
Source File: dataprivacy.component.tsx    From cwa-quick-test-frontend with Apache License 2.0 4 votes vote down vote up
DataprivacyPage = (props: any) => {

    const { t } = useTranslation();
    const [show, setShow] = React.useState(false);

    React.useEffect(() => {
        if (props)
            setShow(props.show);
            // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [props.show])

    const handleClose = () => {
        props.setShow(false)
    }

    return (
        <>
            <Modal
                size='lg'
                contentClassName='bg-light'
                scrollable
                show={show}
                aria-labelledby="example-custom-modal-styling-title"
                centered
                onHide={handleClose}

            >
                <Modal.Header id='data-header' closeButton className='pb-0' >
                    <Row>
                        <Col >
                            <Card.Title className='m-0 jcc-xs-jcfs-md' as={'h2'} >{t('translation:dp-title')}</Card.Title>
                        </Col>
                    </Row>
                </Modal.Header>
                    <hr className='mx-3 mb-0' />
                <Modal.Body className='px-3 bg-light'>
                    <Container className='px-1 px-sm-2 px-md-3'>
                        <h5 className='text-justify'>
                            Der Schutz Ihrer persönlichen Daten hat für die T-Systems International GmbH einen hohen Stellenwert. Es ist uns wichtig, Sie darüber zu informieren, welche persönlichen Daten erfasst werden, wie diese verwendet werden und welche Gestaltungsmöglichkeiten Sie dabei haben.
                    </h5>

                        <ol>
                            <li className='text-justify py-3'>
                                <strong>Welche Daten werden erfasst, wie werden sie verwendet und wie lange werden sie gespeichert?</strong>
                                <ol type='a' className='pr-2 pr-md-4'>
                                    <li>
                                        <strong>Technische Merkmale:</strong> <br />
                                        Wenn Sie sich an unserem Schnelltestportal anmelden, verzeichnet der Server Ihren Benutzernamen, die Teststellen-ID, den verwendeten Mandanten (und die von Ihnen ausgeführten Datenbankoperationen (z.B. Eingabe von Patientendaten, Eingabe von Testergebnissen). 
Die protokollierten Daten werden ausschließlich für Zwecke der Datensicherheit, insbesondere zur Abwehr von Angriffsversuchen auf unseren Server verwendet (Art. 6 Abs. 1f DSGVO). Sie werden weder für die Erstellung von individuellen Anwenderprofilen verwendet noch an Dritte weitergegeben und werden nach Ablauf eines Zeitraums von 7 Tagen bis 30 Tagen gelöscht. Die statistische Auswertung anonymisierter Datensätze behalten wir uns vor.<br />
                                    </li>
                                    <li className='py-3'>
                                        <strong>Authentifizierungsdaten:</strong> <br />
                                        Wenn Sie sich an unserem Schnelltest-Portal anmelden, werden erfolgreiche und fehlgeschlagene Anmeldeversuche dokumentiert. Diese Dokumentation umfasst den Benutzernamen, Ihren Vor- und Nachnamen, den Zeitpunkt der Anmeldung, die IP-Adresse, von der aus die Anmeldung durchgeführt wurde und die Session-Dauer. Rechtsgrundlage dieser Verarbeitung ist § 26 Abs. 1 BDSG, soweit Sie als Beschäftigter eines Unternehmens, welches unsere Leistungen in Anspruch nimmt, tätig sind. Sind Sie auf selbständiger Basis für ein Unternehmen tätig, welches unsere Leistungen in Anspruch nimmt, erfolgt die Verarbeitung auf Grund der durch Ihren Auftraggeber eingeholten Einwilligung zur Speicherung.<br />
                                    </li>
                                    <li>
                                        <strong>Archivierung von Testergebnissen:</strong> <br />
                                        Ihr Benutzername wird zusammen mit den Patientendaten des durchgeführten Tests (Name, Vorname, Geburtsdatum, Geschlecht, Adresse, Testhersteller, eingesetzter Test, Tag des Testergebnisses) und dem Testergebnis gemäß gesetzlicher Grundlage archiviert und 10 Jahre aufbewahrt und dann gelöscht.<br />
                                    </li>
                                </ol>
                            </li>
                            <li className='text-justify py-3' >
                                <strong>Wird mein Nutzungsverhalten ausgewertet, z. B. für Werbung oder Tracking?<br /></strong>
                                Es werden nur für die Nutzung des Schnelltest-Portals erforderliche Cookies verwendet. Diese Cookies sind notwendig, damit Sie durch die Seiten navigieren und wesentliche Funktionen nutzen können. Sie ermöglichen die Benutzung des Schnelltestportals. Rechtsgrundlage für diese Cookies ist Art. 6 Abs. 1b DSGVO bzw. bei Drittstaaten Art. 49 Abs. 1b DSGVO.
                             
                            </li>
                            <Table className='my-3'>
                                <thead>
                                    <tr>
                                        <th>Firma</th>
                                        <th>Zweck</th>
                                        <th>Speicherdauer</th>
                                        <th>Land der Verarbeitung</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <tr>
                                        <td>T-Systems</td>
                                        <td>Login</td>
                                        <td>Session Cookie</td>
                                        <td>Deutschland</td>
                                    </tr>
                                </tbody>
                            </Table>
                            <li className='text-justify py-3' >
                                <strong>Wo finde ich die Informationen, die für mich wichtig sind?</strong><br />
                                Dieser <strong>Datenschutzhinweis</strong> gibt einen Überblick über die Punkte, die für die Verarbeitung Ihrer Daten in diesem Webportal durch T-Systems gelten.<br />
Weitere Informationen, auch zum Datenschutz im allgemeinen und in speziellen Produkten, erhalten Sie auf <a href='https://www.telekom.com/de/verantwortung/datenschutz-und-datensicherheit/datenschutz'>https://www.telekom.com/de/verantwortung/datenschutz-und-datensicherheit/datenschutz</a> und unter <a href='http://www.telekom.de/datenschutzhinweise'>http://www.telekom.de/datenschutzhinweise</a>.
                            </li>
                            <li className='text-justify py-3' >
                                <strong>Wer ist verantwortlich für die Datenverarbeitung? Wer ist mein Ansprechpartner, wenn ich Fragen zum Datenschutz bei der Telekom habe?</strong><br />
                                Datenverantwortliche ist die T-Systems International GmbH. Bei Fragen können Sie sich an unseren <a href='http://www.telekom.de/kontakt'>Kundenservice</a> wenden oder an unseren Datenschutzbeauftragten, Herrn Dr. Claus D. Ulmer, Friedrich-Ebert-Allee 140, 53113 Bonn, <a href='mailto:[email protected]'>[email protected]</a>.
                            </li>
                            <li className='text-justify py-3' >
                                <strong>Welche Rechte habe ich? </strong><br />
                                Sie haben das Recht,
                                <ol type='a' className='pr-2 pr-md-4'>
                                    <li>
                                        <strong>Auskunft</strong> zu verlangen zu Kategorien der verarbeiteten Daten, Verarbeitungszwecken, etwaigen Empfängern der Daten, der geplanten Speicherdauer (Art. 15 DSGVO);
                                    </li>
                                    <li>
                                        die <strong>Berichtigung</strong> bzw. Ergänzung unrichtiger bzw. unvollständiger Daten zu verlangen (Art. 16 DSGVO);
                                    </li>
                                    <li>
                                        eine erteilte Einwilligung jederzeit mit Wirkung für die Zukunft zu <strong>widerrufen</strong> (Art. 7 Abs. 3 DSGVO);
                                    </li>
                                    <li>
                                        einer Datenverarbeitung, die aufgrund eines berechtigten Interesses erfolgen soll, aus Gründen zu <strong>widersprechen</strong>, die sich aus Ihrer besonderen Situation ergeben (Art 21 Abs. 1 DSGVO);
                                    </li>
                                    <li>
                                        in bestimmten Fällen im Rahmen des Art. 17 DSGVO die <strong>Löschung</strong> von Daten zu verlangen - insbesondere soweit die Daten für den vorgesehenen Zweck nicht mehr erforderlich sind bzw. unrechtmäßig verarbeitet werden, oder Sie Ihre Einwilligung gemäß oben (c) widerrufen oder einen Widerspruch gemäß oben (d) erklärt haben;
                                    </li>
                                    <li>
                                        unter bestimmten Voraussetzungen die <strong>Einschränkung</strong> von Daten zu verlangen, soweit eine Löschung nicht möglich bzw. die Löschpflicht streitig ist (Art. 18 DSGVO);
                                    </li>
                                    <li>
                                        auf <strong>Datenübertragbarkeit</strong>, d.h. Sie können Ihre Daten, die Sie uns bereitgestellt haben, in einem gängigen maschinenlesbaren Format, wie z.B. CSV, erhalten und ggf. an andere übermitteln (Art. 20 DSGVO);
                                    </li>
                                    <li>
                                        sich bei der zuständigen <strong>Aufsichtsbehörde</strong> über die Datenverarbeitung zu <strong>beschweren</strong> (für Telekommunikationsverträge: Bundesbeauftragter für den Datenschutz und die Informationsfreiheit; im Übrigen: Landesbeauftragte für den Datenschutz und die Informationsfreiheit Nordrhein-Westfalen).
                                    </li>
                                </ol>
                            </li>

                            <li className='text-justify py-3' >
                                <strong>An wen gibt die Telekom meine Daten weiter?</strong><br />
                                <strong>An Auftragsverarbeiter</strong>, das sind Unternehmen, die wir im gesetzlich vorgesehenen Rahmen mit der Verarbeitung von Daten beauftragen, Art. 28 DSGVO (Dienstleister, Erfüllungsgehilfen). Die Telekom bleibt auch in dem Fall weiterhin für den Schutz Ihrer Daten verantwortlich. Wir beauftragen Unternehmen insbesondere in folgenden Bereichen: IT, Vertrieb, Marketing, Finanzen, Beratung, Kundenservice, Personalwesen, Logistik, Druck.<br />
                                <strong>Aufgrund gesetzlicher Verpflichtung</strong>: In bestimmten Fällen sind wir gesetzlich verpflichtet, bestimmte Daten an die anfragende staatliche Stelle zu übermitteln.
                            </li>
                            <li className='text-justify py-3' >
                                <strong>Wo werden meine Daten verarbeitet?</strong><br />
                                Ihre Daten werden in Deutschland und im europäischen Ausland verarbeitet. Findet eine Verarbeitung Ihrer Daten in Ausnahmefällen auch in Ländern außerhalb der Europäischen Union (in sog. Drittstaaten) statt, geschieht dies,
                                <ol type='a' className='pr-2 pr-md-4'>
                                    <li>
                                    soweit Sie hierin ausdrücklich eingewilligt haben (Art. 49 Abs. 1a DSGVO).  (In den meisten Ländern außerhalb der EU entspricht das Datenschutzniveau nicht den EU Standards. Dies betrifft insbesondere umfassende Überwachungs- und Kontrollrechte staatlicher Behörden, z.B. in den USA, die in den Datenschutz der europäischen Bürgerinnen und Bürger unverhältnismäßig eingreifen,
                                    </li>
                                    <li>
                                    oder soweit es für unsere Leistungserbringung Ihnen gegenüber erforderlich ist (Art. 49 Abs. 1b DSGVO),
                                    </li>
                                    <li>
                                    oder soweit es gesetzlich vorgesehen ist (Art. 6 Abs. 1c DSGVO).
                                    </li>
                                </ol>
                                Darüber hinaus erfolgt eine Verarbeitung Ihrer Daten in Drittstaaten nur, soweit durch bestimmte Maßnahmen sichergestellt ist, dass hierfür ein angemessenes Datenschutzniveau besteht (z.B. Angemessenheitsbeschluss der EU-Kommission oder sog. geeignete Garantien, Art. 44ff. DSGVO).<br/><br/>
                                Stand der Datenschutzhinweise 29.04.2021
                            </li>
                        </ol>
                    </Container>
                </Modal.Body>
                    <hr className='mx-3 mt-0' />

                {/*
    footer with ok button
    */}
                <Modal.Footer id='data-footer'>
                    <Button
                        className='py-0'
                        onClick={handleClose}
                    >
                        {t('translation:cancel')}
                    </Button>
                </Modal.Footer>
            </Modal>
        </>
    )
}
Example #16
Source File: CollectionShare.tsx    From bada-frame with GNU General Public License v3.0 4 votes vote down vote up
function CollectionShare(props: Props) {
    const [loading, setLoading] = useState(false);
    const appContext = useContext(AppContext);
    const galleryContext = useContext(GalleryContext);
    const [sharableLinkError, setSharableLinkError] = useState(null);
    const [publicShareUrl, setPublicShareUrl] = useState<string>(null);
    const [publicShareProp, setPublicShareProp] = useState<PublicURL>(null);
    const [configurePassword, setConfigurePassword] = useState(false);
    const deviceLimitOptions = selectIntOptions(50);
    const expiryOptions = shareExpiryOptions;

    useEffect(() => {
        const main = async () => {
            if (props.collection?.publicURLs?.[0]?.url) {
                const t = await appendCollectionKeyToShareURL(
                    props.collection?.publicURLs?.[0]?.url,
                    props.collection.key
                );
                setPublicShareUrl(t);
                setPublicShareProp(
                    props.collection?.publicURLs?.[0] as PublicURL
                );
            } else {
                setPublicShareUrl(null);
                setPublicShareProp(null);
            }
        };
        main();
    }, [props.collection]);

    const collectionShare = async (
        { email }: formValues,
        { resetForm, setFieldError }: FormikHelpers<formValues>
    ) => {
        try {
            setLoading(true);
            appContext.startLoading();
            const user: User = getData(LS_KEYS.USER);
            if (email === user.email) {
                setFieldError('email', constants.SHARE_WITH_SELF);
            } else if (
                props.collection?.sharees?.find(
                    (value) => value.email === email
                )
            ) {
                setFieldError('email', constants.ALREADY_SHARED(email));
            } else {
                await shareCollection(props.collection, email);
                await sleep(2000);
                await galleryContext.syncWithRemote(false, true);
                resetForm();
            }
        } catch (e) {
            const errorMessage = handleSharingErrors(e);
            setFieldError('email', errorMessage);
        } finally {
            setLoading(false);
            appContext.finishLoading();
        }
    };
    const collectionUnshare = async (sharee) => {
        try {
            appContext.startLoading();
            await unshareCollection(props.collection, sharee.email);
            await sleep(2000);
            await galleryContext.syncWithRemote(false, true);
        } finally {
            appContext.finishLoading();
        }
    };

    const createSharableURLHelper = async () => {
        try {
            appContext.startLoading();
            const publicURL = await createShareableURL(props.collection);
            const sharableURL = await appendCollectionKeyToShareURL(
                publicURL.url,
                props.collection.key
            );
            setPublicShareUrl(sharableURL);
            galleryContext.syncWithRemote(false, true);
        } catch (e) {
            const errorMessage = handleSharingErrors(e);
            setSharableLinkError(errorMessage);
        } finally {
            appContext.finishLoading();
        }
    };

    const disablePublicSharingHelper = async () => {
        try {
            appContext.startLoading();
            await deleteShareableURL(props.collection);
            setPublicShareUrl(null);
            galleryContext.syncWithRemote(false, true);
        } catch (e) {
            const errorMessage = handleSharingErrors(e);
            setSharableLinkError(errorMessage);
        } finally {
            appContext.finishLoading();
        }
    };

    const savePassword = async (passphrase, setFieldError) => {
        if (passphrase && passphrase.trim().length >= 1) {
            await enablePublicUrlPassword(passphrase);
            setConfigurePassword(false);
            publicShareProp.passwordEnabled = true;
        } else {
            setFieldError('linkPassword', 'can not be empty');
        }
    };

    const handlePasswordChangeSetting = async () => {
        if (publicShareProp.passwordEnabled) {
            await disablePublicUrlPassword();
        } else {
            setConfigurePassword(true);
        }
    };

    const disablePublicUrlPassword = async () => {
        appContext.setDialogMessage({
            title: constants.DISABLE_PASSWORD,
            content: constants.DISABLE_PASSWORD_MESSAGE,
            close: { text: constants.CANCEL },
            proceed: {
                text: constants.DISABLE,
                action: () =>
                    updatePublicShareURLHelper({
                        collectionID: props.collection.id,
                        disablePassword: true,
                    }),
                variant: ButtonVariant.danger,
            },
        });
    };

    const enablePublicUrlPassword = async (password: string) => {
        const cryptoWorker = await new CryptoWorker();
        const kekSalt: string = await cryptoWorker.generateSaltToDeriveKey();
        const kek = await cryptoWorker.deriveInteractiveKey(password, kekSalt);

        return updatePublicShareURLHelper({
            collectionID: props.collection.id,
            passHash: kek.key,
            nonce: kekSalt,
            opsLimit: kek.opsLimit,
            memLimit: kek.memLimit,
        });
    };

    const disablePublicSharing = () => {
        appContext.setDialogMessage({
            title: constants.DISABLE_PUBLIC_SHARING,
            content: constants.DISABLE_PUBLIC_SHARING_MESSAGE,
            close: { text: constants.CANCEL },
            proceed: {
                text: constants.DISABLE,
                action: disablePublicSharingHelper,
                variant: ButtonVariant.danger,
            },
        });
    };

    const disableFileDownload = () => {
        appContext.setDialogMessage({
            title: constants.DISABLE_FILE_DOWNLOAD,
            content: constants.DISABLE_FILE_DOWNLOAD_MESSAGE,
            close: { text: constants.CANCEL },
            proceed: {
                text: constants.DISABLE,
                action: () =>
                    updatePublicShareURLHelper({
                        collectionID: props.collection.id,
                        enableDownload: false,
                    }),
                variant: ButtonVariant.danger,
            },
        });
    };

    const updatePublicShareURLHelper = async (req: UpdatePublicURL) => {
        try {
            galleryContext.setBlockingLoad(true);
            const response = await updateShareableURL(req);
            setPublicShareProp(response);
            galleryContext.syncWithRemote(false, true);
        } catch (e) {
            const errorMessage = handleSharingErrors(e);
            setSharableLinkError(errorMessage);
        } finally {
            galleryContext.setBlockingLoad(false);
        }
    };

    const updateDeviceLimit = async (newLimit: number) => {
        return updatePublicShareURLHelper({
            collectionID: props.collection.id,
            deviceLimit: newLimit,
        });
    };

    const updateDeviceExpiry = async (optionFn) => {
        return updatePublicShareURLHelper({
            collectionID: props.collection.id,
            validTill: optionFn(),
        });
    };

    const handleCollectionPublicSharing = () => {
        setSharableLinkError(null);
        if (publicShareUrl) {
            disablePublicSharing();
        } else {
            createSharableURLHelper();
        }
    };

    const handleFileDownloadSetting = () => {
        if (publicShareProp.enableDownload) {
            disableFileDownload();
        } else {
            updatePublicShareURLHelper({
                collectionID: props.collection.id,
                enableDownload: true,
            });
        }
    };

    const ShareeRow = ({ sharee, collectionUnshare }: ShareeProps) => (
        <tr>
            <td>{sharee.email}</td>
            <td>
                <Button
                    variant="outline-danger"
                    style={{
                        height: '25px',
                        lineHeight: 0,
                        padding: 0,
                        width: '25px',
                        fontSize: '1.2em',
                        fontWeight: 900,
                    }}
                    onClick={() => collectionUnshare(sharee)}>
                    -
                </Button>
            </td>
        </tr>
    );

    if (!props.collection) {
        return <></>;
    }

    return (
        <MessageDialog
            show={props.show}
            onHide={props.onHide}
            attributes={{
                title: constants.SHARE_COLLECTION,
                staticBackdrop: true,
            }}>
            <DeadCenter style={{ width: '85%', margin: 'auto' }}>
                <h6 style={{ marginTop: '8px' }}>
                    {constants.SHARE_WITH_PEOPLE}
                </h6>
                <p />
                <Formik<formValues>
                    initialValues={{ email: '' }}
                    validationSchema={Yup.object().shape({
                        email: Yup.string()
                            .email(constants.EMAIL_ERROR)
                            .required(constants.REQUIRED),
                    })}
                    validateOnChange={false}
                    validateOnBlur={false}
                    onSubmit={collectionShare}>
                    {({
                        values,
                        errors,
                        touched,
                        handleChange,
                        handleSubmit,
                    }) => (
                        <Form noValidate onSubmit={handleSubmit}>
                            <Form.Row>
                                <Form.Group
                                    as={Col}
                                    xs={10}
                                    controlId="formHorizontalEmail">
                                    <Form.Control
                                        type="email"
                                        placeholder={constants.ENTER_EMAIL}
                                        value={values.email}
                                        onChange={handleChange('email')}
                                        isInvalid={Boolean(
                                            touched.email && errors.email
                                        )}
                                        autoFocus
                                        disabled={loading}
                                    />
                                    <FormControl.Feedback type="invalid">
                                        {errors.email}
                                    </FormControl.Feedback>
                                </Form.Group>
                                <Form.Group
                                    as={Col}
                                    xs={2}
                                    controlId="formHorizontalEmail">
                                    <SubmitButton
                                        loading={loading}
                                        inline
                                        buttonText="+"
                                    />
                                </Form.Group>
                            </Form.Row>
                        </Form>
                    )}
                </Formik>
                {props.collection.sharees?.length > 0 && (
                    <>
                        <p>{constants.SHAREES}</p>

                        <Table striped bordered hover variant="dark" size="sm">
                            <tbody>
                                {props.collection.sharees?.map((sharee) => (
                                    <ShareeRow
                                        key={sharee.email}
                                        sharee={sharee}
                                        collectionUnshare={collectionUnshare}
                                    />
                                ))}
                            </tbody>
                        </Table>
                    </>
                )}
                <div
                    style={{
                        height: '1px',
                        marginTop: '10px',
                        marginBottom: '18px',
                        background: '#444',
                        width: '100%',
                    }}
                />
                <div>
                    <FlexWrapper>
                        <FlexWrapper
                            style={{ paddingTop: '5px', color: '#fff' }}>
                            {constants.PUBLIC_SHARING}
                        </FlexWrapper>
                        <Form.Switch
                            style={{ marginLeft: '20px' }}
                            checked={!!publicShareUrl}
                            id="collection-public-sharing-toggler"
                            className="custom-switch-md"
                            onChange={handleCollectionPublicSharing}
                        />
                    </FlexWrapper>
                    {sharableLinkError && (
                        <FlexWrapper
                            style={{
                                marginTop: '10px',
                                color: getVariantColor(ButtonVariant.danger),
                            }}>
                            {sharableLinkError}
                        </FlexWrapper>
                    )}
                </div>
                {publicShareUrl ? (
                    <>
                        <CodeBlock
                            wordBreak={'break-all'}
                            code={publicShareUrl}
                        />
                        <details style={{ width: '100%' }}>
                            <summary
                                onClick={(e) => {
                                    const lastOptionRow: Element =
                                        e.currentTarget.nextElementSibling
                                            .lastElementChild;
                                    const main = async (
                                        lastOptionRow: Element
                                    ) => {
                                        await sleep(0);
                                        lastOptionRow.scrollIntoView(true);
                                    };
                                    main(lastOptionRow);
                                }}
                                className="manageLinkHeader"
                                style={{ marginBottom: '20px' }}>
                                {constants.MANAGE_LINK}
                            </summary>
                            <section>
                                <OptionRow>
                                    <OptionLabel>
                                        {constants.LINK_DEVICE_LIMIT}
                                    </OptionLabel>
                                    <OptionValue>
                                        <Select
                                            menuPosition="fixed"
                                            options={deviceLimitOptions}
                                            isSearchable={false}
                                            value={{
                                                label: publicShareProp?.deviceLimit.toString(),
                                                value: publicShareProp?.deviceLimit,
                                            }}
                                            onChange={(e) =>
                                                updateDeviceLimit(e.value)
                                            }
                                            styles={DropdownStyle}
                                        />
                                    </OptionValue>
                                </OptionRow>

                                <OptionRow>
                                    <OptionLabel
                                        style={{ alignItems: 'center' }}>
                                        {constants.LINK_EXPIRY}
                                    </OptionLabel>
                                    <OptionValue>
                                        <Select
                                            menuPosition="fixed"
                                            options={expiryOptions}
                                            isSearchable={false}
                                            value={null}
                                            placeholder={
                                                publicShareProp?.validTill
                                                    ? dateStringWithMMH(
                                                          publicShareProp?.validTill
                                                      )
                                                    : 'never'
                                            }
                                            onChange={(e) => {
                                                updateDeviceExpiry(e.value);
                                            }}
                                            styles={linkExpiryStyle}
                                        />
                                    </OptionValue>
                                </OptionRow>
                                <OptionRow>
                                    <OptionLabel>
                                        {constants.FILE_DOWNLOAD}
                                    </OptionLabel>
                                    <OptionValue>
                                        <Form.Switch
                                            style={{ marginLeft: '10px' }}
                                            checked={
                                                publicShareProp?.enableDownload ??
                                                false
                                            }
                                            id="public-sharing-file-download-toggler"
                                            className="custom-switch-md"
                                            onChange={handleFileDownloadSetting}
                                        />
                                    </OptionValue>
                                </OptionRow>

                                <OptionRow>
                                    <OptionLabel>
                                        {constants.LINK_PASSWORD_LOCK}{' '}
                                    </OptionLabel>
                                    <OptionValue>
                                        <Form.Switch
                                            style={{ marginLeft: '10px' }}
                                            checked={
                                                publicShareProp?.passwordEnabled
                                            }
                                            id="public-sharing-file-password-toggler"
                                            className="custom-switch-md"
                                            onChange={
                                                handlePasswordChangeSetting
                                            }
                                        />
                                    </OptionValue>
                                </OptionRow>
                            </section>
                            <MessageDialog
                                show={configurePassword}
                                onHide={() => setConfigurePassword(false)}
                                size="sm"
                                attributes={{
                                    title: constants.PASSWORD_LOCK,
                                }}>
                                <SingleInputForm
                                    callback={savePassword}
                                    placeholder={
                                        constants.RETURN_PASSPHRASE_HINT
                                    }
                                    buttonText={constants.LOCK}
                                    fieldType="password"
                                />
                            </MessageDialog>
                        </details>
                    </>
                ) : (
                    <div
                        style={{
                            height: '1px',
                            marginTop: '28px',
                            width: '100%',
                        }}
                    />
                )}
            </DeadCenter>
        </MessageDialog>
    );
}
Example #17
Source File: bitcoin-table.tsx    From polkabtc-ui with Apache License 2.0 4 votes vote down vote up
export default function BitcoinTable(): ReactElement {
  const [relayStatus, setStatus] = useState('Online');
  const [fork, setFork] = useState(false);
  const [noData, setNoData] = useState(false);
  const [heightDiff, setHeightDiff] = useState(0);
  const [btcBlocks, setBlocks] = useState<Array<BlockInfo>>([]);
  const polkaBtcLoaded = useSelector((state: StoreType) => state.general.polkaBtcLoaded);
  const { t } = useTranslation();

  useEffect(() => {
    /**
     * Checks for BTC-Relay status.
     * TODO: check parachain for invalid state
     * TODO: check parachain for ongoing fork
     */

    const getRelayStatus = (): string => {
      let status = 'Online';
      if (noData) {
        status = 'Unknown header';
      }
      if (fork) {
        status = 'Fork';
      }
      if (heightDiff > constants.BTC_RELAY_DELAY_CRITICAL) {
        status = 'More than ' + constants.BTC_RELAY_DELAY_CRITICAL + ' blocks behind.';
      }
      return status;
    };

    const fetchData = async () => {
      if (!polkaBtcLoaded) return;

      // Returns a little endian encoded block hash
      // Converting to big endian for display
      const bestParachainBlock = reverseHashEndianness(await window.polkaBTC.btcRelay.getLatestBlock());
      const bestParachainHeight = Number(await window.polkaBTC.btcRelay.getLatestBlockHeight());

      let bestBitcoinBlock = '-';
      let bestBitcoinHeight = 0;

      try {
        // Returns a big endian encoded block hash
        bestBitcoinBlock = await window.polkaBTC.electrsAPI.getLatestBlock();
        bestBitcoinHeight = await window.polkaBTC.electrsAPI.getLatestBlockHeight();
      } catch (error) {
        // network error
      }

      // Check for NO_DATA, forks and height difference
      setNoData(bestBitcoinBlock !== bestParachainBlock && bestBitcoinHeight < bestParachainHeight);

      // TODO: get fork info from parachain. Not possible to check in UI.
      setFork(false);

      setHeightDiff(bestBitcoinHeight - bestParachainHeight);

      setStatus(getRelayStatus());
      setBlocks([
        {
          source: 'BTC Parachain',
          hash: bestParachainBlock,
          height: bestParachainHeight.toString()
        },
        {
          source: 'Bitcoin Core',
          hash: bestBitcoinBlock,
          height: bestBitcoinHeight.toString()
        }
      ]);
    };

    fetchData();
  }, [polkaBtcLoaded, noData, fork, heightDiff]);

  const getCircle = (status: string): string => {
    if (status === 'Online') {
      return 'green-circle';
    }
    if (status === 'Fork') {
      return 'orange-circle';
    }
    return 'red-circle';
  };

  const getHeightColor = (): string => {
    if (Math.abs(heightDiff) > constants.BTC_RELAY_DELAY_CRITICAL) {
      return 'red-text';
    }
    if (Math.abs(heightDiff) > constants.BTC_RELAY_DELAY_WARNING) {
      return 'orange-text';
    }
    return 'green-text';
  };

  return (
    <div style={{ margin: '40px 0px' }}>
      <div>
        <p
          className='mb-4'
          style={{
            fontWeight: 700,
            fontSize: '26px'
          }}>
          {t('dashboard.relay.btc_relay')}
        </p>
        <div className='header'>
          {t('status_colon')} &nbsp; <div className={getCircle(relayStatus)}></div> &nbsp; {relayStatus}
        </div>
      </div>
      <Table
        hover
        responsive
        size='md'>
        <thead>
          <tr>
            <th>{t('source')}</th>
            <th>{t('best_block_hash')}</th>
            <th>{t('best_block_height')}</th>
          </tr>
        </thead>
        <tbody>
          {btcBlocks.map((block, index) => {
            return (
              <tr key={index}>
                <td>{block.source}</td>
                <td>
                  <InterlayLink
                    href={BTC_BLOCK_API + block.hash}
                    target='_blank'
                    rel='noopener noreferrer'>
                    {block.hash}
                  </InterlayLink>
                </td>
                <td className={getHeightColor()}>{block.height}</td>
              </tr>
            );
          })}
        </tbody>
      </Table>
    </div>
  );
}
Example #18
Source File: index.tsx    From nouns-monorepo with GNU General Public License v3.0 4 votes vote down vote up
ProfileActivityFeed: React.FC<ProfileActivityFeedProps> = props => {
  const { nounId } = props;

  const MAX_EVENTS_SHOW_ABOVE_FOLD = 5;

  const [truncateProposals, setTruncateProposals] = useState(true);

  const { loading, error, data } = useQuery(nounVotingHistoryQuery(nounId));
  const {
    loading: proposalTimestampLoading,
    error: proposalTimestampError,
    data: proposalCreatedTimestamps,
  } = useQuery(createTimestampAllProposals());

  const nounCanVoteTimestamp = useNounCanVoteTimestamp(nounId);

  const { data: proposals } = useAllProposals();

  if (loading || !proposals || !proposals.length || proposalTimestampLoading) {
    return <></>;
  } else if (error || proposalTimestampError) {
    return (
      <div>
        <Trans>Failed to fetch Noun activity history</Trans>
      </div>
    );
  }

  const nounVotes: { [key: string]: NounVoteHistory } = data.noun.votes
    .slice(0)
    .reduce((acc: any, h: NounVoteHistory, i: number) => {
      acc[h.proposal.id] = h;
      return acc;
    }, {});

  const filteredProposals = proposals.filter((p: Proposal, id: number) => {
    return (
      parseInt(proposalCreatedTimestamps.proposals[id].createdTimestamp) >
        nounCanVoteTimestamp.toNumber() ||
      (p.id && nounVotes[p.id])
    );
  });

  return (
    <Section fullWidth={false}>
      <Col lg={{ span: 10, offset: 1 }}>
        <div className={classes.headerWrapper}>
          <h1>
            <Trans>Activity</Trans>
          </h1>
        </div>
        {filteredProposals && filteredProposals.length ? (
          <>
            <Table responsive hover className={classes.aboveTheFoldEventsTable}>
              <tbody className={classes.nounInfoPadding}>
                {filteredProposals?.length ? (
                  filteredProposals
                    .slice(0)
                    .reverse()
                    .slice(0, MAX_EVENTS_SHOW_ABOVE_FOLD)
                    .map((p: Proposal, i: number) => {
                      const vote = p.id ? nounVotes[p.id] : undefined;
                      return <NounProfileVoteRow proposal={p} vote={vote} key={i} />;
                    })
                ) : (
                  <LoadingNoun />
                )}
              </tbody>
            </Table>
            <Collapse in={!truncateProposals}>
              <div>
                <Table responsive hover>
                  <tbody className={classes.nounInfoPadding}>
                    {filteredProposals?.length ? (
                      filteredProposals
                        .slice(0)
                        .reverse()
                        .slice(MAX_EVENTS_SHOW_ABOVE_FOLD, filteredProposals.length)
                        .map((p: Proposal, i: number) => {
                          const vote = p.id ? nounVotes[p.id] : undefined;
                          return <NounProfileVoteRow proposal={p} vote={vote} key={i} />;
                        })
                    ) : (
                      <LoadingNoun />
                    )}
                  </tbody>
                </Table>
              </div>
            </Collapse>

            {filteredProposals.length <= MAX_EVENTS_SHOW_ABOVE_FOLD ? (
              <></>
            ) : (
              <>
                {truncateProposals ? (
                  <div
                    className={classes.expandCollapseCopy}
                    onClick={() => setTruncateProposals(false)}
                  >
                    <Trans>Show all {filteredProposals.length} events </Trans>{' '}
                    <FontAwesomeIcon icon={faChevronDown} />
                  </div>
                ) : (
                  <div
                    className={classes.expandCollapseCopy}
                    onClick={() => setTruncateProposals(true)}
                  >
                    <Trans>Show fewer</Trans> <FontAwesomeIcon icon={faChevronUp} />
                  </div>
                )}
              </>
            )}
          </>
        ) : (
          <div className={classes.nullStateCopy}>
            <Trans>This Noun has no activity, since it was just created. Check back soon!</Trans>
          </div>
        )}
      </Col>
    </Section>
  );
}
Example #19
Source File: CommandCodesPage.tsx    From apps with MIT License 4 votes vote down vote up
render() {
        if (this.state.error) return <ErrorStatus error={this.state.error} />;

        if (this.state.loading) return <Loading />;

        return (
            <div id="command-codes" className="listing-page">
                <Row>
                    <Col sm={6} md={5} id="item-rarity">
                        <ButtonGroup>
                            {[...new Set(this.state.commandCodes.map((s) => s.rarity))]
                                // deduplicate star counts
                                .sort((a, b) => a - b)
                                // sort
                                .map((rarity) => (
                                    <Button
                                        variant={
                                            this.state.activeRarityFilters.includes(rarity) ? "success" : "outline-dark"
                                        }
                                        key={rarity}
                                        onClick={(_) => this.toggleRarityFilter(rarity)}
                                    >
                                        {rarity} ★
                                    </Button>
                                ))}
                        </ButtonGroup>
                    </Col>
                    <Col sm={6} md={3} id="item-search">
                        <Form inline>
                            <Form.Control
                                placeholder={"Search"}
                                value={this.state.search ?? ""}
                                onChange={(ev: ChangeEvent) => {
                                    this.setState({ search: ev.target.value });
                                }}
                            />
                        </Form>
                    </Col>
                </Row>

                <hr />

                <Table striped bordered hover responsive>
                    <thead>
                        <tr>
                            <th className="col-center">#</th>
                            <th className="col-center">Thumbnail</th>
                            <th>Name</th>
                            <th className="rarity-col">Rarity</th>
                        </tr>
                    </thead>
                    <tbody>
                        {this.commandCodes().map((commandCode) => {
                            const route = `/${this.props.region}/command-code/${commandCode.collectionNo}`;

                            return (
                                <tr key={commandCode.id}>
                                    <td className="col-center">
                                        <Link to={route}>{commandCode.collectionNo}</Link>
                                    </td>
                                    <td className="col-center">
                                        <Link to={route}>
                                            <FaceIcon
                                                rarity={commandCode.rarity}
                                                location={commandCode.face}
                                                height={50}
                                            />
                                        </Link>
                                    </td>
                                    <td>
                                        <Link to={route}>{commandCode.name}</Link>
                                    </td>
                                    <td className="rarity-col">
                                        <RarityDescriptor rarity={commandCode.rarity} />
                                    </td>
                                </tr>
                            );
                        })}
                    </tbody>
                </Table>
            </div>
        );
    }
Example #20
Source File: IpfsStatsView.tsx    From 3Speak-app with GNU General Public License v3.0 4 votes vote down vote up
export function IpfsStatsView() {
  const [stats, setStats] = useState({} as any)
  const [repoSize, setRepoSize] = useState('')
  const [repoPath, setRepoPath] = useState('')
  const loopPid = useRef<any>()

  const update = async () => {
    const { ipfs } = await IpfsHandler.getIpfs()
    const out = {}
    for await (const theStats of ipfs.stats.bw()) {
      for (const key of Object.keys(theStats)) {
        const stat = Number(theStats[key])
        out[key] = bytesAsString(stat)
      }
    }
    const repoRes = await ipfs.stats.repo()
    setRepoPath(repoRes.path)
    setRepoSize(bytesAsString(Number(repoRes.repoSize)))
    setStats(out)
  }

  useEffect(() => {
    loopPid.current = setInterval(update, 500)

    return () => {
      clearInterval(loopPid.current)
    }
  }, [])

  return (
    <Table responsive="sm">
      <thead>
        <tr>
          <th>#</th>
          <th>In</th>
          <th>Out</th>
          <th>Total In</th>
          <th>Total Out</th>
        </tr>
      </thead>
      <tbody>
        <tr key="Main">
          <td></td>
          <td>
            <strong>{stats.rateIn} /s</strong>
          </td>
          <td>
            <strong>{stats.rateOut} /s</strong>
          </td>
          <td>
            <strong>{stats.totalIn}</strong>
          </td>
          <td>
            <strong>{stats.totalOut}</strong>
          </td>
        </tr>
        ,
      </tbody>
      <thead>
        <tr>
          <th>#</th>
          <th>Repo Size</th>
          <th>Repo Path</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <th></th>
          <th>{repoSize}</th>
          <th>
            {repoPath}
            <Button
              style={{ marginLeft: '5px' }}
              className="btn-sm"
              onClick={() => {
                void shell.openPath(repoPath)
              }}
            >
              Open
            </Button>
          </th>
        </tr>
      </tbody>
    </Table>
  )
}
Example #21
Source File: EffectBreakdownLines.tsx    From apps with MIT License 4 votes vote down vote up
render() {
        const effectStyle = this.props.popOver ? { maxWidth: "400px" } : { width: "45%", minWidth: "300px" };
        return (
            <React.Fragment>
                {this.props.cooldowns && (this.props.level || this.props.levels) ? (
                    <tr>
                        <td style={effectStyle}>Cooldown</td>
                        {this.props.cooldowns.map((cooldown, index) => {
                            return <td key={index}>{cooldown}</td>;
                        })}
                    </tr>
                ) : null}
                {this.props.cooldowns && !this.props.level && !this.props.levels ? (
                    <tr>
                        <td style={effectStyle}>Cooldown {this.props.cooldowns.join(", ")} turn(s)</td>
                    </tr>
                ) : null}
                {this.props.scripts ? (
                    <ScriptBreakdown region={this.props.region} scripts={this.props.scripts} />
                ) : null}
                {this.props.gain ? (
                    <tr>
                        <td style={effectStyle}>NP Gain</td>
                        {[...Array(this.props.level)].map((_, key) => {
                            return (
                                <td key={key}>
                                    {asPercent(this.props.gain?.buster[key], 2)} <CardType card={Card.BUSTER} />
                                    <br />
                                    {asPercent(this.props.gain?.arts[key], 2)} <CardType card={Card.ARTS} />
                                    <br />
                                    {asPercent(this.props.gain?.quick[key], 2)} <CardType card={Card.QUICK} />
                                    <br />
                                    {asPercent(this.props.gain?.extra[key], 2)} <CardType card={Card.EXTRA} />
                                    <br />
                                    {asPercent(this.props.gain?.np[key], 2)} NP
                                    <br />
                                    {asPercent(this.props.gain?.defence[key], 2)} Def
                                </td>
                            );
                        })}
                    </tr>
                ) : null}
                {this.props.funcs.map((func, index) => {
                    let mutatingDescriptions = describeMutators(this.props.region, func),
                        relatedSkillIds = FuncDescriptor.getRelatedSkillIds(func).filter(
                            (skill) => !this.props.triggerSkillIdStack.includes(skill.skillId)
                        ),
                        relatedNpIds = FuncDescriptor.getRelatedNpIds(func),
                        additionalSkillRow = <></>;

                    if (index === this.props.funcs.length - 1 && this.props.additionalSkillId) {
                        relatedSkillIds.push({
                            skillId: this.props.additionalSkillId[0],
                            skillLvs: [this.props.additionalSkillId.length],
                        });

                        additionalSkillRow = (
                            <tr>
                                <td style={effectStyle}>
                                    Additional skill:{" "}
                                    <SkillReferenceDescriptor
                                        region={this.props.region}
                                        id={this.props.additionalSkillId[0]}
                                    />
                                </td>
                            </tr>
                        );
                    }

                    for (let i = 0; i < (this.props.level ?? 0); i++) {
                        if (!mutatingDescriptions[i]) mutatingDescriptions.push("-");
                    }

                    return (
                        <React.Fragment key={index}>
                            <tr>
                                <td style={effectStyle}>
                                    {this.props.relatedSkillId ? (
                                        <>
                                            <SkillReferenceDescriptor
                                                region={this.props.region}
                                                id={this.props.relatedSkillId}
                                            />{" "}
                                        </>
                                    ) : null}
                                    {this.props.relatedNpId ? (
                                        <>
                                            <NoblePhantasmDescriptorId
                                                region={this.props.region}
                                                noblePhantasmId={this.props.relatedNpId}
                                            />{" "}
                                        </>
                                    ) : null}
                                    <FuncDescription
                                        region={this.props.region}
                                        func={func}
                                        levels={this.props.levels}
                                    />
                                </td>
                                {this.props.level
                                    ? mutatingDescriptions.map((description, index) => {
                                          if (this.props.levels) {
                                              if (this.props.levels.includes(index + 1)) {
                                                  return <td key={index}>{description}</td>;
                                              } else if (
                                                  index + 1 >= Math.max(...this.props.levels) &&
                                                  index < (this.props.level ?? 0)
                                              ) {
                                                  return <td key={index}>-</td>;
                                              } else {
                                                  return null;
                                              }
                                          } else {
                                              return <td key={index}>{description}</td>;
                                          }
                                      })
                                    : null}
                            </tr>
                            {additionalSkillRow}
                            {relatedSkillIds.map((relatedSkill) => {
                                return (
                                    <tr className="trigger-skill" key={relatedSkill.skillId}>
                                        <td colSpan={11}>
                                            <CollapsibleLight
                                                title={
                                                    <span className="trigger-skill-name">
                                                        {relatedSkill.skillId}:{" "}
                                                        <SkillReferenceDescriptor
                                                            region={this.props.region}
                                                            id={relatedSkill.skillId}
                                                        />
                                                    </span>
                                                }
                                                content={
                                                    <>
                                                        <Table>
                                                            <tbody>
                                                                <AdditionalEffectBreakdown
                                                                    key={relatedSkill.skillId}
                                                                    region={this.props.region}
                                                                    id={relatedSkill.skillId}
                                                                    triggerSkillIdStack={this.props.triggerSkillIdStack.concat(
                                                                        [relatedSkill.skillId]
                                                                    )}
                                                                    levels={relatedSkill.skillLvs}
                                                                    level={this.props.level}
                                                                    popOver={this.props.popOver}
                                                                />
                                                            </tbody>
                                                        </Table>
                                                    </>
                                                }
                                                eventKey={relatedSkill.skillId.toString()}
                                                defaultActiveKey={relatedSkill.skillId.toString()}
                                            />
                                        </td>
                                    </tr>
                                );
                            })}
                            {relatedNpIds.map((relatedNp) => {
                                return (
                                    <tr className="trigger-skill" key={relatedNp.npId}>
                                        <td colSpan={6}>
                                            <CollapsibleLight
                                                title={
                                                    <span className="trigger-skill-name">
                                                        {relatedNp.npId}:{" "}
                                                        <NoblePhantasmDescriptorId
                                                            region={this.props.region}
                                                            noblePhantasmId={relatedNp.npId}
                                                        />
                                                    </span>
                                                }
                                                content={
                                                    <>
                                                        <Table>
                                                            <tbody>
                                                                <AdditionalEffectBreakdown
                                                                    key={relatedNp.npId}
                                                                    region={this.props.region}
                                                                    id={relatedNp.npId}
                                                                    isNp={true}
                                                                    triggerSkillIdStack={this.props.triggerSkillIdStack.concat(
                                                                        [relatedNp.npId]
                                                                    )}
                                                                    levels={relatedNp.npLvs}
                                                                    level={this.props.level}
                                                                    popOver={this.props.popOver}
                                                                />
                                                            </tbody>
                                                        </Table>
                                                    </>
                                                }
                                                eventKey={relatedNp.npId.toString()}
                                                defaultActiveKey={relatedNp.npId.toString()}
                                            />
                                        </td>
                                    </tr>
                                );
                            })}
                        </React.Fragment>
                    );
                })}
            </React.Fragment>
        );
    }