Groupe accounts by network and sort by name, path, creation date (#481)
* sort by name * compare by path * fixed and added tests * sort by network first * add comment * use localCompare * use the same sorting name - path - creation everywhere * Apply suggestions from code review Co-authored-by: Jaco Greeff <jacogr@gmail.com> * Apply suggestions from code review Co-authored-by: Jaco Greeff <jacogr@gmail.com>
This commit is contained in:
co-authored by
Jaco Greeff
parent
e74db7f71a
commit
ba96ce7337
@@ -4,18 +4,27 @@
|
||||
import { AccountJson, AccountWithChildren } from '@polkadot/extension-base/background/types';
|
||||
import { buildHierarchy } from './buildHierarchy';
|
||||
|
||||
const genesisExample = {
|
||||
KUSAMA: '0xb0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe',
|
||||
POLKADOT: '0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3'
|
||||
};
|
||||
|
||||
const testHierarchy = (accounts: AccountJson[], expected: AccountWithChildren[]): void => {
|
||||
expect(buildHierarchy(accounts)).toEqual(expected);
|
||||
};
|
||||
|
||||
describe('Use Account Hierarchy', () => {
|
||||
const acc = (address: string, parentAddress?: string, whenCreated?: number): {
|
||||
const acc = (address: string, parentAddress?: string, whenCreated?: number, name?: string, suri?: string): {
|
||||
address: string;
|
||||
whenCreated?: number;
|
||||
name?: string;
|
||||
parentAddress?: string;
|
||||
suri?: string;
|
||||
whenCreated?: number;
|
||||
} => ({
|
||||
address,
|
||||
name,
|
||||
parentAddress,
|
||||
suri,
|
||||
whenCreated
|
||||
});
|
||||
|
||||
@@ -56,10 +65,38 @@ describe('Use Account Hierarchy', () => {
|
||||
}]);
|
||||
});
|
||||
|
||||
test('sorts accounts by creation time', () => {
|
||||
test('sorts accounts by network', () => {
|
||||
testHierarchy(
|
||||
[acc('a', undefined, 2), acc('b', 'a', 4), acc('c', 'a', 3), acc('d', undefined, 1)],
|
||||
[acc('d', undefined, 1), { address: 'a', children: [acc('c', 'a', 3), acc('b', 'a', 4)], whenCreated: 2 }]
|
||||
[{ address: 'b', genesisHash: genesisExample.KUSAMA }, { address: 'a', genesisHash: genesisExample.POLKADOT }, { address: 'c', genesisHash: genesisExample.KUSAMA }],
|
||||
[{ address: 'b', genesisHash: genesisExample.KUSAMA }, { address: 'c', genesisHash: genesisExample.KUSAMA }, { address: 'a', genesisHash: genesisExample.POLKADOT }]
|
||||
);
|
||||
});
|
||||
|
||||
test('sorts accounts by network and name', () => {
|
||||
testHierarchy(
|
||||
[{ address: 'b', genesisHash: genesisExample.KUSAMA, name: 'b-last-kusama' }, { address: 'a', genesisHash: genesisExample.POLKADOT }, { address: 'c', genesisHash: genesisExample.KUSAMA, name: 'a-first-kusama' }],
|
||||
[{ address: 'c', genesisHash: genesisExample.KUSAMA, name: 'a-first-kusama' }, { address: 'b', genesisHash: genesisExample.KUSAMA, name: 'b-last-kusama' }, { address: 'a', genesisHash: genesisExample.POLKADOT }]
|
||||
);
|
||||
});
|
||||
|
||||
test('sorts accounts by name and creation date', () => {
|
||||
testHierarchy(
|
||||
[acc('b', undefined, 2, 'b'), acc('z', undefined, 1, 'b'), acc('a', undefined, 4, 'a')],
|
||||
[{ address: 'a', name: 'a', whenCreated: 4 }, { address: 'z', name: 'b', whenCreated: 1 }, { address: 'b', name: 'b', whenCreated: 2 }]
|
||||
);
|
||||
});
|
||||
|
||||
test('sorts account children by name and path', () => {
|
||||
testHierarchy(
|
||||
[acc('a', undefined, 1, 'a'), acc('b', 'a', 1, 'b', '/2'), acc('b', 'a', 1, 'b', '/0')],
|
||||
[{ address: 'a', children: [acc('b', 'a', 1, 'b', '/0'), acc('b', 'a', 1, 'b', '/2')], name: 'a', whenCreated: 1 }]
|
||||
);
|
||||
});
|
||||
|
||||
test('sorts accounts with children by name and creation date', () => {
|
||||
testHierarchy(
|
||||
[acc('b', undefined, 2, 'b'), acc('z', undefined, 1, 'b'), acc('d', 'b', 2, 'd'), acc('c', 'b', 3, 'c'), acc('a', undefined, 4, 'a')],
|
||||
[{ address: 'a', name: 'a', whenCreated: 4 }, { address: 'z', name: 'b', whenCreated: 1 }, { address: 'b', children: [acc('c', 'b', 3, 'c'), acc('d', 'b', 2, 'd')], name: 'b', whenCreated: 2 }]
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -3,18 +3,58 @@
|
||||
|
||||
import { AccountJson, AccountWithChildren } from '@polkadot/extension-base/background/types';
|
||||
|
||||
import getNetworkMap from './getNetworkMap';
|
||||
|
||||
type ChildFilter = (account: AccountJson) => AccountWithChildren;
|
||||
|
||||
function compareByCreationTime (a: AccountJson, b: AccountJson): number {
|
||||
function compareByCreation (a: AccountJson, b: AccountJson): number {
|
||||
return (a.whenCreated || Infinity) - (b.whenCreated || Infinity);
|
||||
}
|
||||
|
||||
function compareByName (a: AccountJson, b: AccountJson): number {
|
||||
const nameA = a.name?.toUpperCase() || '';
|
||||
const nameB = b.name?.toUpperCase() || '';
|
||||
|
||||
return nameA.localeCompare(nameB);
|
||||
}
|
||||
|
||||
function compareByPath (a: AccountJson, b: AccountJson): number {
|
||||
const suriA = a.suri?.toUpperCase() || '';
|
||||
const suriB = b.suri?.toUpperCase() || '';
|
||||
|
||||
return suriA.localeCompare(suriB);
|
||||
}
|
||||
|
||||
function compareByNetwork (a: AccountJson, b: AccountJson): number {
|
||||
const networkMap = getNetworkMap();
|
||||
const networkA = networkMap.get(a?.genesisHash || '') || '';
|
||||
const networkB = networkMap.get(b?.genesisHash || '') || '';
|
||||
|
||||
return networkA.localeCompare(networkB);
|
||||
}
|
||||
|
||||
function compareByPathThenCreation (a: AccountJson, b: AccountJson): number {
|
||||
// if the paths are equal, compare by creation time
|
||||
return compareByPath(a, b) || compareByCreation(a, b);
|
||||
}
|
||||
|
||||
function compareByNameThenPathThenCreation (a: AccountJson, b: AccountJson): number {
|
||||
// This comparison happens after an initial sorting by network.
|
||||
// if the 2 accounts are from different networks, don't touch their order
|
||||
if (a.genesisHash !== b.genesisHash) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// if the names are equal, compare by path then creation time
|
||||
return compareByName(a, b) || compareByPathThenCreation(a, b);
|
||||
}
|
||||
|
||||
export function accountWithChildren (accounts: AccountJson[]): ChildFilter {
|
||||
return (account: AccountJson): AccountWithChildren => {
|
||||
const children = accounts
|
||||
.filter(({ parentAddress }) => account.address === parentAddress)
|
||||
.map(accountWithChildren(accounts))
|
||||
.sort(compareByCreationTime);
|
||||
.sort(compareByNameThenPathThenCreation);
|
||||
|
||||
return children.length === 0
|
||||
? account
|
||||
@@ -31,5 +71,6 @@ export function buildHierarchy (accounts: AccountJson[]): AccountWithChildren[]
|
||||
!accounts.some(({ address }) => parentAddress === address)
|
||||
)
|
||||
.map(accountWithChildren(accounts))
|
||||
.sort(compareByCreationTime);
|
||||
.sort(compareByNetwork)
|
||||
.sort(compareByNameThenPathThenCreation);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright 2019-2020 @polkadot/extension-ui authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import chains from '@polkadot/extension-chains/chains';
|
||||
|
||||
export default function getNetworkMap (): Map<string, string> {
|
||||
const res = new Map<string, string>();
|
||||
|
||||
chains.forEach((chain) => {
|
||||
res.set(chain.genesisHash, chain.chain);
|
||||
});
|
||||
|
||||
return res;
|
||||
}
|
||||
Reference in New Issue
Block a user