Hopefully sort out sudo not found (on deployed) (#1759)

* Hopefully sort out sudo not found (on deployed)

* Simplify

* Use sudoKey eq

* Extract isVisible

* Extract TOOLTIP_OFFSET

* Use isVisible state

* Linting...
This commit is contained in:
Jaco Greeff 2019-10-25 10:38:26 +02:00 committed by GitHub
parent f89943db2a
commit d6601bd092
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -2,12 +2,15 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { ApiProps } from '@polkadot/react-api/types';
import { I18nProps } from '@polkadot/react-components/types';
import { SubjectInfo } from '@polkadot/ui-keyring/observable/types';
import { Route } from '@polkadot/apps-routing/types';
import { AccountId } from '@polkadot/types/interfaces';
import React, { useContext } from 'react';
import React, { useContext, useEffect, useState } from 'react';
import { NavLink } from 'react-router-dom';
import { ApiPromise } from '@polkadot/api';
import { Icon, Menu, Tooltip } from '@polkadot/react-components';
import accountObservable from '@polkadot/ui-keyring/observable/accounts';
import { ApiContext, withCalls, withMulti, withObservable } from '@polkadot/react-api';
@ -20,10 +23,11 @@ interface Props extends I18nProps {
onClick: () => void;
allAccounts?: SubjectInfo;
route: Route;
sudoKey: string;
sudoKey?: AccountId;
}
const disabledLog: Map<string, string> = new Map();
const TOOLTIP_OFFSET = { right: -4 };
function logDisabled (route: string, message: string): void {
if (!disabledLog.get(route)) {
@ -33,53 +37,64 @@ function logDisabled (route: string, message: string): void {
}
}
function Item ({ allAccounts, route: { Modal, display: { isHidden, needsAccounts, needsApi, needsSudo }, i18n, icon, name }, t, isCollapsed, onClick, sudoKey }: Props): React.ReactElement<Props> | null {
const { api, isApiConnected, isApiReady } = useContext(ApiContext);
function hasEndpoint (api: ApiPromise, endpoint: string): boolean {
const [area, section, method] = endpoint.split('.');
const _hasApi = (endpoint: string): boolean => {
const [area, section, method] = endpoint.split('.');
try {
return isFunction((api as any)[area][section][method]);
} catch (error) {
return false;
}
}
try {
return isFunction((api as any)[area][section][method]);
} catch (error) {
return false;
}
};
const _isVisible = (): boolean => {
const hasAccounts = !!allAccounts && Object.keys(allAccounts).length !== 0;
const hasSudo = !!allAccounts && Object.keys(allAccounts).some((address): boolean => address === sudoKey);
function checkVisible (name: string, { api, isApiReady, isApiConnected }: ApiProps, hasAccounts: boolean, hasSudo: boolean, { isHidden, needsAccounts, needsApi, needsSudo }: Route['display']): boolean {
if (isHidden) {
return false;
} else if (needsAccounts && !hasAccounts) {
return false;
} else if (!needsApi) {
return true;
} else if (!isApiReady || !isApiConnected) {
return false;
} else if (needsSudo && !hasSudo) {
logDisabled(name, 'Sudo key not available');
return false;
}
if (isHidden) {
return false;
} else if (needsAccounts && !hasAccounts) {
return false;
} else if (!needsApi) {
return true;
} else if (!isApiReady || !isApiConnected) {
return false;
} else if (needsSudo) {
if (!hasSudo) {
logDisabled(name, 'Sudo key not available');
return false;
}
}
const notFound = needsApi.filter((endpoint: string | string[]): boolean => {
const hasApi = Array.isArray(endpoint)
? endpoint.reduce((hasApi, endpoint): boolean => hasApi || hasEndpoint(api, endpoint), false)
: hasEndpoint(api, endpoint);
const notFound = needsApi.filter((endpoint: string | string[]): boolean => {
const hasApi = Array.isArray(endpoint)
? endpoint.reduce((hasApi, endpoint): boolean => hasApi || _hasApi(endpoint), false)
: _hasApi(endpoint);
return !hasApi;
});
return !hasApi;
});
if (notFound.length !== 0) {
logDisabled(name, `API not available: ${notFound}`);
}
if (notFound.length !== 0) {
logDisabled(name, `API not available: ${notFound}`);
}
return notFound.length === 0;
}
return notFound.length === 0;
};
function Item ({ allAccounts, route: { Modal, display, i18n, icon, name }, t, isCollapsed, onClick, sudoKey }: Props): React.ReactElement<Props> | null {
const apiProps = useContext(ApiContext);
const [hasAccounts, setHasAccounts] = useState(false);
const [hasSudo, setHasSudo] = useState(false);
const [isVisible, setIsVisible] = useState(false);
if (!_isVisible()) {
useEffect((): void => {
setHasAccounts(Object.keys(allAccounts || {}).length !== 0);
}, [allAccounts]);
useEffect((): void => {
setHasSudo(!!sudoKey && Object.keys(allAccounts || {}).some((address): boolean => sudoKey.eq(address)));
}, [allAccounts, sudoKey]);
useEffect((): void => {
setIsVisible(checkVisible(name, apiProps, hasAccounts, hasSudo, display));
}, [apiProps, hasAccounts, hasSudo]);
if (!isVisible) {
return null;
}
@ -88,7 +103,7 @@ function Item ({ allAccounts, route: { Modal, display: { isHidden, needsAccounts
<Icon name={icon} />
<span className='text'>{t(`sidebar.${name}`, i18n)}</span>
<Tooltip
offset={{ right: -4 }}
offset={TOOLTIP_OFFSET}
place='right'
text={t(`sidebar.${name}`, i18n)}
trigger={`nav-${name}`}
@ -132,11 +147,7 @@ export default withMulti(
Item,
translate,
withCalls<Props>(
['query.sudo.key', {
propName: 'sudoKey',
transform: (key): string =>
key.toString()
}]
['query.sudo.key', { propName: 'sudoKey' }]
),
withObservable(accountObservable.subject, { propName: 'allAccounts' })
);