mirror of
https://github.com/PeWu/topola-viewer.git
synced 2026-02-18 02:55:48 +00:00
Refactored WikiTreeMenu component from class-based to functional
This commit is contained in:
parent
be3592f51b
commit
b6c96ae336
@ -1,12 +1,12 @@
|
|||||||
import * as queryString from 'query-string';
|
import * as queryString from 'query-string';
|
||||||
import * as React from 'react';
|
|
||||||
import wikitreeLogo from './wikitree.png';
|
import wikitreeLogo from './wikitree.png';
|
||||||
import {analyticsEvent} from '../util/analytics';
|
import {analyticsEvent} from '../util/analytics';
|
||||||
|
import {Button, Form, Header, Input, Modal} from 'semantic-ui-react';
|
||||||
|
import {Component, createRef, useEffect, useRef, useState} from 'react';
|
||||||
import {FormattedMessage, injectIntl, WrappedComponentProps} from 'react-intl';
|
import {FormattedMessage, injectIntl, WrappedComponentProps} from 'react-intl';
|
||||||
import {getLoggedInUserName} from '../datasource/wikitree';
|
import {getLoggedInUserName} from '../datasource/wikitree';
|
||||||
import {MenuItem, MenuType} from './menu_item';
|
import {MenuItem, MenuType} from './menu_item';
|
||||||
import {RouteComponentProps} from 'react-router-dom';
|
import {RouteComponentProps} from 'react-router-dom';
|
||||||
import {Header, Button, Modal, Input, Form, Ref} from 'semantic-ui-react';
|
|
||||||
|
|
||||||
enum WikiTreeLoginState {
|
enum WikiTreeLoginState {
|
||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
@ -18,81 +18,50 @@ interface Props {
|
|||||||
menuType: MenuType;
|
menuType: MenuType;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
|
||||||
dialogOpen: boolean;
|
|
||||||
wikiTreeId?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Displays and handles the "Select WikiTree ID" menu. */
|
/** Displays and handles the "Select WikiTree ID" menu. */
|
||||||
export class WikiTreeMenu extends React.Component<
|
export function WikiTreeMenu(props: RouteComponentProps & Props) {
|
||||||
RouteComponentProps & Props,
|
const [dialogOpen, setDialogOpen] = useState(false);
|
||||||
State
|
const [wikiTreeId, setWikiTreeId] = useState('');
|
||||||
> {
|
const inputRef = useRef<Input>(null);
|
||||||
state: State = {
|
|
||||||
dialogOpen: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
inputRef: React.RefObject<HTMLElement> = React.createRef();
|
useEffect(() => {
|
||||||
|
if (dialogOpen) {
|
||||||
private openDialog() {
|
setWikiTreeId('');
|
||||||
this.setState(Object.assign({}, this.state, {dialogOpen: true}), () =>
|
inputRef.current!.focus();
|
||||||
(this.inputRef.current!.firstChild as HTMLInputElement).focus(),
|
}
|
||||||
);
|
}, [dialogOpen]);
|
||||||
}
|
|
||||||
|
|
||||||
/** Cancels any of the open dialogs. */
|
|
||||||
private handleClose() {
|
|
||||||
this.setState(
|
|
||||||
Object.assign({}, this.state, {
|
|
||||||
dialogOpen: false,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Select button clicked in the "Select WikiTree ID" dialog. */
|
/** Select button clicked in the "Select WikiTree ID" dialog. */
|
||||||
private handleSelectId() {
|
function handleSelectId() {
|
||||||
this.setState(
|
setDialogOpen(false);
|
||||||
Object.assign({}, this.state, {
|
if (!wikiTreeId) {
|
||||||
dialogOpen: false,
|
return;
|
||||||
}),
|
|
||||||
);
|
|
||||||
if (this.state.wikiTreeId) {
|
|
||||||
analyticsEvent('wikitree_id_selected');
|
|
||||||
const search = queryString.parse(this.props.location.search);
|
|
||||||
const standalone =
|
|
||||||
search.standalone !== undefined ? search.standalone : true;
|
|
||||||
this.props.history.push({
|
|
||||||
pathname: '/view',
|
|
||||||
search: queryString.stringify({
|
|
||||||
indi: this.state.wikiTreeId,
|
|
||||||
source: 'wikitree',
|
|
||||||
standalone,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
analyticsEvent('wikitree_id_selected');
|
||||||
|
const search = queryString.parse(props.location.search);
|
||||||
/** Called when the WikiTree ID input is typed into. */
|
const standalone =
|
||||||
private handleIdChange(value: string) {
|
search.standalone !== undefined ? search.standalone : true;
|
||||||
this.setState(
|
props.history.push({
|
||||||
Object.assign({}, this.state, {
|
pathname: '/view',
|
||||||
wikiTreeId: value,
|
search: queryString.stringify({
|
||||||
|
indi: wikiTreeId,
|
||||||
|
source: 'wikitree',
|
||||||
|
standalone,
|
||||||
}),
|
}),
|
||||||
);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private enterId(event: React.MouseEvent, id: string) {
|
function enterId(event: React.MouseEvent, id: string) {
|
||||||
event.preventDefault(); // Do not follow link in href.
|
event.preventDefault(); // Do not follow link in href.
|
||||||
(this.inputRef.current!.firstChild as HTMLInputElement).value = id;
|
setWikiTreeId(id);
|
||||||
this.handleIdChange(id);
|
inputRef.current!.focus();
|
||||||
(this.inputRef.current!.firstChild as HTMLInputElement).focus();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private wikiTreeIdModal() {
|
function wikiTreeIdModal() {
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
open={this.state.dialogOpen}
|
open={dialogOpen}
|
||||||
onClose={() => this.handleClose()}
|
onClose={() => setDialogOpen(false)}
|
||||||
centered={false}
|
centered={false}
|
||||||
>
|
>
|
||||||
<Header>
|
<Header>
|
||||||
@ -107,7 +76,7 @@ export class WikiTreeMenu extends React.Component<
|
|||||||
/>
|
/>
|
||||||
</Header>
|
</Header>
|
||||||
<Modal.Content>
|
<Modal.Content>
|
||||||
<Form onSubmit={() => this.handleSelectId()}>
|
<Form onSubmit={handleSelectId}>
|
||||||
<p>
|
<p>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id="select_wikitree_id.comment"
|
id="select_wikitree_id.comment"
|
||||||
@ -126,7 +95,7 @@ export class WikiTreeMenu extends React.Component<
|
|||||||
),
|
),
|
||||||
example1: (
|
example1: (
|
||||||
<span
|
<span
|
||||||
onClick={(e) => this.enterId(e, 'Wojtyla-13')}
|
onClick={(e) => enterId(e, 'Wojtyla-13')}
|
||||||
className="link-span"
|
className="link-span"
|
||||||
>
|
>
|
||||||
Wojtyla-13
|
Wojtyla-13
|
||||||
@ -134,7 +103,7 @@ export class WikiTreeMenu extends React.Component<
|
|||||||
),
|
),
|
||||||
example2: (
|
example2: (
|
||||||
<span
|
<span
|
||||||
onClick={(e) => this.enterId(e, 'Skłodowska-2')}
|
onClick={(e) => enterId(e, 'Skłodowska-2')}
|
||||||
className="link-span"
|
className="link-span"
|
||||||
>
|
>
|
||||||
Skłodowska-2
|
Skłodowska-2
|
||||||
@ -143,22 +112,22 @@ export class WikiTreeMenu extends React.Component<
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
<Ref innerRef={this.inputRef}>
|
<Input
|
||||||
<Input
|
fluid
|
||||||
fluid
|
value={wikiTreeId}
|
||||||
onChange={(e, data) => this.handleIdChange(data.value)}
|
onChange={(_, data) => setWikiTreeId(data.value)}
|
||||||
/>
|
ref={inputRef}
|
||||||
</Ref>
|
/>
|
||||||
</Form>
|
</Form>
|
||||||
</Modal.Content>
|
</Modal.Content>
|
||||||
<Modal.Actions>
|
<Modal.Actions>
|
||||||
<Button secondary onClick={() => this.handleClose()}>
|
<Button secondary onClick={() => setDialogOpen(false)}>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id="select_wikitree_id.cancel"
|
id="select_wikitree_id.cancel"
|
||||||
defaultMessage="Cancel"
|
defaultMessage="Cancel"
|
||||||
/>
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
<Button primary onClick={() => this.handleSelectId()}>
|
<Button primary onClick={handleSelectId}>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id="select_wikitree_id.load"
|
id="select_wikitree_id.load"
|
||||||
defaultMessage="Load"
|
defaultMessage="Load"
|
||||||
@ -169,23 +138,18 @@ export class WikiTreeMenu extends React.Component<
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
return (
|
||||||
return (
|
<>
|
||||||
<>
|
<MenuItem menuType={props.menuType} onClick={() => setDialogOpen(true)}>
|
||||||
<MenuItem
|
<img src={wikitreeLogo} alt="WikiTree logo" className="menu-icon" />
|
||||||
menuType={this.props.menuType}
|
<FormattedMessage
|
||||||
onClick={() => this.openDialog()}
|
id="menu.select_wikitree_id"
|
||||||
>
|
defaultMessage="Select WikiTree ID"
|
||||||
<img src={wikitreeLogo} alt="WikiTree logo" className="menu-icon" />
|
/>
|
||||||
<FormattedMessage
|
</MenuItem>
|
||||||
id="menu.select_wikitree_id"
|
{wikiTreeIdModal()}
|
||||||
defaultMessage="Select WikiTree ID"
|
</>
|
||||||
/>
|
);
|
||||||
</MenuItem>
|
|
||||||
{this.wikiTreeIdModal()}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface LoginState {
|
interface LoginState {
|
||||||
@ -194,7 +158,7 @@ interface LoginState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Displays and handles the "Log in to WikiTree" menu. */
|
/** Displays and handles the "Log in to WikiTree" menu. */
|
||||||
class WikiTreeLoginMenuComponent extends React.Component<
|
class WikiTreeLoginMenuComponent extends Component<
|
||||||
RouteComponentProps & WrappedComponentProps & Props,
|
RouteComponentProps & WrappedComponentProps & Props,
|
||||||
LoginState
|
LoginState
|
||||||
> {
|
> {
|
||||||
@ -202,8 +166,8 @@ class WikiTreeLoginMenuComponent extends React.Component<
|
|||||||
wikiTreeLoginState: WikiTreeLoginState.UNKNOWN,
|
wikiTreeLoginState: WikiTreeLoginState.UNKNOWN,
|
||||||
};
|
};
|
||||||
|
|
||||||
wikiTreeLoginFormRef: React.RefObject<HTMLFormElement> = React.createRef();
|
wikiTreeLoginFormRef: React.RefObject<HTMLFormElement> = createRef();
|
||||||
wikiTreeReturnUrlRef: React.RefObject<HTMLInputElement> = React.createRef();
|
wikiTreeReturnUrlRef: React.RefObject<HTMLInputElement> = createRef();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redirect to the WikiTree Apps login page with a return URL pointing to
|
* Redirect to the WikiTree Apps login page with a return URL pointing to
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user