semantic-ui-react#Tab TypeScript Examples
The following examples show how to use
semantic-ui-react#Tab.
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: citeoptimizer.tsx From website with MIT License | 6 votes |
render() {
let { citeData } = this.state;
return (
<>
<Segment>
{!citeData &&
<>
<Icon loading name='spinner' /> Loading citation optimizer ...
</>
}
{citeData &&
<Tab panes={[
{ menuItem: 'Crew To Cite', render: () => this.renderTable(citeData.crewToCite, false) },
{ menuItem: 'Crew To Train', render: () => this.renderTable(citeData.crewToTrain, true) }
]} />
}
<Rail position='right'>
<h3>Explanation</h3>
<p>
A crew's Expected Value (EV) is the average you can expect a crew to contribute to all voyages. EV Final accounts for the crew fully fused. EV Left, while less important, calculates the difference in contribution between fully fused and their current rank. Voyages Improved is how many of the voyage combinations the crew contributes to. Primary and secondary are taken into account, because CMD/DIP voyage will yield different results than DIP/CMD.
</p>
<p>
A crew's EV for a voyage is found by finding the crew's average for the skill "Base + (Min + Max) / 2", multiplying that by 0.35 if the skill is the primary for the voyage, 0.25 if it is secondary, and 0.1 otherwise. To find how much the crew contributes to the total voyage, we find the best crew for the voyage that are fully leveled and equipped.
</p>
<p>
"Training" is considered simply leveling and equipping the considered crew <u>at their current rarity</u>. This is done by comparing the current total EV of all voyages with those as if the considered crew were fully leveled and equiped <u>at current rarity</u>.
</p>
<p>
"Citing" considered <u>fully fusing</u>, leveling and equipping the considered crew. This is done by comparing the current total EV of all voyages with those as if the considered crew were fully leveled and equiped <u>and fused</u>.
</p>
</Rail>
</Segment>
</>
);
}
Example #2
Source File: event_info_modal.tsx From website with MIT License | 5 votes |
function EventInfoModal({instanceId, image, hasDetails, leaderboard}: EventInfoModalProps) {
const [eventData, setEventData] = React.useState(null);
React.useEffect(() => {
async function fetchEventData() {
if (hasDetails) {
const fetchResp = await fetch(`/structured/events/${instanceId}.json`);
const data = await fetchResp.json();
setEventData(data);
}
}
fetchEventData();
}, []);
const eventInfoPanes = [
{
menuItem: 'Event Information',
render: () => (
<Tab.Pane attached={false}>
<EventInformationTab eventData={eventData} />
</Tab.Pane>
),
},
{
menuItem: 'Threshold Rewards',
render: () => (
<Tab.Pane attached={false}>
<ThresholdRewardsTab eventData={eventData} />
</Tab.Pane>
),
},
{
menuItem: 'Ranked Rewards',
render: () => (
<Tab.Pane attached={false}>
<RankedRewardsTab eventData={eventData} />
</Tab.Pane>
),
},
];
const leaderboardPane = [
{
menuItem: 'Leaderboard',
render: () => (
<Tab.Pane attached={false}>
<LeaderboardTab leaderboard={leaderboard} />
</Tab.Pane>
),
},
];
let panes;
if (hasDetails && eventData) {
panes = eventInfoPanes.concat(leaderboardPane);
} else {
panes = leaderboardPane;
}
return (
<Container style={{ padding: '1em' }}>
<Image
src={`${process.env.GATSBY_ASSETS_URL}${image}`}
fluid
/>
<Tab
style={{marginTop: '1em'}}
menu={{secondary: true, pointing: true}}
panes={panes}
renderActiveOnly
/>
</Container>
);
}
Example #3
Source File: voyagecalculator.tsx From website with MIT License | 5 votes |
VoyageResultPane = (props: VoyageResultPaneProps) => {
const { result, requests, requestId, calcState, abortCalculation } = props;
const request = requests.find(r => r.id == requestId);
if (!request) return (<></>);
if (!result) {
return (
<Tab.Pane>
<div style={{ textAlign: 'center' }}>
<Image centered src='/media/voyage-wait-icon.gif' />
<Button onClick={() => abortCalculation(request.id)}>Abort</Button>
</div>
</Tab.Pane>
);
}
// resultToVoyageData
let data = {...request.voyageConfig};
if (result.entries) {
result.entries.forEach((entry, idx) => {
let acrew = request.consideredCrew.find(c => c.symbol === entry.choice.symbol);
data.crew_slots[entry.slotId].crew = acrew;
});
}
data.skill_aggregates = result.aggregates;
data.max_hp = result.startAM;
data.state = 'pending';
const renderCalculatorMessage = () => {
if (calcState != CalculatorState.Done) {
return (
<>
<Image inline size='mini' src='/media/voyage-wait-icon.gif' />
Calculation in progress. Please wait...{` `}
<Button size='mini' onClick={() => abortCalculation(request.id)}>Abort</Button>
</>
);
}
let inputs = Object.entries(request.calcOptions).map(entry => entry[0]+': '+entry[1]);
inputs.unshift('considered crew: '+request.consideredCrew.length);
return (
<>
Calculated by <b>{request.calcName}</b> calculator ({inputs.join(', ')}){` `}
in {((request.perf.end-request.perf.start)/1000).toFixed(2)} seconds!
{result.postscript && (<div>{result.postscript}</div>)}
</>
);
};
return (
<React.Fragment>
{calcState == CalculatorState.Done && (
<Message attached>
Estimate: <b>{formatTime(result.estimate.refills[0].result)}</b>{` `}
(expected range: {formatTime(result.estimate.refills[0].saferResult)} to{` `}
{formatTime(result.estimate.refills[0].moonshotResult)})
</Message>
)}
<Tab.Pane>
<VoyageStats
voyageData={data}
estimate={result.estimate}
ships={[request.bestShip]}
showPanels={['crew']}
/>
<div style={{ marginTop: '1em' }}>
{renderCalculatorMessage()}
</div>
</Tab.Pane>
</React.Fragment>
);
}
Example #4
Source File: voyagecalculator.tsx From website with MIT License | 4 votes |
VoyageInput = (props: VoyageInputProps) => {
const { voyageConfig, myCrew, allShips, useInVoyage } = props;
const [bestShip, setBestShip] = React.useState(undefined);
const [consideredCrew, setConsideredCrew] = React.useState([]);
const [calculator, setCalculator] = React.useState(isMobile ? 'ussjohnjay' : 'iampicard');
const [calcOptions, setCalcOptions] = React.useState({});
const [telemetryOptOut, setTelemetryOptOut] = useStateWithStorage('telemetryOptOut', false, { rememberForever: true });
const [requests, setRequests] = React.useState([]);
const [results, setResults] = React.useState([]);
React.useEffect(() => {
// Note that allShips is missing the default ship for some reason (1* Constellation Class)
// This WILL break voyagecalculator if that's the only ship a player owns
const consideredShips = [];
allShips.filter(ship => ship.owned).forEach(ship => {
const traited = ship.traits.find(trait => trait === voyageConfig.ship_trait);
let entry = {
ship: ship,
score: ship.antimatter + (traited ? 150 : 0),
traited: traited,
bestIndex: Math.min(ship.index.left, ship.index.right)
};
consideredShips.push(entry);
});
consideredShips.sort((a, b) => {
if (a.score === b.score) return a.bestIndex - b.bestIndex;
return b.score - a.score;
});
setBestShip(consideredShips[0]);
setRequests([]);
setResults([]);
}, [voyageConfig]);
React.useEffect(() => {
return function cleanup() {
// Cancel active calculations when leaving page
requests.forEach(request => {
if (request.calcState == CalculatorState.InProgress)
request.abort();
});
}
}, []);
// Scroll here when calculator started, finished
const topAnchor = React.useRef(null);
const calculators = CALCULATORS.helpers.map(helper => {
return { key: helper.id, value: helper.id, text: helper.name };
});
calculators.push({ key: 'all', value: 'all', text: 'All calculators (slower)' });
return (
<React.Fragment>
<div ref={topAnchor} />
{renderBestShip()}
{renderResults()}
{requests.length > 0 && <Header as='h3'>Options</Header>}
<Form>
<InputCrewOptions myCrew={myCrew} updateConsideredCrew={setConsideredCrew} />
<Form.Group inline>
<Form.Field
control={Select}
label='Calculator'
options={calculators}
value={calculator}
onChange={(e, { value }) => setCalculator(value)}
placeholder='Select calculator'
/>
{CALCULATORS.fields.filter(field => field.calculators.includes(calculator) || calculator == 'all').map(field => (
<Form.Field
key={field.id}
control={Select} /* Only control allowed at the moment */
label={field.name}
options={field.options}
value={calcOptions[field.id] ?? field.default}
placeholder={field.description}
onChange={(e, { value }) => setCalcOptions(prevOptions =>
{
const newValue = { [field.id]: value };
return {...prevOptions, ...newValue};
}
)}
/>
))}
</Form.Group>
<Form.Group>
<Form.Button primary onClick={() => startCalculation()}>
Calculate best crew selection
</Form.Button>
{voyageConfig.state &&
<Form.Button onClick={()=> useInVoyage()}>
Return to in voyage calculator
</Form.Button>
}
</Form.Group>
</Form>
<Message style={{ marginTop: '2em' }}>
<Message.Content>
<Message.Header>Privacy Notice</Message.Header>
<p>We use anonymous statistics aggregated from voyage calculations to improve DataCore and power our <b><Link to='/hall_of_fame'>Voyage Hall of Fame</Link></b>.</p>
<Form>
<Form.Field
control={Checkbox}
label={<label>Permit DataCore to collect anonymous voyage stats</label>}
checked={!telemetryOptOut}
onChange={(e, { checked }) => setTelemetryOptOut(!checked) }
/>
</Form>
</Message.Content>
</Message>
</React.Fragment>
);
function renderBestShip(): JSX.Element {
if (!bestShip) return (<></>);
const direction = bestShip.ship.index.right < bestShip.ship.index.left ? 'right' : 'left';
const index = bestShip.ship.index[direction] ?? 0;
return (
<Card fluid>
<Card.Content>
<Image floated='left' src={`${process.env.GATSBY_ASSETS_URL}${bestShip.ship.icon.file.substr(1).replace('/', '_')}.png`} style={{ height: '4em' }} />
<Card.Header>{bestShip.ship.name}</Card.Header>
<p>best ship{bestShip.traited && (<span style={{ marginLeft: '1em' }}>{` +`}{allTraits.ship_trait_names[voyageConfig.ship_trait]}</span>)}</p>
<p style={{ marginTop: '.5em' }}>Tap <Icon name={`arrow ${direction}`} />{index} time{index != 1 ? 's' : ''} on your voyage ship selection screen to select {bestShip.ship.name}.</p>
</Card.Content>
</Card>
);
}
function renderResults(): JSX.Element {
if (results.length == 0)
return (<></>);
const showPopup = (result) => <Popup basic content={<p>{result.result.postscript}</p>} trigger={<p>{result.name}</p>} />
const panes = results.map(result => ({
menuItem: { key: result.id, content: result.result ? showPopup(result) : result.name },
render: () => (
<VoyageResultPane result={result.result}
requests={requests} requestId={result.requestId}
calcState={result.calcState} abortCalculation={abortCalculation}
/>
)
}));
return (
<React.Fragment>
<Header as='h3'>Recommended Lineups</Header>
<Tab menu={{ pointing: true }}
panes={panes}
/>
</React.Fragment>
);
}
function scrollToAnchor(): void {
if (!topAnchor.current) return;
topAnchor.current.scrollIntoView({
behavior: 'smooth'
}, 500);
}
function startCalculation(): void {
const helperConfig = {
voyageConfig, bestShip, consideredCrew, calcOptions,
resultsCallback: handleResults,
isMobile
};
CALCULATORS.helpers.forEach(helper => {
if (helper.id == calculator || calculator == 'all') {
const request = helper.helper(helperConfig);
requests.push(request);
results.push({
id: request.id,
requestId: request.id,
name: 'Calculating...',
calcState: CalculatorState.InProgress
});
request.start();
}
});
setRequests([...requests]);
setResults([...results]);
scrollToAnchor();
}
function handleResults(requestId: string, reqResults: any[], calcState: number): void {
reqResults.forEach((reqResult, idx) => {
// Update existing pane with results
if (idx == 0) {
setResults(prevResults => {
const result = prevResults.find(r => r.id == requestId);
if (calcState == CalculatorState.Done) {
result.name = formatTime(reqResult.estimate.refills[0].result);
result.calcState = CalculatorState.Done;
sendTelemetry(requestId, reqResult);
}
result.result = reqResult;
return [...prevResults];
});
}
// Add new panes if multiple results generated by this request
else {
setResults(prevResults => [...prevResults, {
id: requestId+'-'+idx,
requestId,
name: formatTime(reqResult.estimate.refills[0].result),
calcState: CalculatorState.Done,
result: reqResult
}]);
}
});
if (calcState == CalculatorState.Done) scrollToAnchor();
}
function abortCalculation(requestId: string): void {
const request = requests.find(r => r.id == requestId);
if (request) {
request.abort();
setResults(prevResults => {
const result = prevResults.find(prev => prev.id == requestId);
if (result.result) {
result.name = formatTime(result.result.estimate.refills[0].result);
result.calcState = CalculatorState.Done;
}
else {
const index = prevResults.findIndex(prev => prev.id == requestId);
prevResults.splice(index, 1);
}
return [...prevResults];
});
}
}
function sendTelemetry(requestId: string, result: any): void {
if (telemetryOptOut) return;
const request = requests.find(r => r.id == requestId);
const estimatedDuration = result.estimate.refills[0].result*60*60;
try {
fetch(`${process.env.GATSBY_DATACORE_URL}api/telemetry`, {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
type: 'voyageCalc',
data: {
voyagers: result.entries.map((entry) => entry.choice.symbol),
estimatedDuration,
calculator: request ? request.calculator : ''
}
})
});
}
catch (err) {
console.log('An error occurred while sending telemetry', err);
}
}
}
Example #5
Source File: profile.tsx From website with MIT License | 4 votes |
renderDesktop() {
const { playerData } = this.state;
const panes = [
{
menuItem: 'Crew',
render: () => <ProfileCrew playerData={this.state.playerData} />
},
{
menuItem: 'Crew (mobile)',
render: () => <ProfileCrewMobile playerData={this.state.playerData} isMobile={false} />
},
{
menuItem: 'Ships',
render: () => <ProfileShips playerData={this.state.playerData} />
},
{
menuItem: 'Items',
render: () => <ProfileItems playerData={this.state.playerData} />
},
{
menuItem: 'Other',
render: () => <ProfileOther playerData={this.state.playerData} />
},
{
menuItem: 'Charts & Stats',
render: () => <ProfileCharts playerData={this.state.playerData} />
}
];
return (
<Layout title={playerData.player.character.display_name}>
<Item.Group>
<Item>
<Item.Image
size='tiny'
src={`${process.env.GATSBY_ASSETS_URL}${playerData.player.character.crew_avatar
? playerData.player.character.crew_avatar.portrait
: 'crew_portraits_cm_empty_sm.png'
}`}
/>
<Item.Content>
<Item.Header>{playerData.player.character.display_name}</Item.Header>
<Item.Meta>
<Label>VIP {playerData.player.vip_level}</Label>
<Label>Level {playerData.player.character.level}</Label>
<Label>{playerData.calc.numImmortals} crew</Label>
<Label>{playerData.player.character.shuttle_bays} shuttles</Label>
</Item.Meta>
<Item.Description>
{playerData.player.fleet && (
<p>
Fleet{' '}
<Link to={`/fleet_info?fleetid=${playerData.player.fleet.id}`}>
<b>{playerData.player.fleet.slabel}</b>
</Link>{' '}
({playerData.player.fleet.rank}) Starbase level {playerData.player.fleet.nstarbase_level}{' '}
</p>
)}
</Item.Description>
</Item.Content>
</Item>
</Item.Group>
<Menu compact>
<Menu.Item>
{playerData.calc.lastModified ? <span>Last updated: {playerData.calc.lastModified.toLocaleString()}</span> : <span />}
</Menu.Item>
<Dropdown item text='Download'>
<Dropdown.Menu>
<Dropdown.Item onClick={() => this._exportExcel()}>Complete spreadsheet (XLSX)</Dropdown.Item>
<Dropdown.Item onClick={() => this._exportCrew()}>Crew table (CSV)</Dropdown.Item>
<Dropdown.Item onClick={() => this._exportShips()}>Ship table (CSV)</Dropdown.Item>
<Dropdown.Item onClick={() => this._exportItems()}>Item table (CSV)</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
</Menu>
<Tab menu={{ secondary: true, pointing: true }} panes={panes} />
</Layout>
);
}