mirror of
https://github.com/pybricks/pybricks-code.git
synced 2026-09-12 09:36:27 +00:00
licenses: convert LicenseDialog to functions
This commit is contained in:
+108
-130
@@ -12,155 +12,133 @@ import {
|
||||
Dialog,
|
||||
NonIdealState,
|
||||
} from '@blueprintjs/core';
|
||||
import { WithI18nProps, withI18n } from '@shopify/react-i18n';
|
||||
import { useI18n } from '@shopify/react-i18n';
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { appName } from '../app/constants';
|
||||
import { RootState } from '../reducers';
|
||||
import { fetchList, select } from './actions';
|
||||
import { LicenseStringId } from './i18n';
|
||||
import en from './i18n.en.json';
|
||||
import { LicenseInfo, LicenseList } from './reducers';
|
||||
import { LicenseInfo } from './reducers';
|
||||
|
||||
import './license.scss';
|
||||
|
||||
type StateProps = {
|
||||
licenseList: LicenseList | null;
|
||||
licenseInfo: LicenseInfo | null;
|
||||
type LicenseListPanelProps = {
|
||||
onItemClick(info: LicenseInfo): void;
|
||||
};
|
||||
|
||||
type DispatchProps = {
|
||||
onOpening: () => void;
|
||||
onSelectPackage: (info: LicenseInfo) => void;
|
||||
const LicenseListPanel: React.VoidFunctionComponent<LicenseListPanelProps> = (
|
||||
props,
|
||||
) => {
|
||||
const licenseList = useSelector((state: RootState) => state.licenses.list);
|
||||
|
||||
return (
|
||||
<div className="pb-license-list">
|
||||
{licenseList === null ? (
|
||||
// TODO: this should be translated and hooked to
|
||||
// state indicating if download is in progress
|
||||
// or there was an actual failure.
|
||||
<NonIdealState>Failed to load license data.</NonIdealState>
|
||||
) : (
|
||||
<ButtonGroup minimal={true} vertical={true} alignText="left">
|
||||
{licenseList.map((info, i) => (
|
||||
<Button key={i} onClick={() => props.onItemClick(info)}>
|
||||
{info.name}
|
||||
</Button>
|
||||
))}
|
||||
</ButtonGroup>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
type OwnProps = {
|
||||
const LicenseInfoPanel = React.forwardRef<HTMLDivElement>((_props, ref) => {
|
||||
const licenseInfo = useSelector((state: RootState) => state.licenses.selected);
|
||||
|
||||
const [i18n] = useI18n({ id: 'license', translations: { en }, fallback: en });
|
||||
|
||||
return (
|
||||
<div className="pb-license-info" ref={ref}>
|
||||
{licenseInfo == null ? (
|
||||
<NonIdealState>
|
||||
{i18n.translate(LicenseStringId.SelectPackageHelp)}
|
||||
</NonIdealState>
|
||||
) : (
|
||||
<div>
|
||||
<Card>
|
||||
<p>
|
||||
<strong>
|
||||
{i18n.translate(LicenseStringId.PackageLabel)}
|
||||
</strong>{' '}
|
||||
{licenseInfo.name}{' '}
|
||||
<span className={Classes.TEXT_MUTED}>
|
||||
v{licenseInfo.version}
|
||||
</span>
|
||||
</p>
|
||||
{licenseInfo.author && (
|
||||
<p>
|
||||
<strong>
|
||||
{i18n.translate(LicenseStringId.AuthorLabel)}
|
||||
</strong>{' '}
|
||||
{licenseInfo.author}
|
||||
</p>
|
||||
)}
|
||||
<p>
|
||||
<strong>
|
||||
{i18n.translate(LicenseStringId.LicenseLabel)}
|
||||
</strong>{' '}
|
||||
{licenseInfo.license}
|
||||
</p>
|
||||
</Card>
|
||||
<div className="pb-license-text">
|
||||
<pre>{licenseInfo.licenseText}</pre>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
LicenseInfoPanel.displayName = 'LicenseInfoPanel';
|
||||
|
||||
type LicenseDialogProps = {
|
||||
isOpen: boolean;
|
||||
onClose(): void;
|
||||
};
|
||||
|
||||
type LicenseDialogProps = StateProps & DispatchProps & OwnProps & WithI18nProps;
|
||||
const LicenseDialog: React.VoidFunctionComponent<LicenseDialogProps> = (props) => {
|
||||
const infoDiv = React.useRef<HTMLDivElement>(null);
|
||||
|
||||
class LicenseDialog extends React.Component<LicenseDialogProps> {
|
||||
render(): JSX.Element {
|
||||
const infoDiv = React.createRef<HTMLDivElement>();
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const {
|
||||
licenseList,
|
||||
licenseInfo,
|
||||
onOpening,
|
||||
onSelectPackage,
|
||||
isOpen,
|
||||
onClose,
|
||||
i18n,
|
||||
} = this.props;
|
||||
return (
|
||||
<Dialog
|
||||
title={i18n.translate(LicenseStringId.Title)}
|
||||
isOpen={isOpen}
|
||||
onOpening={() => onOpening()}
|
||||
onClose={() => onClose()}
|
||||
className="pb-license-dialog"
|
||||
>
|
||||
<div className={Classes.DIALOG_BODY}>
|
||||
<Callout className={Classes.INTENT_PRIMARY} icon="info-sign">
|
||||
{i18n.translate(LicenseStringId.Description, {
|
||||
name: appName,
|
||||
})}
|
||||
</Callout>
|
||||
<Callout className="pb-license-browser">
|
||||
<div className="pb-license-list">
|
||||
{licenseList === null ? (
|
||||
// TODO: this should be translated and hooked to
|
||||
// state indicating if download is in progress
|
||||
// or there was an actual failure.
|
||||
<NonIdealState>
|
||||
Failed to load license data.
|
||||
</NonIdealState>
|
||||
) : (
|
||||
<ButtonGroup
|
||||
minimal={true}
|
||||
vertical={true}
|
||||
alignText="left"
|
||||
>
|
||||
{licenseList.map((info) => (
|
||||
<Button
|
||||
key={`${info.name}@${info.version}`}
|
||||
onClick={() => {
|
||||
infoDiv.current?.scrollTo(0, 0);
|
||||
onSelectPackage(info);
|
||||
}}
|
||||
>
|
||||
{info.name}
|
||||
</Button>
|
||||
))}
|
||||
</ButtonGroup>
|
||||
)}
|
||||
</div>
|
||||
<div className="pb-license-info" ref={infoDiv}>
|
||||
{licenseInfo == null ? (
|
||||
<NonIdealState>
|
||||
{i18n.translate(LicenseStringId.SelectPackageHelp)}
|
||||
</NonIdealState>
|
||||
) : (
|
||||
<div>
|
||||
<Card>
|
||||
<p>
|
||||
<strong>
|
||||
{i18n.translate(
|
||||
LicenseStringId.PackageLabel,
|
||||
)}
|
||||
</strong>{' '}
|
||||
{licenseInfo.name}{' '}
|
||||
<span className={Classes.TEXT_MUTED}>
|
||||
v{licenseInfo.version}
|
||||
</span>
|
||||
</p>
|
||||
{licenseInfo.author && (
|
||||
<p>
|
||||
<strong>
|
||||
{' '}
|
||||
{i18n.translate(
|
||||
LicenseStringId.AuthorLabel,
|
||||
)}
|
||||
</strong>{' '}
|
||||
{licenseInfo.author}
|
||||
</p>
|
||||
)}
|
||||
<p>
|
||||
<strong>
|
||||
{' '}
|
||||
{i18n.translate(
|
||||
LicenseStringId.LicenseLabel,
|
||||
)}
|
||||
</strong>{' '}
|
||||
{licenseInfo.license}
|
||||
</p>
|
||||
</Card>
|
||||
<div className="pb-license-text">
|
||||
<pre>{licenseInfo.licenseText}</pre>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Callout>
|
||||
</div>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
}
|
||||
const [i18n] = useI18n({ id: 'license', translations: { en }, fallback: en });
|
||||
|
||||
const mapStateToProps = (state: RootState): StateProps => ({
|
||||
licenseList: state.licenses.list,
|
||||
licenseInfo: state.licenses.selected,
|
||||
});
|
||||
|
||||
const mapDispatchToProps: DispatchProps = {
|
||||
onOpening: fetchList,
|
||||
onSelectPackage: select,
|
||||
return (
|
||||
<Dialog
|
||||
title={i18n.translate(LicenseStringId.Title)}
|
||||
onOpening={() => dispatch(fetchList())}
|
||||
className="pb-license-dialog"
|
||||
{...props}
|
||||
>
|
||||
<div className={Classes.DIALOG_BODY}>
|
||||
<Callout className={Classes.INTENT_PRIMARY} icon="info-sign">
|
||||
{i18n.translate(LicenseStringId.Description, {
|
||||
name: appName,
|
||||
})}
|
||||
</Callout>
|
||||
<Callout className="pb-license-browser">
|
||||
<LicenseListPanel
|
||||
onItemClick={(info) => {
|
||||
infoDiv.current?.scrollTo(0, 0);
|
||||
dispatch(select(info));
|
||||
}}
|
||||
/>
|
||||
<LicenseInfoPanel ref={infoDiv} />
|
||||
</Callout>
|
||||
</div>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps,
|
||||
)(withI18n({ id: 'license', fallback: en, translations: { en } })(LicenseDialog));
|
||||
export default LicenseDialog;
|
||||
|
||||
Reference in New Issue
Block a user