aliasSelector: prep for Alias refactor, and fix (#2058)

* aliasSelector: prep for Alias refactor, and fix

This commit does three things:

1. It fixes a bug, where the selector shows other identities own
addresses as potential aliases to bind to. This only happens when the
other identity was already in the graph (i.e. wasn't just freshly
created in the ui). The fix is to filter out any ledger identity's own
address.

2. It preps for a coming refactor where aliases will have addresses and
descriptions.

3. It no longer peeks at the Ledger's private properties.

Test plan:
- Run `yarn start` and navigate to the ledger admin pane
- Observe that when you open the add alias selector for a user...
  - you do not see any already-bound aliases (existing behavior
  preserved)
  - you do not see any of the other identities as suggestions (new fix)
  - you still see the single unbound alias an option

Request for help from @topocount: Right now there's some sort of bug
around adding aliases; I'm not sure what exactly. PTAL

* fix combobox bugs

- add inputItems  state so we have tighter control over generating those
lists of available aliases. This is necessary to ensure ledger and graph
state changes are reflected as expected in the dropdown: no identities
and used aliases should show up and any point.

- temporarily empty out the useMemo hook that renders the list of each
identity's aliases. This relies on #2059 to work, sp once that's merged
in, it'll get set back up

test-p[an: newly added aliases should render above above the combobox as
before, and the dropdown should not render claimed aliases or identities
at any point, including freshly claimed aliases. Previously claimed
aliases will not yet render correctly when switching between identities

Co-authored-by: Kevin Siegler <17910833+topocount@users.noreply.github.com>
This commit is contained in:
Dandelion Mané 2020-07-29 12:14:17 -07:00 committed by GitHub
parent aa0f8acf8b
commit 5fb970fdf1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -16,6 +16,11 @@ type Props = {|
+setCurrentIdentity: (Identity) => void,
|};
type Alias = {|
+address: NodeAddressT,
+description: string,
|};
export function AliasSelector({
currentIdentity,
ledger,
@ -28,38 +33,53 @@ export function AliasSelector({
getSelectedItemProps,
getDropdownProps,
addSelectedItem,
removeSelectedItem,
//removeSelectedItem, will be utilzed again when #2059 is merged
selectedItems,
} = useMultipleSelection({
initialSelectedItems: [],
});
// this memo is utilized to repopulate the selected Items
// list each time the user is changed in the interface
useMemo(() => {
selectedItems.forEach((item) => {
removeSelectedItem(item);
});
if (currentIdentity) {
currentIdentity.aliases.forEach((aliasAddress) =>
addSelectedItem(aliasAddress)
// This memo will be reimplemented once the
// alias primitives (#2059) are merged into this
// branch or master
}, [currentIdentity && currentIdentity.id]);
const claimedAddresses: Set<NodeAddressT> = new Set();
for (const {identity} of ledger.accounts()) {
claimedAddresses.add(identity.address);
for (const address of identity.aliases) {
claimedAddresses.add(address);
}
}
const potentialAliases = credView
.userNodes()
.map(({address, description}) => ({
address,
description,
}))
.filter(({address}) => !claimedAddresses.has(address));
function filteredAliasesMatchingString(input: string): Alias[] {
return potentialAliases.filter(({description}) =>
description.toLowerCase().startsWith(input.toLowerCase())
);
}
}, [currentIdentity]);
const getNodeDescription = (nodeAddress: NodeAddressT): string => {
const node = credView.node(nodeAddress);
if (node) {
return node.description;
}
return "";
const [inputItems, setInputItems] = useState(
filteredAliasesMatchingString("")
);
const setAliasSearch = (input: string = "") => {
setInputItems(filteredAliasesMatchingString(input));
};
const getFilteredItems = (items) =>
items.filter(
(item) =>
!ledger._aliases.has(item) &&
getNodeDescription(item)
.toLowerCase()
.startsWith(inputValue.toLowerCase())
);
useMemo(() => {
setAliasSearch();
}, [currentIdentity && currentIdentity.aliases]);
const {
isOpen,
@ -72,21 +92,25 @@ export function AliasSelector({
selectItem,
} = useCombobox({
inputValue,
items: getFilteredItems(credView.userNodes().map((i) => i.address)),
items: inputItems,
onStateChange: ({inputValue, type, selectedItem}) => {
switch (type) {
case useCombobox.stateChangeTypes.InputChange:
setInputValue(inputValue);
setAliasSearch(inputValue);
break;
case useCombobox.stateChangeTypes.InputKeyDownEnter:
case useCombobox.stateChangeTypes.ItemClick:
case useCombobox.stateChangeTypes.InputBlur:
if (selectedItem && currentIdentity) {
setLedger(ledger.addAlias(currentIdentity.id, selectedItem));
setLedger(
ledger.addAlias(currentIdentity.id, selectedItem.address)
);
setCurrentIdentity(ledger.account(currentIdentity.id).identity);
setInputValue("");
addSelectedItem(selectedItem);
selectItem(null);
claimedAddresses.add(selectedItem.address);
}
break;
@ -101,14 +125,14 @@ export function AliasSelector({
<h2>Aliases:</h2>
</label>
<div>
{selectedItems.filter(getNodeDescription).map((selectedItem, index) => (
{selectedItems.map((selectedItem, index) => (
<span
key={`selected-item-${index}`}
{...getSelectedItemProps({selectedItem, index})}
>
<Markdown
renderers={{paragraph: "span"}}
source={getNodeDescription(selectedItem)}
source={selectedItem.description}
/>
<br />
</span>
@ -124,22 +148,20 @@ export function AliasSelector({
</div>
<ul {...getMenuProps()} style={menuMultipleStyles}>
{isOpen &&
getFilteredItems(credView.userNodes().map((i) => i.address)).map(
(item, index) => (
inputItems.map((item, index) => (
<li
style={
highlightedIndex === index ? {backgroundColor: "#bde4ff"} : {}
}
key={`${item}${index}`}
key={`${item.address}${index}`}
{...getItemProps({item, index})}
>
<Markdown
renderers={{paragraph: "span"}}
source={getNodeDescription(item)}
source={item.description}
/>
</li>
)
)}
))}
</ul>
</div>
);
@ -158,5 +180,4 @@ const menuMultipleStyles = {
zIndex: 1000,
listStyle: "none",
padding: 0,
//right: "40px",
};