feat(webui): labels can be edited via column header (banner)
ci/woodpecker/push/woodpecker Pipeline was successful Details

fixes #55
known issue: replaces all labels with one
feat/tables
Tomáš Mládek 2024-02-17 17:22:58 +01:00
parent dd9ff79e20
commit 2faa113691
3 changed files with 43 additions and 18 deletions

View File

@ -400,7 +400,9 @@
<header> <header>
<h2> <h2>
{#if $entity} {#if $entity}
<UpObject banner {address} on:resolved={onResolved} /> {#key $entity}
<UpObject banner {address} on:resolved={onResolved} on:change={onChange} />
{/key}
{:else} {:else}
<Spinner centered /> <Spinner centered />
{/if} {/if}

View File

@ -11,7 +11,7 @@
import { vaultInfo } from '$lib/util/info'; import { vaultInfo } from '$lib/util/info';
import type { BrowseContext } from '$lib/util/browse'; import type { BrowseContext } from '$lib/util/browse';
import { Query, type UpObject } from '@upnd/upend'; import { Query, type UpObject } from '@upnd/upend';
import type { ADDRESS_TYPE, EntityInfo } from '@upnd/upend/types'; import type { ADDRESS_TYPE, EntityInfo, IValue } from '@upnd/upend/types';
import { useEntity } from '$lib/entity'; import { useEntity } from '$lib/entity';
import { i18n } from '$lib/i18n'; import { i18n } from '$lib/i18n';
import api from '$lib/api'; import api from '$lib/api';
@ -19,8 +19,11 @@
import { selected } from '../EntitySelect.svelte'; import { selected } from '../EntitySelect.svelte';
import { Any } from '@upnd/upend/query'; import { Any } from '@upnd/upend/query';
import type { AddressComponents } from '@upnd/upend/wasm'; import type { AddressComponents } from '@upnd/upend/wasm';
import Editable from '$lib/components/utils/Editable.svelte';
import type { WidgetChange } from '$lib/types/base';
import type { SelectorValue } from '$lib/components/utils/Selector.svelte';
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher<{ change: WidgetChange; resolved: string[] }>();
export let address: string; export let address: string;
export let labels: string[] | undefined = undefined; export let labels: string[] | undefined = undefined;
@ -143,6 +146,12 @@
); );
}); });
} }
function onLabelEdit(ev: CustomEvent<SelectorValue>) {
if (ev.detail.t == 'String') {
dispatch('change', { type: 'upsert', attribute: ATTR_LABEL, value: ev.detail });
}
}
</script> </script>
<div <div
@ -161,17 +170,24 @@
<HashBadge {address} /> <HashBadge {address} />
<div class="separator" /> <div class="separator" />
<div class="label" class:resolving title={displayLabel}> <div class="label" class:resolving title={displayLabel}>
<div class="label-inner"> <Editable
{#if banner && hasFile} value={{ t: 'String', c: displayLabel }}
<UpObjectLabel label={displayLabel} backpath={resolvedBackpath} /> editable={banner}
{:else if link} types={['String']}
<UpLink to={{ entity: address }}> on:edit={onLabelEdit}
>
<div class="label-inner">
{#if banner && hasFile}
<UpObjectLabel label={displayLabel} backpath={resolvedBackpath} /> <UpObjectLabel label={displayLabel} backpath={resolvedBackpath} />
</UpLink> {:else if link}
{:else} <UpLink to={{ entity: address }}>
<UpObjectLabel label={displayLabel} backpath={resolvedBackpath} /> <UpObjectLabel label={displayLabel} backpath={resolvedBackpath} />
{/if} </UpLink>
</div> {:else}
<UpObjectLabel label={displayLabel} backpath={resolvedBackpath} />
{/if}
</div>
</Editable>
{#if $entity?.get(ATTR_KEY) && !$entity?.get(ATTR_KEY)?.toString()?.startsWith('TYPE_')} {#if $entity?.get(ATTR_KEY) && !$entity?.get(ATTR_KEY)?.toString()?.startsWith('TYPE_')}
<div class="key">{$entity.get(ATTR_KEY)}</div> <div class="key">{$entity.get(ATTR_KEY)}</div>
{/if} {/if}

View File

@ -4,8 +4,9 @@
import type { IValue } from '@upnd/upend/types'; import type { IValue } from '@upnd/upend/types';
import IconButton from './IconButton.svelte'; import IconButton from './IconButton.svelte';
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher<{ edit: SelectorValue }>();
export let editable = true;
export let value: IValue | undefined = undefined; export let value: IValue | undefined = undefined;
export let types: SELECTOR_TYPE[] | undefined = undefined; export let types: SELECTOR_TYPE[] | undefined = undefined;
let newValue: SelectorValue | undefined = value; let newValue: SelectorValue | undefined = value;
@ -53,7 +54,7 @@
<IconButton <IconButton
name="save" name="save"
on:click={() => { on:click={() => {
dispatch('edit', newValue); if (newValue) dispatch('edit', newValue);
editing = false; editing = false;
}} }}
/> />
@ -61,9 +62,11 @@
<div class="content"> <div class="content">
<slot /> <slot />
</div> </div>
<div class="edit-icon"> {#if editable}
<IconButton name="edit" on:click={() => (editing = true)} /> <div class="edit-icon">
</div> <IconButton name="edit" on:click={() => (editing = true)} plain />
</div>
{/if}
{/if} {/if}
</div> </div>
</div> </div>
@ -92,4 +95,8 @@
flex-grow: 1; flex-grow: 1;
min-width: 0; min-width: 0;
} }
.editing {
width: 100%;
}
</style> </style>