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