[ui] basic table editing

feat/vaults
Tomáš Mládek 2021-12-02 18:45:29 +01:00
parent 738cc81e0a
commit 0fbb5ac9c4
5 changed files with 88 additions and 56 deletions

View File

@ -5,7 +5,8 @@
import type { Component, UpType, Widget } from "../lib/types"; import type { Component, UpType, Widget } from "../lib/types";
import Table from "./widgets/Table.svelte"; import Table from "./widgets/Table.svelte";
import TableComponent from "./widgets/Table.svelte"; // silence false svelte(reactive-component) warnings import TableComponent from "./widgets/Table.svelte"; // silence false svelte(reactive-component) warnings
const dispatcher = createEventDispatcher(); import type { AttributeChange } from "../types/base";
const dispatch = createEventDispatcher();
export let attributes: [string, IEntry][]; export let attributes: [string, IEntry][];
export let type: UpType | undefined = undefined; export let type: UpType | undefined = undefined;
@ -43,8 +44,30 @@
)!.components; )!.components;
} }
function processChange() { async function onChange(change: AttributeChange) {
// noop switch (change.type) {
case "create":
await fetch(`/api/obj`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
entity: address,
attribute: change.attribute,
value: {
t: "Value",
c: change.value,
},
}),
});
break;
case "delete":
await fetch(`/api/obj/${change.addr}`, { method: "DELETE" });
break;
default:
console.error("Unimplemented AttributeChange", change);
return;
}
dispatch("changed");
} }
</script> </script>
@ -82,7 +105,7 @@
{...component.props || {}} {...component.props || {}}
{attributes} {attributes}
{editable} {editable}
on:edit={processChange} on:change={(ev) => onChange(ev.detail)}
/> />
{/each} {/each}
{:else} {:else}

View File

@ -93,7 +93,7 @@
{address} {address}
type={allTypes[typeAddr]} type={allTypes[typeAddr]}
{attributes} {attributes}
on:edit={revalidate} on:changed={revalidate}
/> />
{/each} {/each}
{#if filteredUntypedAttributes.length > 0 || editable} {#if filteredUntypedAttributes.length > 0 || editable}
@ -102,7 +102,7 @@
{editable} {editable}
{address} {address}
attributes={untypedAttributes} attributes={untypedAttributes}
on:change={revalidate} on:changed={revalidate}
/> />
{/if} {/if}
{#if $backlinks.length > 0} {#if $backlinks.length > 0}
@ -111,6 +111,7 @@
{address} {address}
attributes={$backlinks} attributes={$backlinks}
reverse reverse
on:changed={revalidate}
/> />
{/if} {/if}
</div> </div>

View File

@ -1,10 +1,13 @@
<script lang="ts"> <script lang="ts">
import filesize from "filesize"; import filesize from "filesize";
import { format, fromUnixTime } from "date-fns"; import { format, fromUnixTime } from "date-fns";
import type { Readable } from "svelte/store";
import type { OrderedListing } from "upend/types"; import type { OrderedListing } from "upend/types";
import Marquee from "../Marquee.svelte"; import Marquee from "../Marquee.svelte";
import Address from "../Address.svelte"; import Address from "../Address.svelte";
import { createEventDispatcher } from "svelte";
import type { AttributeChange } from "../../types/base";
const dispatch = createEventDispatcher();
export let columns = "attribute, value"; export let columns = "attribute, value";
export let header = true; export let header = true;
@ -26,34 +29,34 @@
let newEntryValue = ""; let newEntryValue = "";
async function addEntry() { async function addEntry() {
// this.$emit("edit", { dispatch("change", {
// type: "create", type: "create",
// attribute: this.newEntryAttribute, attribute: newEntryAttribute,
// value: this.newEntryValue, value: newEntryValue,
// } as AttributeChange); } as AttributeChange);
// this.newEntryAttribute = ""; newEntryAttribute = "";
// this.newEntryValue = ""; newEntryValue = "";
} }
async function removeEntry(addr: string) { async function removeEntry(addr: string) {
// if (confirm("Are you sure you want to remove the attribute?")) { if (confirm("Are you sure you want to remove the attribute?")) {
// this.$emit("edit", { type: "delete", addr } as AttributeChange); dispatch("change", { type: "delete", addr } as AttributeChange);
// } }
} }
async function updateEntry(addr: string, attribute: string, value: string) { async function updateEntry(addr: string, attribute: string, value: string) {
// this.$emit("edit", { dispatch("change", {
// type: "update", type: "update",
// addr, addr,
// value value,
// } as AttributeChange); } as AttributeChange);
// this.$emit("edit", { dispatch("change", {
// type: "delete", type: "delete",
// addr, addr,
// } as AttributeChange); } as AttributeChange);
// this.$emit("edit", { dispatch("change", {
// type: "create", type: "create",
// attribute, attribute,
// value, value,
// } as AttributeChange); } as AttributeChange);
} }
// Sorting // Sorting
@ -233,16 +236,22 @@
{#if editable} {#if editable}
<tr> <tr>
<td class="attr-action"> <td class="attr-action">
<sl-icon-button name="plus-circle" on:click={addEntry()} /> <sl-icon-button name="plus-circle" on:click={addEntry} />
</td> </td>
{#if showAttribute} {#if showAttribute}
<td> <td>
<sl-input v-sl-model:newEntryAttribute size="small" /> <sl-input
on:sl-input={(ev) => (newEntryAttribute = ev.target.value)}
size="small"
/>
</td> </td>
{/if} {/if}
{#if showValue} {#if showValue}
<td> <td>
<sl-input v-sl-model:newEntryValue size="small" /> <sl-input
on:sl-input={(ev) => (newEntryValue = ev.target.value)}
size="small"
/>
</td> </td>
{/if} {/if}
</tr> </tr>

View File

@ -75,25 +75,3 @@ const TYPE_WIDGETS: { [key: string]: Widget } = {
], ],
}, },
}; };
export type AttributeChange =
| AttributeCreate
| AttributeUpdate
| AttributeDelete;
export interface AttributeCreate {
type: "create";
attribute: string;
value: any;
}
export interface AttributeUpdate {
type: "update";
addr: string;
value: any;
}
export interface AttributeDelete {
type: "delete";
addr: string;
}

21
ui/src/types/base.ts Normal file
View File

@ -0,0 +1,21 @@
export type AttributeChange =
| AttributeCreate
| AttributeUpdate
| AttributeDelete;
export interface AttributeCreate {
type: "create";
attribute: string;
value: any;
}
export interface AttributeUpdate {
type: "update";
addr: string;
value: any;
}
export interface AttributeDelete {
type: "delete";
addr: string;
}