mirror of
https://github.com/pezkuwichain/pezkuwi-apps.git
synced 2026-04-22 11:17:59 +00:00
feat: initial Pezkuwi Apps rebrand from polkadot-apps
Rebranded terminology: - Polkadot → Pezkuwi - Kusama → Dicle - Westend → Zagros - Rococo → PezkuwiChain - Substrate → Bizinikiwi - parachain → teyrchain Custom logos with Kurdistan brand colors (#e6007a → #86e62a): - bizinikiwi-hexagon.svg - sora-bizinikiwi.svg - hezscanner.svg - heztreasury.svg - pezkuwiscan.svg - pezkuwistats.svg - pezkuwiassembly.svg - pezkuwiholic.svg
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
// Copyright 2017-2025 @pezkuwi/react-components authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { DefinitionCallNamed } from '@pezkuwi/types/types';
|
||||
import type { DropdownOption } from '../util/types.js';
|
||||
|
||||
import React, { useCallback } from 'react';
|
||||
|
||||
import Dropdown from '../Dropdown.js';
|
||||
import { filterDropdownItems } from '../util/index.js';
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
defs: Record<string, Record<string, DefinitionCallNamed>>;
|
||||
isError?: boolean;
|
||||
onChange: (value: DefinitionCallNamed) => void;
|
||||
options: DropdownOption[];
|
||||
value: DefinitionCallNamed;
|
||||
}
|
||||
|
||||
function SelectMethod ({ className = '', defs, isError, onChange, options, value }: Props): React.ReactElement<Props> | null {
|
||||
const _transform = useCallback(
|
||||
(method: string) => defs[value.section][method],
|
||||
[defs, value]
|
||||
);
|
||||
|
||||
if (!options.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Dropdown
|
||||
className={`${className} ui--DropdownLinked-Items`}
|
||||
isError={isError}
|
||||
onChange={onChange}
|
||||
onSearch={filterDropdownItems}
|
||||
options={options}
|
||||
transform={_transform}
|
||||
value={value.method}
|
||||
withLabel={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default React.memo(SelectMethod);
|
||||
@@ -0,0 +1,36 @@
|
||||
// Copyright 2017-2025 @pezkuwi/react-components authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { DefinitionCallNamed } from '@pezkuwi/types/types';
|
||||
import type { DropdownOptions } from '../util/types.js';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import Dropdown from '../Dropdown.js';
|
||||
import { filterDropdownItems } from '../util/index.js';
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
defaultValue?: string;
|
||||
isError?: boolean;
|
||||
onChange: (value: string) => void;
|
||||
options: DropdownOptions;
|
||||
value: DefinitionCallNamed;
|
||||
}
|
||||
|
||||
function SelectSection ({ className = '', defaultValue, isError, onChange, options, value }: Props): React.ReactElement<Props> {
|
||||
return (
|
||||
<Dropdown
|
||||
className={`${className} ui--DropdownLinked-Sections`}
|
||||
defaultValue={defaultValue}
|
||||
isError={isError}
|
||||
onChange={onChange}
|
||||
onSearch={filterDropdownItems}
|
||||
options={options}
|
||||
value={value.section}
|
||||
withLabel={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default React.memo(SelectSection);
|
||||
@@ -0,0 +1,84 @@
|
||||
// Copyright 2017-2025 @pezkuwi/react-components authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// TODO: We have a lot shared between this and InputExtrinsic & InputStorage
|
||||
|
||||
import type { DefinitionCallNamed } from '@pezkuwi/types/types';
|
||||
import type { DropdownOptions } from '../util/types.js';
|
||||
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import LinkedWrapper from '../InputExtrinsic/LinkedWrapper.js';
|
||||
import methodOptions from './options/method.js';
|
||||
import sectionOptions from './options/section.js';
|
||||
import SelectMethod from './SelectMethod.js';
|
||||
import SelectSection from './SelectSection.js';
|
||||
import useRuntime from './useRuntime.js';
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
label: React.ReactNode;
|
||||
onChange?: (value: DefinitionCallNamed) => void;
|
||||
withLabel?: boolean;
|
||||
}
|
||||
|
||||
function InputCalls ({ className, label, onChange, withLabel }: Props): React.ReactElement<Props> | null {
|
||||
const [defs, defaultValue] = useRuntime();
|
||||
const [optionsSection] = useState<DropdownOptions>(() => sectionOptions(defs));
|
||||
const [optionsMethod, setOptionsMethod] = useState<DropdownOptions>(() => methodOptions(defs, defaultValue?.section));
|
||||
const [value, setValue] = useState<DefinitionCallNamed | null>(() => defaultValue);
|
||||
|
||||
useEffect((): void => {
|
||||
value && onChange && onChange(value);
|
||||
}, [onChange, value]);
|
||||
|
||||
const _onMethodChange = useCallback(
|
||||
(newValue: DefinitionCallNamed): void => {
|
||||
if (value !== newValue) {
|
||||
// set via callback since the method is a function itself
|
||||
setValue(() => newValue);
|
||||
}
|
||||
},
|
||||
[value]
|
||||
);
|
||||
|
||||
const _onSectionChange = useCallback(
|
||||
(newSection: string): void => {
|
||||
if (value && newSection !== value.section) {
|
||||
const optionsMethod = methodOptions(defs, newSection);
|
||||
|
||||
setOptionsMethod(optionsMethod);
|
||||
_onMethodChange(defs[newSection][optionsMethod[0].value]);
|
||||
}
|
||||
},
|
||||
[_onMethodChange, defs, value]
|
||||
);
|
||||
|
||||
if (!value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<LinkedWrapper
|
||||
className={className}
|
||||
label={label}
|
||||
withLabel={withLabel}
|
||||
>
|
||||
<SelectSection
|
||||
className='small'
|
||||
onChange={_onSectionChange}
|
||||
options={optionsSection}
|
||||
value={value}
|
||||
/>
|
||||
<SelectMethod
|
||||
className='large'
|
||||
defs={defs}
|
||||
onChange={_onMethodChange}
|
||||
options={optionsMethod}
|
||||
value={value}
|
||||
/>
|
||||
</LinkedWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
export default React.memo(InputCalls);
|
||||
@@ -0,0 +1,48 @@
|
||||
// Copyright 2017-2025 @pezkuwi/react-components authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { DefinitionCallNamed } from '@pezkuwi/types/types';
|
||||
import type { DropdownOption, DropdownOptions } from '../../util/types.js';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
export default function createOptions (runtime: Record<string, Record<string, DefinitionCallNamed>>, sectionName?: string | null): DropdownOptions {
|
||||
if (!sectionName) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const section = runtime[sectionName];
|
||||
|
||||
if (!section || Object.keys(runtime[sectionName]).length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return Object
|
||||
.keys(runtime[sectionName])
|
||||
.filter((s) => !s.startsWith('$'))
|
||||
.sort()
|
||||
.map((m) => section[m])
|
||||
.map(({ description, method, params }): DropdownOption => {
|
||||
const inputs = params.map(({ name }) => name).join(', ');
|
||||
|
||||
return {
|
||||
className: 'ui--DropdownLinked-Item',
|
||||
key: `${sectionName}_${method}`,
|
||||
text: [
|
||||
<div
|
||||
className='ui--DropdownLinked-Item-call'
|
||||
key={`${sectionName}_${method}:call`}
|
||||
>
|
||||
{method}({inputs})
|
||||
</div>,
|
||||
<div
|
||||
className='ui--DropdownLinked-Item-text'
|
||||
key={`${sectionName}_${method}:text`}
|
||||
>
|
||||
{description || method}
|
||||
</div>
|
||||
],
|
||||
value: method
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// Copyright 2017-2025 @pezkuwi/react-components authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { DefinitionCallNamed } from '@pezkuwi/types/types';
|
||||
import type { DropdownOptions } from '../../util/types.js';
|
||||
|
||||
export default function createOptions (runtime: Record<string, Record<string, DefinitionCallNamed>>): DropdownOptions {
|
||||
return Object
|
||||
.keys(runtime)
|
||||
.filter((s) => !s.startsWith('$'))
|
||||
.sort()
|
||||
.filter((s) => Object.keys(runtime[s]).length !== 0)
|
||||
.map((value): { text: string; value: string } => ({
|
||||
text: value,
|
||||
value
|
||||
}));
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
// Copyright 2017-2025 @pezkuwi/react-components authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { ApiPromise } from '@pezkuwi/api';
|
||||
import type { DefinitionCallNamed } from '@pezkuwi/types/types';
|
||||
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { createNamedHook, useApi } from '@pezkuwi/react-hooks';
|
||||
|
||||
function getEntries <T> (obj: Record<string, T>): [string, T][] {
|
||||
return Object
|
||||
.entries(obj)
|
||||
.sort(([a], [b]) => a.localeCompare(b));
|
||||
}
|
||||
|
||||
function getAllCalls (api: ApiPromise): [Record<string, Record<string, DefinitionCallNamed>>, DefinitionCallNamed | null] {
|
||||
const result: Record<string, Record<string, DefinitionCallNamed>> = {};
|
||||
let defValue: DefinitionCallNamed | null = null;
|
||||
const sections = getEntries(api.call);
|
||||
|
||||
for (let i = 0, secCount = sections.length; i < secCount; i++) {
|
||||
const [section, methodsObj] = sections[i];
|
||||
const methods = getEntries(methodsObj);
|
||||
|
||||
for (let j = 0, metCount = methods.length; j < metCount; j++) {
|
||||
const [method, { meta }] = methods[j] as unknown as [string, { meta: DefinitionCallNamed }];
|
||||
|
||||
if (meta) {
|
||||
if (!result[section]) {
|
||||
result[section] = {};
|
||||
|
||||
if (defValue === null) {
|
||||
defValue = meta;
|
||||
}
|
||||
}
|
||||
|
||||
result[section][method] = meta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [result, defValue];
|
||||
}
|
||||
|
||||
function useRuntimeImpl (): [Record<string, Record<string, DefinitionCallNamed>>, DefinitionCallNamed | null] {
|
||||
const { api } = useApi();
|
||||
|
||||
return useMemo(
|
||||
() => getAllCalls(api),
|
||||
[api]
|
||||
);
|
||||
}
|
||||
|
||||
export default createNamedHook('useRuntime', useRuntimeImpl);
|
||||
Reference in New Issue
Block a user