mirror of
https://github.com/pybricks/pybricks-code.git
synced 2026-09-14 10:35:11 +00:00
add license dialog
This commit is contained in:
@@ -6,9 +6,16 @@ const {
|
||||
getLoaders,
|
||||
loaderByName,
|
||||
} = require('@craco/craco');
|
||||
const LicensePlugin = require('webpack-license-plugin');
|
||||
|
||||
module.exports = {
|
||||
webpack: {
|
||||
plugins: [
|
||||
new LicensePlugin({
|
||||
outputFilename: 'static/oss-licenses.json',
|
||||
replenishDefaultLicenseTexts: true,
|
||||
}),
|
||||
],
|
||||
configure: {
|
||||
resolve: {
|
||||
// need 'esnext' first to avoid compile errors
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
"redux-saga": "^1.1.3",
|
||||
"typescript": "~4.1.3",
|
||||
"web-vitals": "^1.0.1",
|
||||
"webpack-license-plugin": "^4.1.2",
|
||||
"xterm": "^4.9.0",
|
||||
"xterm-addon-fit": "^0.4.0",
|
||||
"zen-push": "^0.2.1"
|
||||
|
||||
+23
-1
@@ -17,6 +17,10 @@ export enum AppActionType {
|
||||
OpenAboutDialog = 'app.action.openAboutDialog',
|
||||
/** Close about dialog. */
|
||||
CloseAboutDialog = 'app.action.closeAboutDialog',
|
||||
/** Open license dialog. */
|
||||
OpenLicenseDialog = 'app.action.openLicenseDialog',
|
||||
/** Close license dialog. */
|
||||
CloseLicenseDialog = 'app.action.closeLicenseDialog',
|
||||
}
|
||||
|
||||
/** Action that indicates the app has just started. */
|
||||
@@ -59,10 +63,28 @@ export function closeAboutDialog(): AppCloseAboutDialogAction {
|
||||
return { type: AppActionType.CloseAboutDialog };
|
||||
}
|
||||
|
||||
/** Action to open the license dialog. */
|
||||
export type AppOpenLicenseDialogAction = Action<AppActionType.OpenLicenseDialog>;
|
||||
|
||||
/** Creates an action to open the license dialog. */
|
||||
export function openLicenseDialog(): AppOpenLicenseDialogAction {
|
||||
return { type: AppActionType.OpenLicenseDialog };
|
||||
}
|
||||
|
||||
/** Action to close the license dialog. */
|
||||
export type AppCloseLicenseDialogAction = Action<AppActionType.CloseLicenseDialog>;
|
||||
|
||||
/** Creates an action to close the license dialog. */
|
||||
export function closeLicenseDialog(): AppCloseLicenseDialogAction {
|
||||
return { type: AppActionType.CloseLicenseDialog };
|
||||
}
|
||||
|
||||
/** common type for all app actions. */
|
||||
export type AppAction =
|
||||
| AppStartupAction
|
||||
| AppOpenSettingsAction
|
||||
| AppCloseSettingsAction
|
||||
| AppOpenAboutDialogAction
|
||||
| AppCloseAboutDialogAction;
|
||||
| AppCloseAboutDialogAction
|
||||
| AppOpenLicenseDialogAction
|
||||
| AppCloseLicenseDialogAction;
|
||||
|
||||
@@ -8,6 +8,7 @@ import { BleUartAction } from './ble-uart';
|
||||
import { EditorAction } from './editor';
|
||||
import { FlashFirmwareAction } from './flash-firmware';
|
||||
import { HubAction, HubMessageAction } from './hub';
|
||||
import { LicenseAction } from './license';
|
||||
import {
|
||||
BootloaderConnectionAction,
|
||||
BootloaderDidRequestAction,
|
||||
@@ -36,6 +37,7 @@ export type Action =
|
||||
| FlashFirmwareAction
|
||||
| HubAction
|
||||
| HubMessageAction
|
||||
| LicenseAction
|
||||
| MpyAction
|
||||
| NotificationAction
|
||||
| ServiceWorkerAction
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright (c) 2021 The Pybricks Authors
|
||||
|
||||
import { Action } from 'redux';
|
||||
import { LicenseInfo, LicenseList } from '../reducers/license';
|
||||
|
||||
export enum LicenseActionType {
|
||||
DidFetchList = 'license.action.didFetchList',
|
||||
Select = 'license.action.select',
|
||||
}
|
||||
|
||||
export type LicenseDidFetchListAction = Action<LicenseActionType.DidFetchList> & {
|
||||
list: LicenseList;
|
||||
};
|
||||
|
||||
export function didFetchList(list: LicenseList): LicenseDidFetchListAction {
|
||||
return { type: LicenseActionType.DidFetchList, list };
|
||||
}
|
||||
|
||||
export type LicenseSelectAction = Action<LicenseActionType.Select> & {
|
||||
info: LicenseInfo;
|
||||
};
|
||||
|
||||
export function select(info: LicenseInfo): LicenseSelectAction {
|
||||
return { type: LicenseActionType.Select, info };
|
||||
}
|
||||
|
||||
export type LicenseAction = LicenseDidFetchListAction | LicenseSelectAction;
|
||||
@@ -3,12 +3,12 @@
|
||||
|
||||
// The about dialog
|
||||
|
||||
import { AnchorButton, Classes, Dialog } from '@blueprintjs/core';
|
||||
import { AnchorButton, Button, Classes, Dialog } from '@blueprintjs/core';
|
||||
import { WithI18nProps, withI18n } from '@shopify/react-i18n';
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Action, Dispatch } from '../actions';
|
||||
import { closeAboutDialog } from '../actions/app';
|
||||
import { closeAboutDialog, openLicenseDialog } from '../actions/app';
|
||||
import { RootState } from '../reducers';
|
||||
import {
|
||||
appName,
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
pybricksWebsiteUrl,
|
||||
} from '../settings/ui';
|
||||
import ExternalLinkIcon from './ExternalLinkIcon';
|
||||
import LicenseDialog from './LicenseDialog';
|
||||
import { AboutStringId } from './about-i18n';
|
||||
import en from './about-i18n.en.json';
|
||||
|
||||
@@ -24,13 +25,13 @@ import './about.scss';
|
||||
|
||||
type StateProps = { showAboutDialog: boolean };
|
||||
|
||||
type DispatchProps = { onClose: () => void };
|
||||
type DispatchProps = { onClose: () => void; onLicenseButtonClick: () => void };
|
||||
|
||||
type AboutDialogProps = StateProps & DispatchProps & WithI18nProps;
|
||||
|
||||
class AboutDialog extends React.Component<AboutDialogProps> {
|
||||
render(): JSX.Element {
|
||||
const { i18n, showAboutDialog, onClose } = this.props;
|
||||
const { i18n, showAboutDialog, onClose, onLicenseButtonClick } = this.props;
|
||||
return (
|
||||
<Dialog title={appName} isOpen={showAboutDialog} onClose={() => onClose()}>
|
||||
<div className={Classes.DIALOG_BODY}>
|
||||
@@ -47,12 +48,16 @@ class AboutDialog extends React.Component<AboutDialogProps> {
|
||||
<small>{legoDisclaimer}</small>
|
||||
</p>
|
||||
<div className={Classes.DIALOG_FOOTER_ACTIONS}>
|
||||
<Button onClick={() => onLicenseButtonClick()}>
|
||||
{i18n.translate(AboutStringId.LicenseButtonLabel)}
|
||||
</Button>
|
||||
<AnchorButton href={pybricksWebsiteUrl} target="blank_">
|
||||
{i18n.translate(AboutStringId.WebsiteButtonLabel)}
|
||||
<ExternalLinkIcon />
|
||||
</AnchorButton>
|
||||
</div>
|
||||
</div>
|
||||
<LicenseDialog />
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
@@ -64,6 +69,7 @@ const mapStateToProps = (state: RootState): StateProps => ({
|
||||
|
||||
const mapDispatchToProps = (dispatch: Dispatch): DispatchProps => ({
|
||||
onClose: (): Action => dispatch(closeAboutDialog()),
|
||||
onLicenseButtonClick: (): Action => dispatch(openLicenseDialog()),
|
||||
});
|
||||
|
||||
export default connect(
|
||||
|
||||
@@ -5,7 +5,6 @@ import React, { useState } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import SplitterLayout from 'react-splitter-layout';
|
||||
import { RootState } from '../reducers';
|
||||
import AboutDialog from './AboutDialog';
|
||||
import Editor from './Editor';
|
||||
import SettingsDrawer from './SettingsDrawer';
|
||||
import StatusBar from './StatusBar';
|
||||
@@ -65,7 +64,6 @@ function App(): JSX.Element {
|
||||
</SplitterLayout>
|
||||
<StatusBar />
|
||||
<SettingsDrawer />
|
||||
<AboutDialog key="about" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright (c) 2021 The Pybricks Authors
|
||||
|
||||
// The license dialog
|
||||
|
||||
import {
|
||||
Button,
|
||||
ButtonGroup,
|
||||
Callout,
|
||||
Card,
|
||||
Classes,
|
||||
Dialog,
|
||||
NonIdealState,
|
||||
} from '@blueprintjs/core';
|
||||
import { WithI18nProps, withI18n } from '@shopify/react-i18n';
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Action, Dispatch } from '../actions';
|
||||
import { closeLicenseDialog } from '../actions/app';
|
||||
import { select } from '../actions/license';
|
||||
import { RootState } from '../reducers';
|
||||
import { LicenseInfo, LicenseList } from '../reducers/license';
|
||||
import { appName } from '../settings/ui';
|
||||
import { LicenseStringId } from './license-i18n';
|
||||
import en from './license-i18n.en.json';
|
||||
|
||||
import './license.scss';
|
||||
|
||||
type StateProps = {
|
||||
showLicenseDialog: boolean;
|
||||
licenseList: LicenseList | null;
|
||||
licenseInfo: LicenseInfo | null;
|
||||
};
|
||||
|
||||
type DispatchProps = {
|
||||
onClose: () => void;
|
||||
onSelectPackage: (info: LicenseInfo) => void;
|
||||
};
|
||||
|
||||
type LicenseDialogProps = StateProps & DispatchProps & WithI18nProps;
|
||||
|
||||
class LicenseDialog extends React.Component<LicenseDialogProps> {
|
||||
render(): JSX.Element {
|
||||
const infoDiv = React.createRef<HTMLDivElement>();
|
||||
|
||||
const {
|
||||
i18n,
|
||||
showLicenseDialog,
|
||||
onClose,
|
||||
licenseList,
|
||||
licenseInfo,
|
||||
onSelectPackage,
|
||||
} = this.props;
|
||||
return (
|
||||
<Dialog
|
||||
title={i18n.translate(LicenseStringId.Title)}
|
||||
isOpen={showLicenseDialog}
|
||||
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 mapStateToProps = (state: RootState): StateProps => ({
|
||||
showLicenseDialog: state.app.showLicenseDialog,
|
||||
licenseList: state.license.list,
|
||||
licenseInfo: state.license.selected,
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch: Dispatch): DispatchProps => ({
|
||||
onClose: (): Action => dispatch(closeLicenseDialog()),
|
||||
onSelectPackage: (info): Action => dispatch(select(info)),
|
||||
});
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps,
|
||||
)(withI18n({ id: 'license', fallback: en, translations: { en } })(LicenseDialog));
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
} from '../settings/ui';
|
||||
import { SettingId } from '../settings/user';
|
||||
import { isMacOS } from '../utils/os';
|
||||
import AboutDialog from './AboutDialog';
|
||||
import ExternalLinkIcon from './ExternalLinkIcon';
|
||||
import { SettingsStringId } from './settings-i18n';
|
||||
import en from './settings-i18n.en.json';
|
||||
@@ -192,6 +193,7 @@ class SettingsDrawer extends React.PureComponent<SettingsProps> {
|
||||
>
|
||||
{i18n.translate(SettingsStringId.HelpAboutLabel)}
|
||||
</Button>
|
||||
<AboutDialog />
|
||||
</ButtonGroup>
|
||||
</FormGroup>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"about": {
|
||||
"description": "A simple web app for programming LEGO® Powered Up smart hubs using Pybricks MicroPython.",
|
||||
"licenseButton": { "label": "Open Source Licenses" },
|
||||
"websiteButton": { "label": "Pybricks Website" }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,5 +5,6 @@
|
||||
|
||||
export enum AboutStringId {
|
||||
Description = 'about.description',
|
||||
LicenseButtonLabel = 'about.licenseButton.label',
|
||||
WebsiteButtonLabel = 'about.websiteButton.label',
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"license": {
|
||||
"title": "Open Source Licenses",
|
||||
"description": "{name} is built on open source software. By using {name} you are agreeing to the terms and conditions of all of the included software licenses.",
|
||||
"packageLabel": "Package:",
|
||||
"authorLabel": "Author:",
|
||||
"licenseLabel": "License:",
|
||||
"help": {
|
||||
"selectPackage": "Select a package to view the license."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright (c) 2021 The Pybricks Authors
|
||||
|
||||
import { lookup } from '../../test';
|
||||
import { LicenseStringId } from './license-i18n';
|
||||
import en from './license-i18n.en.json';
|
||||
|
||||
describe('Ensure .json file has matches for LicenseStringId', () => {
|
||||
test.each(Object.values(LicenseStringId))('%s', (id) => {
|
||||
expect(lookup(en, id)).toBeDefined();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright (c) 2021 The Pybricks Authors
|
||||
|
||||
// License dialog translation keys.
|
||||
|
||||
export enum LicenseStringId {
|
||||
Title = 'license.title',
|
||||
Description = 'license.description',
|
||||
PackageLabel = 'license.packageLabel',
|
||||
AuthorLabel = 'license.authorLabel',
|
||||
LicenseLabel = 'license.licenseLabel',
|
||||
SelectPackageHelp = 'license.help.selectPackage',
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright (c) 2020-2021 The Pybricks Authors
|
||||
|
||||
// Custom styling for the LicenseDialog control.
|
||||
|
||||
@import '../variables.scss';
|
||||
|
||||
.pb-license-dialog {
|
||||
width: 1200px;
|
||||
}
|
||||
|
||||
.pb-license-browser {
|
||||
margin-top: 16px;
|
||||
display: flex;
|
||||
height: 600px;
|
||||
}
|
||||
|
||||
.pb-license-list {
|
||||
width: 25%;
|
||||
flex-flow: column;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.pb-license-info {
|
||||
width: 75%;
|
||||
flex-flow: column;
|
||||
padding: 0px 16px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.pb-license-text {
|
||||
padding: 0px 16px;
|
||||
}
|
||||
+13
-1
@@ -10,6 +10,7 @@ import { AppActionType } from '../actions/app';
|
||||
export interface AppState {
|
||||
readonly showSettings: boolean;
|
||||
readonly showAboutDialog: boolean;
|
||||
readonly showLicenseDialog: boolean;
|
||||
}
|
||||
|
||||
const showSettings: Reducer<boolean, Action> = (state = false, action) => {
|
||||
@@ -34,4 +35,15 @@ const showAboutDialog: Reducer<boolean, Action> = (state = false, action) => {
|
||||
}
|
||||
};
|
||||
|
||||
export default combineReducers({ showSettings, showAboutDialog });
|
||||
const showLicenseDialog: Reducer<boolean, Action> = (state = false, action) => {
|
||||
switch (action.type) {
|
||||
case AppActionType.OpenLicenseDialog:
|
||||
return true;
|
||||
case AppActionType.CloseLicenseDialog:
|
||||
return false;
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
export default combineReducers({ showSettings, showAboutDialog, showLicenseDialog });
|
||||
|
||||
@@ -7,6 +7,7 @@ import ble, { BleState } from './ble';
|
||||
import bootloader, { BootloaderState } from './bootloader';
|
||||
import editor, { EditorState } from './editor';
|
||||
import hub, { HubState } from './hub';
|
||||
import license, { LicenseState } from './license';
|
||||
import notification, { NotificationState } from './notification';
|
||||
import settings, { SettingsState } from './settings';
|
||||
import status, { StatusState } from './status';
|
||||
@@ -21,6 +22,7 @@ export interface RootState {
|
||||
readonly ble: BleState;
|
||||
readonly editor: EditorState;
|
||||
readonly hub: HubState;
|
||||
readonly license: LicenseState;
|
||||
readonly notification: NotificationState;
|
||||
readonly settings: SettingsState;
|
||||
readonly status: StatusState;
|
||||
@@ -33,6 +35,7 @@ export default combineReducers({
|
||||
ble,
|
||||
editor,
|
||||
hub,
|
||||
license,
|
||||
notification,
|
||||
settings,
|
||||
status,
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright (c) 2021 The Pybricks Authors
|
||||
|
||||
import { Reducer, combineReducers } from 'redux';
|
||||
import { Action } from '../actions';
|
||||
import { LicenseActionType } from '../actions/license';
|
||||
|
||||
export interface LicenseInfo {
|
||||
readonly name: string;
|
||||
readonly version: string;
|
||||
readonly author: string | undefined;
|
||||
readonly repository: string | null;
|
||||
readonly source: string;
|
||||
readonly license: string;
|
||||
readonly licenseText: string | null;
|
||||
}
|
||||
|
||||
export type LicenseList = LicenseInfo[];
|
||||
|
||||
export interface LicenseState {
|
||||
readonly list: LicenseList | null;
|
||||
readonly selected: LicenseInfo | null;
|
||||
}
|
||||
|
||||
const list: Reducer<LicenseList | null, Action> = (state = null, action) => {
|
||||
switch (action.type) {
|
||||
case LicenseActionType.DidFetchList:
|
||||
return action.list;
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
const selected: Reducer<LicenseInfo | null, Action> = (state = null, action) => {
|
||||
switch (action.type) {
|
||||
case LicenseActionType.Select:
|
||||
return action.info;
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
export default combineReducers({ list, selected });
|
||||
@@ -8,6 +8,7 @@ import editor from './editor';
|
||||
import errorLog from './error-log';
|
||||
import flashFirmware from './flash-firmware';
|
||||
import hub from './hub';
|
||||
import license from './license';
|
||||
import lwp3BootloaderBle from './lwp3-bootloader-ble';
|
||||
import lwp3BootloaderProtocol from './lwp3-bootloader-protocol';
|
||||
import mpy from './mpy';
|
||||
@@ -24,6 +25,7 @@ export default function* (): Generator {
|
||||
errorLog(),
|
||||
flashFirmware(),
|
||||
hub(),
|
||||
license(),
|
||||
mpy(),
|
||||
settings(),
|
||||
terminal(),
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright (c) 2021 The Pybricks Authors
|
||||
|
||||
import { call, put, select, takeEvery } from 'redux-saga/effects';
|
||||
import { AppActionType } from '../actions/app';
|
||||
import { didFetchList } from '../actions/license';
|
||||
import { RootState } from '../reducers';
|
||||
import { LicenseList } from '../reducers/license';
|
||||
|
||||
function* fetchLicenses(): Generator {
|
||||
const licenses = (yield select(
|
||||
(s: RootState) => s.license.list,
|
||||
)) as LicenseList | null;
|
||||
|
||||
// if we already have license list, nothing to do
|
||||
if (licenses !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const response = (yield call(() => fetch('static/oss-licenses.json'))) as Response;
|
||||
if (!response.ok || response.body === null) {
|
||||
// TODO: dispatch an action to notify user
|
||||
console.error('failed to fetch oss-licenses.json', response.statusText);
|
||||
return;
|
||||
}
|
||||
|
||||
const list = (yield call(() => response.json())) as LicenseList;
|
||||
yield put(didFetchList(list));
|
||||
}
|
||||
|
||||
export default function* (): Generator {
|
||||
yield takeEvery(AppActionType.OpenLicenseDialog, fetchLicenses);
|
||||
}
|
||||
@@ -4331,7 +4331,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9:
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@^3.1.1, debug@^3.2.5:
|
||||
debug@^3.1.1, debug@^3.2.5, debug@^3.2.6:
|
||||
version "3.2.7"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
|
||||
integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
|
||||
@@ -5833,6 +5833,13 @@ get-intrinsic@^1.0.0, get-intrinsic@^1.0.1:
|
||||
has "^1.0.3"
|
||||
has-symbols "^1.0.1"
|
||||
|
||||
get-npm-tarball-url@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/get-npm-tarball-url/-/get-npm-tarball-url-2.0.1.tgz#43c15223c35096e3e4068d8a6c6747bbdfc23462"
|
||||
integrity sha512-POrVRGyS9X5w+855/H46JGVYBGuVgJXyIkbsTCzW+sv5x2qH+rfQjc7652DzkgOskF+cqLevA2En7V0hu0gZCg==
|
||||
dependencies:
|
||||
normalize-registry-url "^1.0.0"
|
||||
|
||||
get-own-enumerable-property-symbols@^3.0.0:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664"
|
||||
@@ -6295,7 +6302,7 @@ human-signals@^1.1.1:
|
||||
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3"
|
||||
integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==
|
||||
|
||||
iconv-lite@0.4.24:
|
||||
iconv-lite@0.4.24, iconv-lite@^0.4.4:
|
||||
version "0.4.24"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
||||
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
|
||||
@@ -8197,6 +8204,15 @@ natural-compare@^1.4.0:
|
||||
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
||||
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
|
||||
|
||||
needle@^2.2.4:
|
||||
version "2.6.0"
|
||||
resolved "https://registry.yarnpkg.com/needle/-/needle-2.6.0.tgz#24dbb55f2509e2324b4a99d61f413982013ccdbe"
|
||||
integrity sha512-KKYdza4heMsEfSWD7VPUIz3zX2XDwOyX2d+geb4vrERZMT5RMU6ujjaD+I5Yr54uZxQ2w6XRTAhHBbSCyovZBg==
|
||||
dependencies:
|
||||
debug "^3.2.6"
|
||||
iconv-lite "^0.4.4"
|
||||
sax "^1.2.4"
|
||||
|
||||
negotiator@0.6.2:
|
||||
version "0.6.2"
|
||||
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
|
||||
@@ -8368,6 +8384,11 @@ normalize-range@^0.1.2:
|
||||
resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942"
|
||||
integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=
|
||||
|
||||
normalize-registry-url@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/normalize-registry-url/-/normalize-registry-url-1.0.0.tgz#f75d2c48373da780c76f1f0eeb6382c06e784d13"
|
||||
integrity sha512-0v6T4851b72ykk5zEtFoN4QX/Fqyk7pouIj9xZyAvAe9jlDhAwT4z6FlwsoQCHjeuK2EGUoAwy/F4y4B1uZq9A==
|
||||
|
||||
normalize-url@1.9.1:
|
||||
version "1.9.1"
|
||||
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c"
|
||||
@@ -10720,7 +10741,7 @@ sass-loader@8.0.2:
|
||||
schema-utils "^2.6.1"
|
||||
semver "^6.3.0"
|
||||
|
||||
sax@~1.2.4:
|
||||
sax@^1.2.4, sax@~1.2.4:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
|
||||
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
|
||||
@@ -11080,7 +11101,7 @@ sort-keys@^1.0.0:
|
||||
dependencies:
|
||||
is-plain-obj "^1.0.0"
|
||||
|
||||
source-list-map@^2.0.0:
|
||||
source-list-map@^2.0.0, source-list-map@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
|
||||
integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==
|
||||
@@ -11165,6 +11186,13 @@ spdx-expression-parse@^3.0.0:
|
||||
spdx-exceptions "^2.1.0"
|
||||
spdx-license-ids "^3.0.0"
|
||||
|
||||
spdx-expression-validate@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/spdx-expression-validate/-/spdx-expression-validate-2.0.0.tgz#25c9408e1c63fad94fff5517bb7101ffcd23350b"
|
||||
integrity sha512-b3wydZLM+Tc6CFvaRDBOF9d76oGIHNCLYFeHbftFXUWjnfZWganmDmvtM5sm1cRwJc/VDBMLyGGrsLFd1vOxbg==
|
||||
dependencies:
|
||||
spdx-expression-parse "^3.0.0"
|
||||
|
||||
spdx-license-ids@^3.0.0:
|
||||
version "3.0.7"
|
||||
resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz#e9c18a410e5ed7e12442a549fbd8afa767038d65"
|
||||
@@ -12393,6 +12421,18 @@ webpack-dev-server@3.11.0:
|
||||
ws "^6.2.1"
|
||||
yargs "^13.3.2"
|
||||
|
||||
webpack-license-plugin@^4.1.2:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/webpack-license-plugin/-/webpack-license-plugin-4.1.2.tgz#d3eb954babf30ba65c50cc416c0a59d568776215"
|
||||
integrity sha512-aS/fMx9zGfqs7OSj02iCX7W4hnaiGolihz+sHn6nEwaMTFeTEp0Uu+QIyRMluC731USIB42hFIdI/vje1SKdrQ==
|
||||
dependencies:
|
||||
chalk "^4.1.0"
|
||||
get-npm-tarball-url "^2.0.1"
|
||||
lodash "^4.17.20"
|
||||
needle "^2.2.4"
|
||||
spdx-expression-validate "^2.0.0"
|
||||
webpack-sources "^2.0.0"
|
||||
|
||||
webpack-log@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f"
|
||||
@@ -12426,6 +12466,14 @@ webpack-sources@^1.1.0, webpack-sources@^1.3.0, webpack-sources@^1.4.0, webpack-
|
||||
source-list-map "^2.0.0"
|
||||
source-map "~0.6.1"
|
||||
|
||||
webpack-sources@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.2.0.tgz#058926f39e3d443193b6c31547229806ffd02bac"
|
||||
integrity sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==
|
||||
dependencies:
|
||||
source-list-map "^2.0.1"
|
||||
source-map "^0.6.1"
|
||||
|
||||
webpack@4.44.2:
|
||||
version "4.44.2"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.44.2.tgz#6bfe2b0af055c8b2d1e90ed2cd9363f841266b72"
|
||||
|
||||
Reference in New Issue
Block a user