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:
parent
f89943db2a
commit
d6601bd092
@ -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' })
|
||||
);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user