refactor(webui): use EntitySetEditor in Inspect & MultiGroup
ci/woodpecker/push/woodpecker Pipeline failed Details

feat/vault-scan-modes
Tomáš Mládek 2023-10-23 15:29:55 +02:00
parent 2b6a41ebe4
commit eef2d3f5a4
3 changed files with 41 additions and 220 deletions

View File

@ -9,6 +9,7 @@
const dispatch = createEventDispatcher();
export let entities: string[];
export let hide = false;
export let header = "";
export let confirmRemoveMessage: string | null = $i18n.t(
@ -37,7 +38,7 @@
}
</script>
<LabelBorder>
<LabelBorder {hide}>
<span slot="header">{header}</span>
{#if adding}
@ -59,7 +60,11 @@
<div class="body">
<div class="group-list">
{#each entities as entity}
<div class="group">
<div
class="group"
on:mouseenter={() => dispatch("highlighted", entity)}
on:mouseleave={() => dispatch("highlighted", undefined)}
>
<UpObjectDisplay address={entity} link />
<IconButton subdued name="x-circle" on:click={() => remove(entity)} />
</div>

View File

@ -1,136 +1,42 @@
<script lang="ts">
import UpObjectDisplay from "./display/UpObject.svelte";
import Selector from "./utils/Selector.svelte";
import IconButton from "./utils/IconButton.svelte";
import type { IValue } from "@upnd/upend/types";
import api from "../lib/api";
import { ATTR_IN } from "@upnd/upend/constants";
import { createEventDispatcher } from "svelte";
import { i18n } from "../i18n";
import type { UpObject } from "@upnd/upend";
import type { Readable } from "svelte/store";
import LabelBorder from "./utils/LabelBorder.svelte";
import EntitySetEditor from "./EntitySetEditor.svelte";
const dispatch = createEventDispatcher();
export let entity: Readable<UpObject>;
let adding = false;
let groupSelector: Selector;
$: if (adding && groupSelector) groupSelector.focus();
$: groups = ($entity?.attr[ATTR_IN] || []).map(
(e) => [e.value.c as string, e.address] as [string, string],
$: groups = Object.fromEntries(
($entity?.attr[ATTR_IN] || []).map((e) => [e.value.c as string, e.address]),
);
let groupToAdd: IValue | undefined;
async function addGroup() {
if (!groupToAdd) {
return;
}
async function addGroup(address: string) {
await api.putEntry([
{
entity: $entity.address,
attribute: ATTR_IN,
value: {
t: "Address",
c: String(groupToAdd.c),
c: address,
},
},
]);
dispatch("change");
groupToAdd = undefined;
}
async function removeGroup(groupAddress: string) {
if (confirm($i18n.t("Are you sure you want to remove this group?"))) {
await api.deleteEntry(groupAddress);
dispatch("change");
}
async function removeGroup(address: string) {
await api.deleteEntry(groups[address]);
dispatch("change");
}
</script>
<LabelBorder hide={groups.length === 0}>
<span slot="header">{$i18n.t("Groups")}</span>
{#if adding}
<div class="selector">
<Selector
bind:this={groupSelector}
type="value"
valueTypes={["Address"]}
bind:value={groupToAdd}
on:input={addGroup}
on:focus={(ev) => {
if (!ev.detail) adding = false;
}}
placeholder={$i18n.t("Choose an entity...")}
/>
</div>
{/if}
<div class="body">
<div class="group-list">
{#each groups as [groupAddress, groupEntryAddress]}
<div
class="group"
on:mouseenter={() => dispatch("highlighted", groupAddress)}
on:mouseleave={() => dispatch("highlighted", undefined)}
>
<UpObjectDisplay address={groupAddress} link />
<IconButton
subdued
name="x-circle"
on:click={() => removeGroup(groupEntryAddress)}
/>
</div>
{:else}
<div class="no-groups">
{$i18n.t("Object is not in any groups.")}
</div>
{/each}
</div>
{#if !adding}
<div class="add-button">
<IconButton
outline
small
name="folder-plus"
on:click={() => (adding = true)}
/>
</div>
{/if}
</div>
</LabelBorder>
<style lang="scss">
.group-list {
display: flex;
flex-wrap: wrap;
gap: 0.25rem 0.2rem;
align-items: center;
}
.group {
display: inline-flex;
align-items: center;
}
.body {
display: flex;
align-items: start;
.group-list {
flex-grow: 1;
}
}
.selector {
width: 100%;
margin-bottom: 0.5rem;
}
.no-groups {
opacity: 0.66;
}
</style>
<EntitySetEditor
entities={Object.keys(groups)}
hide={Object.keys(groups).length === 0}
on:add={(e) => addGroup(e.detail)}
on:remove={(e) => removeGroup(e.detail)}
on:highlighted
/>

View File

@ -1,21 +1,12 @@
<script lang="ts">
import UpObjectDisplay from "./display/UpObject.svelte";
import Selector from "./utils/Selector.svelte";
import IconButton from "./utils/IconButton.svelte";
import type { IValue } from "@upnd/upend/types";
import api from "../lib/api";
import { ATTR_IN } from "@upnd/upend/constants";
import { i18n } from "../i18n";
import LabelBorder from "./utils/LabelBorder.svelte";
import { Query, UpListing } from "@upnd/upend";
import EntitySetEditor from "./EntitySetEditor.svelte";
export let entities: string[];
let adding = false;
let groupSelector: Selector;
$: if (adding && groupSelector) groupSelector.focus();
let groups = [];
let groupListing: UpListing | undefined = undefined;
async function updateGroups() {
@ -46,118 +37,37 @@
}
$: entities && updateGroups();
let groupToAdd: IValue | undefined;
async function addGroup() {
if (!groupToAdd) {
return;
}
async function addGroup(address: string) {
await api.putEntry(
entities.map((entity) => ({
entity,
attribute: ATTR_IN,
value: {
t: "Address",
c: String(groupToAdd.c),
c: address,
},
})),
);
groupToAdd = undefined;
await updateGroups();
}
async function removeGroup(groupAddress: string) {
if (confirm($i18n.t("Are you sure you want to remove this group?"))) {
await Promise.all(
entities.map((entity) =>
api.deleteEntry(
groupListing.objects[entity].attr[ATTR_IN].find(
(v) => v.value.c === groupAddress,
).address,
),
async function removeGroup(address: string) {
await Promise.all(
entities.map((entity) =>
api.deleteEntry(
groupListing.objects[entity].attr[ATTR_IN].find(
(v) => v.value.c === address,
).address,
),
);
await updateGroups();
}
),
);
await updateGroups();
}
</script>
<LabelBorder>
<span slot="header">{$i18n.t("Common groups")}</span>
{#if adding}
<div class="selector">
<Selector
bind:this={groupSelector}
type="value"
valueTypes={["Address"]}
bind:value={groupToAdd}
on:input={addGroup}
on:focus={(ev) => {
if (!ev.detail) adding = false;
}}
placeholder={$i18n.t("Choose an entity...")}
/>
</div>
{/if}
<div class="body">
<div class="group-list">
{#each groups as groupAddress}
<div class="group">
<UpObjectDisplay address={groupAddress} link />
<IconButton
subdued
name="x-circle"
on:click={() => removeGroup(groupAddress)}
/>
</div>
{:else}
<div class="no-groups">
{$i18n.t("Entities have no groups in common.")}
</div>
{/each}
</div>
{#if !adding}
<div class="add-button">
<IconButton
outline
small
name="folder-plus"
on:click={() => (adding = true)}
/>
</div>
{/if}
</div>
</LabelBorder>
<style lang="scss">
.group-list {
display: flex;
flex-wrap: wrap;
gap: 0.25rem 0.2rem;
align-items: center;
}
.group {
display: inline-flex;
align-items: center;
}
.body {
display: flex;
align-items: start;
.group-list {
flex-grow: 1;
}
}
.selector {
width: 100%;
margin-bottom: 0.5rem;
}
.no-groups {
opacity: 0.66;
}
</style>
<EntitySetEditor
entities={groups}
header={$i18n.t("Common groups")}
on:add={(ev) => addGroup(ev.detail)}
on:remove={(ev) => removeGroup(ev.detail)}
/>