[ui] constrain value types for certain attrs / selector contexts

feat/vaults
Tomáš Mládek 2022-02-07 16:32:49 +01:00
parent 267e427a87
commit f082edd6b5
No known key found for this signature in database
GPG Key ID: ED21612889E75EC5
4 changed files with 70 additions and 46 deletions

View File

@ -195,7 +195,8 @@
{#if editable}
<div class="selector">
<Selector
type="entity"
type="value"
valueTypes={["Address"]}
bind:value={groupToAdd}
on:input={addGroup}
placeholder="Choose an entity..."

View File

@ -1,21 +1,35 @@
<script lang="ts">
import Selector from "./Selector.svelte";
import { createEventDispatcher } from "svelte";
import type { IValue } from "upend/types";
import type { IValue, VALUE_TYPE } from "upend/types";
import IconButton from "./IconButton.svelte";
import { isEqual } from "lodash";
const dispatch = createEventDispatcher();
export let editable: boolean;
export let attribute: string | undefined = undefined;
export let value: IValue;
let newValue: IValue = value;
// todo - grab from db
const TYPES_FOR_ATTR: { [key: string]: VALUE_TYPE[] } = {
LBL: ["String"],
FILE_SIZE: ["Number"],
FILE_MIME: ["String"],
ADDED: ["Number"],
LAST_VISITED: ["Number"]
};
</script>
<div class="editable">
{#if editable}
<div class="inner">
<div class="selector">
<Selector type="value" bind:value={newValue} />
<Selector
type="value"
valueTypes={TYPES_FOR_ATTR[attribute]}
bind:value={newValue}
/>
</div>
<IconButton
name="check-circle"

View File

@ -1,7 +1,7 @@
<script lang="ts">
import { debounce } from "lodash";
import { createEventDispatcher } from "svelte";
import type { IValue } from "upend/types";
import type { IValue, VALUE_TYPE } from "upend/types";
import {
baseSearchOnce,
createLabelled,
@ -14,7 +14,8 @@
export let attribute: string | undefined = undefined;
export let value: IValue | undefined = undefined;
export let type: "attribute" | "value" | "entity";
export let type: "attribute" | "value";
export let valueTypes: VALUE_TYPE[] | undefined = undefined;
export let placeholder = "";
let inputValue = "";
@ -43,7 +44,8 @@
}
let options: SelectorOption[] = [];
const updateOptions = debounce(async (query: string) => {
let objects = [];
const updateOptions = debounce(async (query: string, doSearch: boolean) => {
if (query.length == 0) {
options = [];
return;
@ -62,14 +64,10 @@
});
break;
}
case "value":
case "entity": {
const result = await baseSearchOnce(query);
const objects = await getObjects(result.entries);
case "value": {
options = [];
if (type === "value") {
if (valueTypes === undefined || valueTypes.includes("Number")) {
const number = parseFloat(query);
if (!Number.isNaN(number)) {
options.push({
@ -79,6 +77,9 @@
},
});
}
}
if (valueTypes === undefined || valueTypes.includes("String")) {
options.push({
value: {
t: "String",
@ -87,51 +88,59 @@
});
}
let exactHits = Object.entries(addressToLabels)
.filter(([_, labels]) =>
labels
.map((l) => l.toLowerCase())
.includes(inputValue.toLowerCase())
)
.map(([addr, _]) => addr);
if (valueTypes === undefined || valueTypes.includes("Address")) {
if (doSearch) {
const result = await baseSearchOnce(query);
objects = await getObjects(result.entries);
}
if (exactHits.length) {
exactHits.forEach((addr) =>
options.push({
value: {
t: "Address",
c: addr,
},
})
);
} else {
options.push({
labelToCreate: inputValue,
});
}
let exactHits = Object.entries(addressToLabels)
.filter(([_, labels]) =>
labels
.map((l) => l.toLowerCase())
.includes(inputValue.toLowerCase())
)
.map(([addr, _]) => addr);
options.push(
...objects
.filter(([addr, _]) => !exactHits.includes(addr))
.slice(0, 25)
.map(([address, _]) => {
return {
if (exactHits.length) {
exactHits.forEach((addr) =>
options.push({
value: {
t: "Address",
c: address,
c: addr,
},
} as SelectorOption;
})
);
})
);
} else {
options.push({
labelToCreate: inputValue,
});
}
options.push(
...objects
.filter(([addr, _]) => !exactHits.includes(addr))
.slice(0, 25)
.map(([address, _]) => {
return {
value: {
t: "Address",
c: address,
},
} as SelectorOption;
})
);
}
options = options;
break;
}
}
}, 200);
$: {
if (inputFocused) {
updateOptions(inputValue);
updateOptions(inputValue, true);
addressToLabels = {};
}
}
@ -139,7 +148,7 @@
let addressToLabels: { [key: string]: string[] } = {};
function onAddressResolved(address: string, ev: CustomEvent<string[]>) {
addressToLabels[address] = ev.detail;
updateOptions(inputValue);
updateOptions(inputValue, false);
}
async function set(option: SelectorOption) {
@ -149,7 +158,6 @@
inputValue = option.attribute;
break;
case "value":
case "entity":
if (!option.labelToCreate) {
value = option.value;
inputValue = String(option.value.c);

View File

@ -292,6 +292,7 @@
<td class="value">
<Editable
{editable}
attribute={entry.attribute}
value={entry.value}
on:edit={(ev) =>
updateEntry(entry.address, entry.attribute, ev.detail)}