2021-02-16 07:41:56 +13:00
|
|
|
<script>
|
2021-12-07 06:39:51 +13:00
|
|
|
import {
|
|
|
|
Icon,
|
|
|
|
ActionButton,
|
|
|
|
Input,
|
|
|
|
Label,
|
|
|
|
Toggle,
|
|
|
|
Select,
|
2021-12-15 01:30:26 +13:00
|
|
|
ActionMenu,
|
|
|
|
MenuItem,
|
2021-12-07 06:39:51 +13:00
|
|
|
} from "@budibase/bbui"
|
2021-12-01 06:56:15 +13:00
|
|
|
import { createEventDispatcher } from "svelte"
|
2021-12-02 02:31:40 +13:00
|
|
|
import { lowercase } from "helpers"
|
2021-12-01 06:56:15 +13:00
|
|
|
|
|
|
|
let dispatch = createEventDispatcher()
|
2021-02-16 07:41:56 +13:00
|
|
|
|
2021-02-25 05:31:47 +13:00
|
|
|
export let defaults
|
|
|
|
export let object = defaults || {}
|
2021-12-08 07:24:10 +13:00
|
|
|
export let activity = {}
|
2021-02-20 01:07:37 +13:00
|
|
|
export let readOnly
|
2021-09-30 01:02:30 +13:00
|
|
|
export let noAddButton
|
2021-12-02 02:31:40 +13:00
|
|
|
export let name
|
2021-12-03 00:53:51 +13:00
|
|
|
export let headings = false
|
2021-12-07 06:39:51 +13:00
|
|
|
export let options
|
2021-12-08 07:24:10 +13:00
|
|
|
export let toggle
|
2021-12-09 06:58:30 +13:00
|
|
|
export let keyPlaceholder = "Key"
|
|
|
|
export let valuePlaceholder = "Value"
|
2021-12-15 01:30:26 +13:00
|
|
|
export let valueHeading
|
2021-12-16 03:37:03 +13:00
|
|
|
export let keyHeading
|
2021-12-09 06:58:30 +13:00
|
|
|
export let tooltip
|
2021-12-15 01:30:26 +13:00
|
|
|
export let menuItems
|
2021-12-15 05:58:17 +13:00
|
|
|
export let showMenu = false
|
2021-02-16 07:41:56 +13:00
|
|
|
|
2022-01-05 23:57:05 +13:00
|
|
|
let fields = Object.entries(object || {}).map(([name, value]) => ({
|
|
|
|
name,
|
|
|
|
value,
|
|
|
|
}))
|
2021-12-14 00:24:13 +13:00
|
|
|
let fieldActivity = buildFieldActivity(activity)
|
2021-02-16 07:41:56 +13:00
|
|
|
|
|
|
|
$: object = fields.reduce(
|
|
|
|
(acc, next) => ({ ...acc, [next.name]: next.value }),
|
|
|
|
{}
|
|
|
|
)
|
2021-12-08 07:24:10 +13:00
|
|
|
|
|
|
|
function buildFieldActivity(obj) {
|
|
|
|
if (!obj || typeof obj !== "object") {
|
|
|
|
return []
|
|
|
|
}
|
|
|
|
const array = Array(fields.length)
|
|
|
|
for (let [key, value] of Object.entries(obj)) {
|
|
|
|
const field = fields.find(el => el.name === key)
|
|
|
|
const idx = fields.indexOf(field)
|
2021-12-14 04:18:44 +13:00
|
|
|
array[idx] = idx !== -1 ? value : true
|
2021-12-08 07:24:10 +13:00
|
|
|
}
|
|
|
|
return array
|
|
|
|
}
|
2021-02-16 07:41:56 +13:00
|
|
|
|
2021-09-30 01:02:30 +13:00
|
|
|
export function addEntry() {
|
2021-12-03 00:32:21 +13:00
|
|
|
fields = [...fields, { name: "", value: "" }]
|
2021-12-08 07:24:10 +13:00
|
|
|
fieldActivity = [...fieldActivity, true]
|
2021-12-01 06:56:15 +13:00
|
|
|
changed()
|
2021-02-16 07:41:56 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
function deleteEntry(idx) {
|
|
|
|
fields.splice(idx, 1)
|
2021-12-08 07:24:10 +13:00
|
|
|
fieldActivity.splice(idx, 1)
|
2021-12-01 06:56:15 +13:00
|
|
|
changed()
|
|
|
|
}
|
|
|
|
|
|
|
|
function changed() {
|
2021-02-16 07:41:56 +13:00
|
|
|
fields = fields
|
2021-12-08 07:24:10 +13:00
|
|
|
const newActivity = {}
|
|
|
|
for (let idx = 0; idx < fields.length; idx++) {
|
|
|
|
const fieldName = fields[idx].name
|
|
|
|
if (fieldName) {
|
|
|
|
newActivity[fieldName] = fieldActivity[idx]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
activity = newActivity
|
2021-12-01 06:56:15 +13:00
|
|
|
dispatch("change", fields)
|
2021-02-16 07:41:56 +13:00
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<!-- Builds Objects with Key Value Pairs. Useful for building things like Request Headers. -->
|
2021-12-02 02:09:16 +13:00
|
|
|
{#if Object.keys(object || {}).length > 0}
|
2021-12-03 00:53:51 +13:00
|
|
|
{#if headings}
|
2021-12-08 07:50:29 +13:00
|
|
|
<div class="container" class:container-active={toggle}>
|
2021-12-16 03:37:03 +13:00
|
|
|
<Label {tooltip}>{keyHeading || keyPlaceholder}</Label>
|
2021-12-15 01:30:26 +13:00
|
|
|
<Label>{valueHeading || valuePlaceholder}</Label>
|
2021-12-08 07:50:29 +13:00
|
|
|
{#if toggle}
|
2021-12-03 00:53:51 +13:00
|
|
|
<Label>Active</Label>
|
|
|
|
{/if}
|
|
|
|
</div>
|
|
|
|
{/if}
|
2021-12-15 01:30:26 +13:00
|
|
|
<div
|
|
|
|
class="container"
|
|
|
|
class:container-active={toggle}
|
2021-12-15 05:58:17 +13:00
|
|
|
class:container-menu={showMenu}
|
2021-12-15 01:30:26 +13:00
|
|
|
class:readOnly
|
2021-12-15 05:58:17 +13:00
|
|
|
class:readOnly-menu={readOnly && showMenu}
|
2021-12-15 01:30:26 +13:00
|
|
|
>
|
2021-12-02 02:09:16 +13:00
|
|
|
{#each fields as field, idx}
|
2021-12-09 06:58:30 +13:00
|
|
|
<Input
|
|
|
|
placeholder={keyPlaceholder}
|
2021-12-15 05:46:31 +13:00
|
|
|
readonly={readOnly}
|
2021-12-09 06:58:30 +13:00
|
|
|
bind:value={field.name}
|
|
|
|
on:change={changed}
|
|
|
|
/>
|
2021-12-07 06:39:51 +13:00
|
|
|
{#if options}
|
|
|
|
<Select bind:value={field.value} on:change={changed} {options} />
|
|
|
|
{:else}
|
|
|
|
<Input
|
2021-12-09 06:58:30 +13:00
|
|
|
placeholder={valuePlaceholder}
|
2021-12-15 05:46:31 +13:00
|
|
|
readonly={readOnly}
|
2021-12-07 06:39:51 +13:00
|
|
|
bind:value={field.value}
|
|
|
|
on:change={changed}
|
|
|
|
/>
|
|
|
|
{/if}
|
2021-12-08 07:24:10 +13:00
|
|
|
{#if toggle}
|
2021-12-14 00:24:13 +13:00
|
|
|
<Toggle bind:value={fieldActivity[idx]} on:change={changed} />
|
2021-12-03 00:53:51 +13:00
|
|
|
{/if}
|
2021-12-02 02:09:16 +13:00
|
|
|
{#if !readOnly}
|
|
|
|
<Icon hoverable name="Close" on:click={() => deleteEntry(idx)} />
|
|
|
|
{/if}
|
2021-12-15 05:58:17 +13:00
|
|
|
{#if menuItems?.length > 0 && showMenu}
|
2021-12-15 01:30:26 +13:00
|
|
|
<ActionMenu>
|
2021-12-17 00:44:17 +13:00
|
|
|
<div slot="control" class="control icon">
|
2021-12-15 01:30:26 +13:00
|
|
|
<Icon size="S" hoverable name="MoreSmallList" />
|
|
|
|
</div>
|
|
|
|
{#each menuItems as item}
|
2021-12-16 08:20:19 +13:00
|
|
|
<MenuItem on:click={() => item.onClick(field)}>
|
2021-12-15 01:30:26 +13:00
|
|
|
{item.text}
|
|
|
|
</MenuItem>
|
|
|
|
{/each}
|
|
|
|
</ActionMenu>
|
|
|
|
{/if}
|
2021-12-02 02:09:16 +13:00
|
|
|
{/each}
|
|
|
|
</div>
|
|
|
|
{/if}
|
2021-09-30 01:02:30 +13:00
|
|
|
{#if !readOnly && !noAddButton}
|
2021-05-04 20:55:14 +12:00
|
|
|
<div>
|
2021-12-02 02:11:35 +13:00
|
|
|
<ActionButton icon="Add" secondary thin outline on:click={addEntry}
|
2021-12-02 02:31:40 +13:00
|
|
|
>Add{name ? ` ${lowercase(name)}` : ""}</ActionButton
|
2021-12-02 02:11:35 +13:00
|
|
|
>
|
2021-05-04 20:55:14 +12:00
|
|
|
</div>
|
2021-02-20 01:07:37 +13:00
|
|
|
{/if}
|
2021-02-16 07:41:56 +13:00
|
|
|
|
|
|
|
<style>
|
|
|
|
.container {
|
|
|
|
display: grid;
|
|
|
|
grid-template-columns: 1fr 1fr 20px;
|
|
|
|
grid-gap: var(--spacing-m);
|
|
|
|
align-items: center;
|
2021-02-16 07:59:21 +13:00
|
|
|
margin-bottom: var(--spacing-m);
|
2021-02-16 07:41:56 +13:00
|
|
|
}
|
2021-12-03 00:53:51 +13:00
|
|
|
.container-active {
|
|
|
|
grid-template-columns: 1fr 1fr 50px 20px;
|
|
|
|
}
|
2021-12-15 01:30:26 +13:00
|
|
|
.container-menu {
|
|
|
|
grid-template-columns: 1fr 1fr 20px 20px;
|
|
|
|
}
|
2021-12-10 01:30:05 +13:00
|
|
|
.readOnly {
|
|
|
|
grid-template-columns: 1fr 1fr;
|
|
|
|
}
|
2021-12-15 05:58:17 +13:00
|
|
|
.readOnly-menu {
|
|
|
|
grid-template-columns: 1fr 1fr 20px;
|
|
|
|
}
|
2021-12-16 08:20:19 +13:00
|
|
|
.control {
|
|
|
|
margin-top: 4px;
|
|
|
|
}
|
2021-02-16 07:41:56 +13:00
|
|
|
</style>
|